ci: make schema and build jobs work without repository secrets (#214) - #227
Merged
Conversation
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 <head ref>`, 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) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012LtdRKTkaKRAuTkEEpgPcc
SanabriaRusso
approved these changes
Sep 2, 2026
SanabriaRusso
left a comment
Collaborator
There was a problem hiding this comment.
Approving. This closes two of the repo-level findings from the round-4 review (§4.1 Check Schema blind to fork/Dependabot PRs, and #214 registry token in the Docker build context) with no change to the API surface, so nothing for mina-explorer / mina-explorer-api to adapt to.
What I verified
Schema gate (graphql-inspector.yaml)
- The new gate ran on this PR's own merge ref (job 100292004125) and reported
[success] No changes detected— so thenpxpath, thegit fetchoforigin/main, and thegit:loader all work under the read-only token. The PR itself doesn't touchschema.graphql, so that only exercises the passing path. - Ran
@graphql-inspector/cli@7.0.0 diff 'git:origin/main:schema.graphql' <file>locally against three variants of the current schema:- unchanged →
[success] No changes detected, exit 0 parentHashremoved fromBlockandBlockInfo→[error] Detected 2 breaking changes, exit 1- new optional field added →
✔ Field … was added,[success] No breaking changes detected, exit 0
The gate fails only on breaking changes, which matches the previous action'sfail-on-breakingdefault; additive changes (the shape #225 uses) still pass.
- unchanged →
permissions: contents: readis explicit; no${{ }}interpolation of PR-controlled data intorun:(the label check goes throughenv), and theexpected-breaking-changelabel can only be applied by someone with triage rights, so a fork author cannot self-approve a breaking change.
Build job (build.yaml)
- Triggers are
pull_requestandpush: tags: v*. The newif:leaves tag builds untouched, keeps same-repo PR builds (this PR'sbuild-and-deployran and passed, 5m42s), and skips only fork/Dependabot PRs where the job could never have succeeded. ref: head.shafor PRs builds the same commit the oldgit fetch origin <ref> && git checkout <sha>step did; for tag pushes it resolves togithub.sha, identical to before.rm -f .npmrcis now its ownif: always()step, so the GAR token is removed beforedocker/build-push-actionon every path — including release builds, whereneeds_version_update == 'false'previously left it in the context..dockerignorenow excludes it as defence in depth. The Dockerfile never copies.npmrcandnpm ciuses the public registry, so this cannot break the image build. No.npmrcis committed.
Non-blocking
npx @graphql-inspector/cli@7.0.0pins the CLI but resolves its^transitive deps fresh each run. Same class of exposure as the old@masteraction (strictly better, since the top-level is pinned now); a follow-up could vendor it intodevDependenciesso the lockfile covers it.- Branch is behind
main(no conflicts). After merge, #225 and #226 need their runs re-triggered as the description says, and #213 (makeCheck Schemarequired) is now actually achievable.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
A pull request from a fork, and one opened by Dependabot, runs with a read-only
GITHUB_TOKENand no repository secrets. Two jobs assume otherwise and fail on every such pull request. This is currently red on #225 (fork, community contribution) and #226 (Dependabot).1.
Check Schema— could not reportkamilkisiela/graphql-inspector@masterreports by creating a check run, which needschecks: write. Adding apermissions:block does not help: GitHub caps the token at read-only for these events whatever the workflow asks for.The gate is now
npx @graphql-inspector/cli@7.0.0 diff 'git:origin/main:schema.graphql' schema.graphql, whose exit code is the job result — no API write, so it works from a fork. Behaviour kept: theexpected-breaking-changelabel still approves a deliberate breaking change. Side benefit:actions/checkout@masterandgraphql-inspector@masterwere unpinned; both are now pinned.2.
build-and-deploy— could not authenticate, and could not check out a forkand, on forks only, one step earlier:
This job authenticates to Google Cloud, writes a registry token, publishes a dev npm package and pushes an image. None of that can or should run for an untrusted pull request — the failure is GitHub's protection working, not a bug to fix by handing over secrets. So the job is now skipped for fork and Dependabot pull requests instead of failing at the auth step, and the checkout resolves the head SHA through
actions/checkoutrather thangit fetch origin <head ref>, which cannot resolve a branch living in a fork.Coverage for those pull requests is unchanged otherwise:
Run-Tests,Linting,unit-tests,smoke-load,npm audit,SBOMandCheck Schemaall still run. Both required checks (Run-Tests,Linting) are unaffected.3. Registry credential in the Docker build context — closes #214
.npmrcholds a live GCP access token, and the step that deleted it only ran whenneeds_version_update == 'true'.docker/build-push-actionruns later in the same job withcontext: ., so on any other build the token was uploaded into the build context. Nothing copies it into a layer today; the hazard is oneCOPY . .away.rm -f .npmrcsplit into its own step and made unconditional..npmrcadded to.dockerignore.The
package.jsonversion restore keeps its original condition.Testing
actionlint— clean on both changed workflows.[success] No changes detected, exit 0. WithparentHashdeleted fromBlockInfo→✖ Field parentHash was removed from object type BlockInfo/[error] Detected 1 breaking change, exit 1. So the gate still fails the build on a breaking change..dockerignore, verified with a throwaway image that doesCOPY . /ctxover a workspace containing a fake.npmrc: with the new line the file is absent from the context (build passes); with the line removed the same build fails — a negative control proving the test is meaningful.Follow-up, not in this PR
Once this lands,
Check Schemacan pass from a fork, which unblocks making it a required status check — tracked in #213.Note on ordering: for
pull_requestevents GitHub runs the workflow files from the merge ref, so #225 and #226 need their runs re-triggered after this merges (both are behindmainanyway).🤖 Generated with Claude Code
https://claude.ai/code/session_012LtdRKTkaKRAuTkEEpgPcc