From 8c7233efdedee62a024390b0581ab7b5b23902bd Mon Sep 17 00:00:00 2001 From: dkijania Date: Wed, 2 Sep 2026 16:38:32 +0200 Subject: [PATCH] ci: make schema and build jobs work without repository secrets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A pull request from a fork, and one opened by Dependabot, runs with a read-only GITHUB_TOKEN and no repository secrets. Two jobs assumed otherwise and failed on every such pull request, most recently on #225 (fork) and #226 (Dependabot). Check Schema reported through a check run, which needs `checks: write`, so it ended in "Resource not accessible by integration". A `permissions:` block cannot fix that — GitHub caps the token for these events whatever the workflow asks for. The gate is now `@graphql-inspector/cli diff`, whose exit code is the job result, so it needs no write access. The expected-breaking-change label keeps working as the approval escape hatch, and the unpinned `@master` action references are gone. build-and-deploy authenticates to Google Cloud, publishes a dev npm package and pushes an image, none of which can work without secrets. It is now skipped for fork and Dependabot pull requests rather than left to fail at the auth step. Its checkout no longer runs `git fetch origin `, which could not resolve a branch that lives in a fork; actions/checkout resolves the head SHA directly. Also removes the registry credential from the workspace unconditionally (#214). `docker/build-push-action` runs later in the same job with `context: .`, so a live token must not survive on disk because the version-bump branch was not taken, and `.npmrc` is added to `.dockerignore` so a future `COPY . .` cannot bake it into a layer. Closes #214. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_012LtdRKTkaKRAuTkEEpgPcc --- .dockerignore | 1 + .github/workflows/build.yaml | 29 +++++++++++++++----- .github/workflows/graphql-inspector.yaml | 35 +++++++++++++++++++++--- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/.dockerignore b/.dockerignore index 897ac5f9..4da07d91 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,6 +5,7 @@ coverage .github .memsearch .env* +.npmrc db data *.log diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index ed68c2f6..9eafaafc 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -18,18 +18,27 @@ env: jobs: build-and-deploy: + # This job authenticates to Google Cloud, publishes a dev npm package and + # pushes a Docker image, so it only works where repository secrets are + # available. GitHub passes no secrets to a pull request from a fork or from + # Dependabot, so the job is skipped there instead of failing at the auth + # step. Fork and Dependabot pull requests are still covered by Run-Tests, + # Linting, unit-tests, smoke-load, npm audit and Check Schema. + if: >- + github.event_name != 'pull_request' || + (github.event.pull_request.head.repo.full_name == github.repository && + github.event.pull_request.user.login != 'dependabot[bot]') runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - - - name: Checkout PR branch - if: github.event_name == 'pull_request' - run: | - git fetch origin ${{github.event.pull_request.head.ref}} - git checkout ${{github.event.pull_request.head.sha}} + # Build the head commit of the pull request rather than the merge + # commit, which is what this job published before. The previous + # `git fetch origin ` assumed the branch lived in this + # repository and could not resolve a fork's branch. + ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3.6.1 @@ -110,7 +119,13 @@ jobs: if: always() && steps.determine_npm_version.outputs.needs_version_update == 'true' run: | node -e "const fs = require('fs'); const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); pkg.version = '${{ steps.determine_npm_version.outputs.original_version }}'; fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');" - rm -f .npmrc + + - name: Remove registry credentials from the workspace + # Unconditional, unlike the version restore above: `docker/build-push-action` + # runs later with `context: .`, so a live registry token must never be left + # on disk merely because the version-bump branch was not taken (#214). + if: always() + run: rm -f .npmrc - name: Determine tags id: determine_tags diff --git a/.github/workflows/graphql-inspector.yaml b/.github/workflows/graphql-inspector.yaml index 8a564663..ef9c8340 100644 --- a/.github/workflows/graphql-inspector.yaml +++ b/.github/workflows/graphql-inspector.yaml @@ -6,6 +6,14 @@ on: branches: - main +# A pull request from a fork, or one opened by Dependabot, runs with a read-only +# GITHUB_TOKEN. The previous implementation reported through a check run, which +# needs `checks: write`, so it failed on every such pull request with +# "Resource not accessible by integration". The gate is now the job's own exit +# code, which needs no write access at all. +permissions: + contents: read + jobs: test: name: Check Schema @@ -13,9 +21,28 @@ jobs: steps: - name: Checkout - uses: actions/checkout@master + uses: actions/checkout@v4 - - uses: kamilkisiela/graphql-inspector@master + - name: Install NodeJS + uses: actions/setup-node@v4 with: - schema: 'main:schema.graphql' - approve-label: expected-breaking-change + node-version: '22' + + - name: Fetch the base schema + run: git fetch --no-tags --depth=1 origin +refs/heads/main:refs/remotes/origin/main + + - name: Diff schema.graphql against main + env: + # Same escape hatch as before: a deliberate breaking change is approved + # by labelling the pull request, not by editing the workflow. + APPROVED: ${{ contains(github.event.pull_request.labels.*.name, 'expected-breaking-change') }} + run: | + set +e + npx --yes @graphql-inspector/cli@7.0.0 diff 'git:origin/main:schema.graphql' schema.graphql + status=$? + set -e + if [ "$status" -ne 0 ] && [ "$APPROVED" = 'true' ]; then + echo "::warning::Breaking schema changes detected. Accepted because this pull request carries the expected-breaking-change label." + exit 0 + fi + exit $status