Skip to content

ci: authenticate GitHub Packages installs when the app opts in - #16

Merged
gpmayorga merged 3 commits into
mainfrom
ci/setup-app-github-packages
Oct 2, 2026
Merged

gpmayorga merged 3 commits into
mainfrom
ci/setup-app-github-packages

Conversation

@gpmayorga

@gpmayorga gpmayorga commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Do not merge before centrifuge/apps-management#1316 and centrifuge/apps-invest#341. Those grant packages: read to each app's ci-checks, deploy-dev and release callers. This PR makes the installing jobs request it, and a called job cannot request more than its caller grants. Merged first, the next CI, preview and release runs in both apps fail at startup, whether or not anything installs from GitHub Packages.

Lets an app install packages from GitHub Packages in its pipeline, starting with the @centrifuge/sdk-internal snapshots that centrifuge/backend#625 publishes there.

What changes

actions/setup-app reads the app's .npmrc. If it routes a scope, or the default registry, to https://npm.pkg.github.com, it:

Otherwise it writes nothing and outputs false. Only the placeholder is written, so the token never lands on disk.

Install steps in app-ci-checks.yml (format-n-lint and pnpm-audit) and in actions/build-app set NODE_AUTH_TOKEN to github.token when that output is true, and to an empty string otherwise. github.token is the run's automatic token. No secret is added anywhere.

Permissions: format-n-lint, pnpm-audit, and the build jobs in app-build-deploy-dev.yml and app-build-deploy-release.yml (including build-demo) now request packages: read. This is the contract change above.

README: permission table, both caller examples, and a new consumer rule.

Why the app's .npmrc is the switch

The routing already has to live there, so the opt-in follows it and needs no new inputs across three workflows. An app that routes nothing to GitHub Packages gets no auth line and an empty token, exactly as today. Both apps' current .npmrc files evaluate to false.

Both apps are on pnpm 10.10, so they route with a scope mapping. The per-package gh: prefix backend uses for @centrifuge/protocol-events needs pnpm 11.20 (backend/docs/docker-images.md#L83), and this detection does not look for it.

A pnpm step that runs after the install (a build or verify script) logs Failed to replace env in config: ${NODE_AUTH_TOKEN} in opted-in apps, because the token is only in the install step's environment. Backend CI shows the same warning. It is harmless, and exporting the token job-wide to silence it would hand it to every later step.

Also in this PR: shorter production-promotion message

The Slack message notify-production-promotion posts on released drops the paragraph about the AUTHORIZED_DEPLOYERS gate and releasing the tag first. The message fires on released, so the tag is already the latest release, and app-promote-production.yml enforces the gate itself. The job step summary is unchanged. Rendered for invest-v3:

🚀 *invest-v3*: release *v3.3.3* deployed to staging.
• Release: <…/releases/tag/v3.3.3|v3.3.3> by ARR552

*To promote:*
gh workflow run promote-production.yml --repo centrifuge/apps-invest --ref main
Or via <…/actions/workflows/promote-production.yml|Promote Production> → Run workflow.
Emergency fallback: a Cloudflare admin can promote from the <…|dashboard>.
Once promoted, live at https://app.centrifuge.io

No input or caller change.

Rollout

  1. centrifuge/apps-management#1316 and centrifuge/apps-invest#341 merge. No behaviour change on their own.
  2. This PR merges.
  3. An app opts in on the branch that needs it: add @centrifuge:registry=https://npm.pkg.github.com to .npmrc, and install "@centrifuge/sdk": "npm:@centrifuge/sdk-internal@0.0.0-sha-<commit>".

Step 4 in CLAUDE.md ("point one app caller at your branch") does not exercise this change by itself: the reusable workflows call setup-app@main and build-app@main, so a caller pinned to this branch still runs the old composite actions.

Verification

  • actionlint 1.7.7 and yamllint (relaxed, line-length disabled) clean across .github and actions.
  • shellcheck clean on the new setup-app script. The single quotes around the placeholder are deliberate and annotated.
  • Detection regex tested against 9 cases: scope routed, spaces and trailing slash, default registry, trailing comment, commented out, auth line only, npmjs, and two lookalike hosts (npm.pkg.github.com.evil.example, npm.pkg.github.comx). Plus both apps' current .npmrc, which stay false.
  • Promotion message rendered locally from the step's own printf block with invest-v3 values.
  • No new third-party actions, so pinact is unaffected.

🤖 Generated with Claude Code

https://claude.ai/code/session_014vAMiNPVaNSZvobuesTQnA

setup-app now checks the app's .npmrc. When it routes a scope to
https://npm.pkg.github.com, setup-app appends the
//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN} placeholder to
~/.npmrc and reports github-packages=true. The install steps in
app-ci-checks and build-app then set NODE_AUTH_TOKEN to github.token.
Apps that route nothing there see no change: no auth line, and an empty
token in the install environment.

Contract change: every installing job (format-n-lint, pnpm-audit, and
the build jobs in app-build-deploy-dev and app-build-deploy-release) now
requests packages: read. A called job cannot request more than its
caller grants, so each caller must add packages: read before this
merges, or its next run fails at startup. The README permission table,
examples and consumer rules are updated to match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014vAMiNPVaNSZvobuesTQnA
@gpmayorga gpmayorga added the enhancement New feature or request label Sep 23, 2026 — with Claude
Drop the paragraph about the AUTHORIZED_DEPLOYERS gate and releasing the
tag first. The notification fires on `released`, so the tag is already
the latest release, and the promote workflow enforces the gate itself.
The headline now says the release is deployed to staging.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014vAMiNPVaNSZvobuesTQnA
@gpmayorga
gpmayorga marked this pull request as ready for review September 29, 2026 09:13
@gpmayorga
gpmayorga requested a review from hieronx as a code owner September 29, 2026 09:13
@gpmayorga
gpmayorga merged commit 53c3cbe into main Oct 2, 2026
3 checks passed
@gpmayorga
gpmayorga deleted the ci/setup-app-github-packages branch October 2, 2026 08:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants