feat: redesign the remote MCP connect page #37485
Workflow file for this run
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: Hygiene | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened, edited, labeled, unlabeled] | |
| branches: | |
| - main | |
| merge_group: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.event.pull_request.number || github.run_id }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| lint-pr: | |
| name: Lint PR Title and Changesets | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| env: | |
| PR_TITLE: ${{ github.event.pull_request.title }} | |
| GIT_REF: ${{ github.ref }} | |
| BASE_REF: ${{ github.base_ref }} | |
| HEAD_REF: ${{ github.head_ref }} | |
| steps: | |
| - name: Validate PR title format | |
| shell: bash | |
| run: | | |
| if [[ "${{ github.event_name }}" == "merge_group" || "$GIT_REF" == "refs/heads/main" ]]; then | |
| echo "Skipping PR title validation on $GIT_REF (event: ${{ github.event_name }})." | |
| exit 0 | |
| fi | |
| if [[ "$PR_TITLE" =~ ^[a-z0-9_-]+(\([a-zA-Z0-9_-]+\))?!?:\ [a-zA-Z] ]]; then | |
| echo "PR title format is valid." | |
| else | |
| echo "PR title must:" | |
| echo '- Start with a lowercase qualifier (e.g. "chore", "fix", "feat", "mig") - alphanumeric, dashes, and underscores only' | |
| echo "- ... optionally followed by a scope in parentheses - alphanumeric, dashes, and underscores only" | |
| echo "- ... optionally followed by an exclamation mark (!) to indicate a breaking change" | |
| echo "- ... followed by a colon and a space" | |
| echo "- ... followed by a space" | |
| echo "- ... followed by a short description of the change _starting with a lowercase letter_" | |
| echo | |
| echo 'Example: "feat: added user avatars to the dashboard"' | |
| echo 'Example: "chore(deps): updated dependency xyz to v2"' | |
| echo 'Example: "fix(auth)!: changed password hashing algorithm"' | |
| echo | |
| echo "Got: $PR_TITLE" | |
| exit 1 | |
| fi | |
| - name: Checkout | |
| uses: useblacksmith/checkout@6fd481652155169ed4d2f25ebaf97464f685175f # v1 | |
| # .gitignore does not protect files that are already tracked (or added | |
| # with `git add -f`), which is how build output like the old client/sdk | |
| # esm tree and stray screenshots ended up committed. Fail if any tracked | |
| # file matches a .gitignore pattern. | |
| - name: Check for tracked ignored files | |
| shell: bash | |
| run: | | |
| tracked_ignored=$(git ls-files --cached --ignored --exclude-standard) | |
| if [[ -n "$tracked_ignored" ]]; then | |
| echo "❌ These tracked files match .gitignore patterns:" | |
| echo "$tracked_ignored" | sed 's/^/ - /' | |
| echo "" | |
| echo "Build output, caches, and generated artifacts must not be committed." | |
| echo "Remove them with 'git rm --cached <file>' (add a .gitignore rule if missing)," | |
| echo "or if the file is intentionally tracked, adjust the .gitignore pattern excluding it." | |
| exit 1 | |
| fi | |
| echo "✅ No tracked files match .gitignore patterns." | |
| - name: Detect changed files | |
| uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2 | |
| id: filter | |
| with: | |
| filters: .github/filters.yaml | |
| list-files: json | |
| # Run a second paths-filter pass with `predicate-quantifier: every` so | |
| # the `!` patterns below act as exclusions (every pattern must match, | |
| # which inverts negations into proper exclusions). The default `some` | |
| # quantifier on the step above would treat each `!` as its own positive | |
| # predicate, matching every file outside the negated path. | |
| - name: Detect server-internal changes | |
| uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2 | |
| id: filter-internal | |
| with: | |
| predicate-quantifier: every | |
| list-files: json | |
| # Excludes SQLc-generated output paths (per `server/database/sqlc.yaml` | |
| # `out:` directives) since they legitimately change alongside | |
| # schema.sql edits. | |
| filters: | | |
| server-internal: | |
| - "server/internal/**" | |
| - "!server/internal/database/**" | |
| - "!server/internal/**/repo/**" | |
| - "!server/internal/testenv/testrepo/**" | |
| - name: Block changes to deprecated paths | |
| if: ${{ github.event_name != 'merge_group' && steps.filter.outputs.deprecated-paths == 'true' }} | |
| shell: bash | |
| env: | |
| DEPRECATED_FILES: ${{ steps.filter.outputs.deprecated-paths_files }} | |
| PR_BODY: ${{ github.event.pull_request.body }} | |
| HAS_SKIP_LABEL: ${{ contains(github.event.pull_request.labels.*.name, 'skip-deprecated-path-check') }} | |
| run: | | |
| set -e | |
| if [[ "$PR_BODY" == *"[skip deprecated path check]"* || "$HAS_SKIP_LABEL" == "true" ]]; then | |
| echo "Deprecated path check skipped via explicit directive." | |
| exit 0 | |
| fi | |
| echo "❌ This PR touches paths that were moved or retired:" | |
| echo "$DEPRECATED_FILES" | jq -r '.[]' | sed 's/^/ - /' | |
| echo "" | |
| echo "These locations are deprecated (see the deprecated-paths filter in" | |
| echo ".github/filters.yaml for where each one went). Changes here usually mean" | |
| echo "a stale generator target or an old branch resurrecting a moved directory." | |
| echo "Make the change in the path's new home instead." | |
| echo "To explicitly allow this exception, add '[skip deprecated path check]'" | |
| echo "to the PR body or apply the 'skip-deprecated-path-check' label." | |
| exit 1 | |
| - name: "Require mig: prefix for migration PRs" | |
| if: ${{ github.event_name != 'merge_group' && steps.filter.outputs.db-migrations == 'true' }} | |
| shell: bash | |
| env: | |
| MIG_FILES: ${{ steps.filter.outputs.db-migrations_files }} | |
| run: | | |
| if [[ "$PR_TITLE" =~ ^mig(\([a-zA-Z0-9_-]+\))?!?:\ [a-zA-Z] ]]; then | |
| echo "PR title is correctly qualified with 'mig:'." | |
| exit 0 | |
| fi | |
| echo "❌ This PR includes PostgreSQL or ClickHouse migration changes," | |
| echo "so its title must be qualified with the 'mig:' type (not 'feat', 'fix', or 'chore')." | |
| echo "" | |
| echo "Migration files changed:" | |
| echo "$MIG_FILES" | jq -r '.[]' | sed 's/^/ - /' | |
| echo "" | |
| echo 'Example: "mig: add supports_dcr column to deployments"' | |
| echo 'Example: "mig(catalog): version registry cache key"' | |
| echo "" | |
| echo "Got: $PR_TITLE" | |
| exit 1 | |
| - name: Validate migration PR does not mix server changes | |
| if: ${{ github.event_name != 'merge_group' && steps.filter.outputs.database-changes == 'true' && steps.filter-internal.outputs.server-internal == 'true' }} | |
| shell: bash | |
| env: | |
| DB_FILES: ${{ steps.filter.outputs.database-changes_files }} | |
| INTERNAL_FILES: ${{ steps.filter-internal.outputs.server-internal_files }} | |
| PR_BODY: ${{ github.event.pull_request.body }} | |
| HAS_SKIP_LABEL: ${{ contains(github.event.pull_request.labels.*.name, 'skip-migration-check') }} | |
| run: | | |
| set -e | |
| if [[ "$PR_BODY" == *"[skip migration check]"* || "$HAS_SKIP_LABEL" == "true" ]]; then | |
| echo "Migration PR isolation check skipped via explicit directive." | |
| exit 0 | |
| fi | |
| echo "❌ This PR mixes database migration changes with other server changes." | |
| echo "" | |
| echo "Database migration files changed:" | |
| echo "$DB_FILES" | jq -r '.[]' | sed 's/^/ - /' | |
| echo "" | |
| echo "Server implementation files changed:" | |
| echo "$INTERNAL_FILES" | jq -r '.[]' | sed 's/^/ - /' | |
| echo "" | |
| echo "Database schema changes should be scheduled separately from business logic changes" | |
| echo "so each can be reviewed and rolled out independently." | |
| echo "To explicitly allow this exception, add '[skip migration check]'" | |
| echo "to the PR body or apply the 'skip-migration-check' label." | |
| echo "Please move the non-migration changes to a separate PR." | |
| exit 1 | |
| - name: Check for significant changes | |
| id: check | |
| run: | | |
| if [[ "${{ github.event_name }}" == "merge_group" || "$GIT_REF" == "refs/heads/main" ]]; then | |
| echo "Skipping changesets-lint job on $GIT_REF (event: ${{ github.event_name }})." | |
| elif [[ "$PR_TITLE" =~ ^(chore|mig)(\([a-zA-Z0-9_-]+\))?: ]]; then | |
| echo "Skipping changesets-lint job for chore/mig PR." | |
| else | |
| echo "lint=true" >> $GITHUB_OUTPUT | |
| fi | |
| # Check out both the base and head refs so changeset status can compare | |
| # against the base branch | |
| - name: Checkout base ref | |
| if: ${{ steps.check.outputs.lint == 'true' }} | |
| run: git fetch origin "$BASE_REF" && git checkout "$BASE_REF" | |
| - name: Checkout head ref | |
| if: ${{ steps.check.outputs.lint == 'true' }} | |
| run: git fetch origin "$HEAD_REF" && git checkout "$HEAD_REF" | |
| - name: Setup Mise | |
| if: ${{ steps.check.outputs.lint == 'true' }} | |
| uses: jdx/mise-action@7e36c90d9ab29c415a2384db3006f3ec8a8cc654 # v4.2.4 | |
| with: | |
| install: true | |
| cache: true | |
| cache_key_prefix: mise-blacksmith-v1 | |
| env: false | |
| - name: Prepare GitHub Actions environment | |
| if: ${{ steps.check.outputs.lint == 'true' }} | |
| run: mise run github | |
| - name: Cache aube store | |
| if: ${{ steps.check.outputs.lint == 'true' }} | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| key: ${{ env.GH_CACHE_AUBE_KEY }} | |
| restore-keys: | | |
| ${{ env.GH_CACHE_AUBE_KEY }} | |
| ${{ env.GH_CACHE_AUBE_KEY_PARTIAL }} | |
| path: | | |
| ${{ env.AUBE_STORE_PATH }} | |
| - name: Install dependencies | |
| if: ${{ steps.check.outputs.lint == 'true' }} | |
| run: aube install --frozen-lockfile | |
| - name: Lint changesets | |
| if: ${{ steps.check.outputs.lint == 'true' }} | |
| shell: bash | |
| run: | | |
| set -e | |
| mkdir -p scratch | |
| aube exec changeset -- status --output scratch/changeset-status.json | |
| cat scratch/changeset-status.json | |
| echo "" | |
| echo "" | |
| # Check if changesets array exists and has length > 0 | |
| if ! jq -e '.changesets | length > 0' scratch/changeset-status.json > /dev/null; then | |
| echo "❌ Changeset validation failed!" | |
| echo "" | |
| echo "It looks like you've made significant changes but haven't added a changeset." | |
| echo "Changesets help us track what's changed and generate release notes." | |
| echo "" | |
| echo "To fix this, run one of this command locally:" | |
| echo " aube exec changeset" | |
| echo "" | |
| echo "Then commit the generated .changeset/*.md file with your changes." | |
| exit 1 | |
| fi | |
| echo "✅ Changeset validation passed!" | |
| - name: Prune aube store | |
| if: ${{ steps.check.outputs.lint == 'true' }} | |
| run: aube store prune |