CI #208
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| branches: | |
| - main | |
| schedule: | |
| # Run daily at 00:00 UTC to catch any updates | |
| - cron: '0 0 * * *' | |
| workflow_dispatch: | |
| permissions: {} | |
| jobs: | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Set up Go | |
| uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: true | |
| - name: Run golangci-lint | |
| uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9 | |
| with: | |
| version: latest | |
| args: --timeout=5m | |
| validate-and-test: | |
| name: Validate and Test | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Set up Go | |
| uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: true | |
| - name: Install dependencies | |
| run: go mod download | |
| - name: Run tests | |
| run: go test -v -race -coverprofile=coverage.out ./... | |
| - name: Upload coverage reports | |
| uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5 | |
| with: | |
| files: ./coverage.out | |
| flags: unittests | |
| name: codecov-umbrella | |
| continue-on-error: true | |
| - name: Install Task | |
| uses: arduino/setup-task@b91d5d2c96a56797b48ac1e0e89220bf64044611 # v2 | |
| - name: Validate catalog entries | |
| run: task catalog:validate | |
| update-catalog-data: | |
| name: Update Catalog Data Files | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| needs: [lint, validate-and-test] | |
| if: github.ref == 'refs/heads/main' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Set up Go | |
| uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: true | |
| - name: Install Task | |
| uses: arduino/setup-task@b91d5d2c96a56797b48ac1e0e89220bf64044611 # v2 | |
| - name: Build registry files | |
| run: | | |
| task catalog:build | |
| for registry_dir in build/*/; do | |
| registry_name=$(basename "$registry_dir") | |
| [ -f "$registry_dir/registry.json" ] || continue | |
| mkdir -p "pkg/catalog/$registry_name/data" | |
| cp "$registry_dir/registry.json" "pkg/catalog/$registry_name/data/registry.json" | |
| cp "$registry_dir/official-registry.json" "pkg/catalog/$registry_name/data/official-registry.json" | |
| done | |
| - name: Generate version | |
| id: metadata | |
| run: echo "version=$(date +'%Y.%m.%d')" >> $GITHUB_OUTPUT | |
| - name: Open or update PR with catalog data files | |
| run: | | |
| BRANCH="update-catalog-data-${VERSION}" | |
| git config --local user.email "action@github.com" | |
| git config --local user.name "GitHub Action" | |
| # Create or reset the branch | |
| git checkout -B "$BRANCH" | |
| # Stage only the catalog data files | |
| git add pkg/catalog/*/data/registry.json pkg/catalog/*/data/official-registry.json | |
| # Check if there are changes to commit | |
| if git diff --cached --quiet; then | |
| echo "No changes to commit" | |
| exit 0 | |
| fi | |
| git commit -m "chore: update catalog data files for v${VERSION}" | |
| git push -f origin "$BRANCH" | |
| # Check if PR already exists | |
| EXISTING_PR=$(gh pr list --head "$BRANCH" --json number --jq '.[0].number' 2>/dev/null || true) | |
| if [ -n "$EXISTING_PR" ]; then | |
| echo "PR #$EXISTING_PR already exists, updated branch" | |
| else | |
| gh pr create \ | |
| --title "chore: update catalog data files for v${VERSION}" \ | |
| --body "$(cat <<'BODY' | |
| Automated PR to update the embedded catalog data files. | |
| Files updated: | |
| - `pkg/catalog/toolhive/data/registry.json` — ToolHive legacy format | |
| - `pkg/catalog/toolhive/data/official-registry.json` — Upstream MCP format | |
| When merged, a release will be created automatically. | |
| BODY | |
| )" \ | |
| --head "$BRANCH" | |
| # Enable auto-merge | |
| gh pr merge "$BRANCH" --auto --squash || true | |
| fi | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| VERSION: ${{ steps.metadata.outputs.version }} | |
| build-pr: | |
| name: Build Check | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Set up Go | |
| uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache: true | |
| - name: Install Task | |
| uses: arduino/setup-task@b91d5d2c96a56797b48ac1e0e89220bf64044611 # v2 | |
| - name: Build catalog files | |
| run: task catalog:build | |
| - name: Generate PR comment | |
| id: comment | |
| run: | | |
| CONTAINER_COUNT=$(jq '.servers | length' build/toolhive/registry.json) | |
| REMOTE_COUNT=$(jq '.remote_servers | length // 0' build/toolhive/registry.json) | |
| TOTAL=$((CONTAINER_COUNT + REMOTE_COUNT)) | |
| SKILL_COUNT=$(jq '.data.skills | length // 0' build/toolhive/official-registry.json) | |
| SIZE=$(du -h build/toolhive/registry.json | cut -f1) | |
| LAST_UPDATED=$(jq -r '.last_updated' build/toolhive/registry.json) | |
| { | |
| echo "body<<EOF" | |
| echo "## Registry Build Preview" | |
| echo "" | |
| echo "Registry built successfully!" | |
| echo "" | |
| echo "- **Total Servers**: $TOTAL" | |
| echo " - Container-based: $CONTAINER_COUNT" | |
| echo " - Remote: $REMOTE_COUNT" | |
| echo "- **Skills**: $SKILL_COUNT" | |
| echo "- **File Size**: $SIZE" | |
| echo "- **Last Updated**: $LAST_UPDATED" | |
| echo "EOF" | |
| } >> $GITHUB_OUTPUT | |
| - name: Post or update PR comment | |
| run: | | |
| # Find existing comment | |
| COMMENT_ID=$(gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments" \ | |
| --jq '[.[] | select(.user.login == "github-actions[bot]") | select(.body | contains("Registry Build Preview"))][0].id' \ | |
| 2>/dev/null || true) | |
| if [ -n "$COMMENT_ID" ] && [ "$COMMENT_ID" != "null" ]; then | |
| gh api "repos/${GITHUB_REPOSITORY}/issues/comments/${COMMENT_ID}" \ | |
| --method PATCH \ | |
| --field body="$COMMENT_BODY" | |
| else | |
| gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments" \ | |
| --method POST \ | |
| --field body="$COMMENT_BODY" | |
| fi | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| COMMENT_BODY: ${{ steps.comment.outputs.body }} | |
| - name: Upload PR artifact | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 | |
| with: | |
| name: pr-registry-json | |
| path: | | |
| build/toolhive/registry.json | |
| build/toolhive/official-registry.json | |
| retention-days: 7 |