Skip to content

feat(ci): install through a private npm registry on self-hosted runners - #88

Merged
oto-macenauer-absa merged 1 commit into
masterfrom
feat/private-npm-registry
Sep 5, 2026
Merged

feat(ci): install through a private npm registry on self-hosted runners#88
oto-macenauer-absa merged 1 commit into
masterfrom
feat/private-npm-registry

Conversation

@oto-macenauer-absa

Copy link
Copy Markdown
Collaborator

What

Consuming repositories may run on self-hosted runners inside a private network where registry.npmjs.org is unreachable and every package must come from an internal Artifactory. Neither publishing action nor the reusable build workflow offered a way to install from anywhere but the public registry, and build-image.yml hard-coded ubuntu-latest.

The lockfiles stay exactly as they are. npm's replace-registry-host (default npmjs) rewrites a resolved host that is the default registry to the configured one at fetch time, and the integrity hashes still verify because the mirror serves the same tarballs. So one lockfile, one action ref and one workflow serve both runner populations; what was missing was a way to name the registry. Both actions and the workflow now take npm-registry / npm-token (and node-mirror / node-mirror-token for setup-node), and the workflow takes runs-on. All default to the current behaviour.

The registry is applied as project-level npm config next to the lockfile being installed, for that install only: the runner's own npm configuration stays layered underneath (a runner with an ~/.npmrc naming the mirror needs no input at all), nothing is exported into the calling workflow's later steps, and the token is referenced from the environment rather than written to disk.

The corollary is a rule CI now enforces: every resolved in both lockfiles must stay on registry.npmjs.org, because npm rewrites only the default host and a lockfile regenerated behind a corporate .npmrc installs in one network only.

Changes

  • actions/lib/npm-registry.sh — writes the project .npmrc from KB_NPM_REGISTRY / KB_NPM_TOKEN; no-op when unset; rejects anything that is not a single http(s) URL.
  • actions/publish-docs/action.yml, actions/publish-single-page-docs/action.yml — the four new inputs; setup-node gets mirror / mirror-token; the install runs the script first and carries the token in its environment.
  • .github/workflows/build-image.yml — inputs runs-on (a label, or JSON for several labels / a runner group), npm-registry, node-mirror; secrets npm-token, node-mirror-token; the same .npmrc logic inlined against the knowledge-base/ checkout so an older pinned kb-ref still honours it; ASTRO_TELEMETRY_DISABLED on the build.
  • .github/workflows/ci.yml — the deployment dry run passes runs-on in its JSON form, so the parsing branch of the expression runs in CI.
  • tests/private-registry.spec.js — the lockfile rule, the inputs on all three manifests, and the script (no-op, URL normalisation, token never on disk, bad input rejected).
  • .gitattributes*.sh checked out with LF so the script runs under Git bash on a CRLF checkout.
  • Docs: contract/DEPLOYMENT.md (a "Private networks" section and checklist items, including what no input can cover: the Docker daemon's mirror, GitHub's cache service), actions/publish-docs/README.md, contract/SINGLE_PAGE.md (inputs, a private-network subsection, troubleshooting rows), examples/deployment-repo (the inputs, commented), AGENTS.md / CONTRIBUTING.md (the lockfile rule), CLAUDE.md (the new spec).

Verification

npm ci of actions/ was run locally through a logging reverse proxy standing in for Artifactory, with a fresh cache each time:

Configuration Result
--registry=<proxy>, replace-registry-host=npmjs (npm's default) 174/174 tarballs fetched through the proxy, exit 0
project .npmrc written by npm-registry.sh with a token 174/174 through the proxy, Authorization: Bearer … on every request, exit 0
--registry=<proxy>, replace-registry-host=never 0 tarballs through the proxy — npm went to registry.npmjs.org directly, which is the behaviour a non-default resolved host would get
  • npm run build:headless — green
  • npm test — green (includes the new spec: 10 tests)
  • npx playwright test --config=playwright.config.ci.js — green
  • cd actions && npm run selftest — green
  • All five touched YAML manifests parse with the same yaml package CI uses

Not verified: an actual self-hosted runner behind Artifactory, and the runs-on JSON form on a runner group. The CI dry run exercises the JSON-array branch on ubuntu-latest.

Closes #87

🤖 Generated with Claude Code

https://claude.ai/code/session_01PYtmxSeSXFg4wEXRcKCmAi

Consuming repositories may run on runners inside a private network where
registry.npmjs.org is unreachable and every package must come from an
internal Artifactory. Neither publishing action nor the reusable build
workflow could be pointed anywhere else, and build-image.yml hard-coded
ubuntu-latest.

The lockfiles need no change: npm's replace-registry-host (default
`npmjs`) rewrites the default host to the configured registry at fetch
time and the integrity hashes still verify against the mirror's tarballs.
Both actions and the workflow now take npm-registry / npm-token and
node-mirror / node-mirror-token; the workflow also takes runs-on. All
default to the current behaviour. The registry is applied as project-level
npm config for that one install, with the token read from the environment
rather than written to disk.

The corollary is a rule CI now enforces: every `resolved` in both
lockfiles stays on registry.npmjs.org, because npm rewrites only the
default host.

Closes #87

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PYtmxSeSXFg4wEXRcKCmAi
@oto-macenauer-absa
oto-macenauer-absa merged commit 83d63d2 into master Sep 5, 2026
8 checks passed
@oto-macenauer-absa
oto-macenauer-absa deleted the feat/private-npm-registry branch September 5, 2026 09:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Shared actions and reusable workflow cannot install from a private npm registry (Artifactory) on self-hosted runners

1 participant