Conversation
Add a trusted-publishing workflow for published releases with explicit-tag recovery, preflight asset validation, and integrity-checked idempotent reruns. Document npm trusted-publisher setup and the current release-asset blocker. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 23fc3b8d-7678-46d3-9fe7-875d8311b526
Select only newly prefixed publishable npm tarballs, leave legacy launcher archives untouched, and reject old releases without the complete new asset set. Cover mixed and legacy-only release fixtures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 23fc3b8d-7678-46d3-9fe7-875d8311b526
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The dist-tag recheck has a race that can still move a channel backward during concurrent external publication.
Review effort: Balanced
Findings: 1
Open (1)
What changed in this PR
Adds secure npm publication from GitHub release tarballs with validation and recovery safeguards.
Changes:
- Adds an OIDC-based release publishing workflow.
- Validates package assets, metadata, integrity, and dist-tags.
- Adds contract tests and cutover documentation.
| File | Description |
|---|---|
.github/workflows/publish-npm.yml |
Defines the trusted publishing workflow. |
script/publish-npm-release.mjs |
Validates and publishes nine npm packages. |
test/publish-npm-release.test.mjs |
Tests validation, recovery, and publishing behavior. |
README.md |
Documents setup and cutover requirements. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+170
to
+174
| const tags = JSON.parse(run("npm", ["view", item.name, "dist-tags", "--json", "--registry", "https://registry.npmjs.org"])); | ||
| if (item.tag === channel && tags[channel] && compareVersions(tags[channel], version) > 0) { | ||
| item.tag = `release-${version.replaceAll(".", "-")}`; | ||
| } | ||
| run("npm", ["publish", item.file, "--ignore-scripts", "--access", "public", "--tag", item.tag, "--registry", "https://registry.npmjs.org"]); |
Require an operator-confirmed cutover before publishing with channel tags; document retirement and draining of the old publisher and correct the recheck comment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 23fc3b8d-7678-46d3-9fe7-875d8311b526
This was referenced Sep 29, 2026
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.

Why
npm publishing should be triggered by the published GitHub release in
github/copilot-cli, with an explicit-tag manual recovery path. npm auth uses trusted publishing (OIDC), not an npm token. The runtime repository's internal feed and ancillary release jobs remain separate; its public release is published only after assets are complete.What changed
release: published, or manually onmainwith an explicit published release tag. Always check out the trusted script frommain, never the release tag.npm-github-copilot-${VERSION}.tgz(umbrella) andnpm-github-copilot-${VERSION}-${PLATFORM}.tgz(eight platform subpackages:darwin-arm64,darwin-x64,linux-arm64,linux-x64,linuxmusl-arm64,linuxmusl-x64,win32-arm64,win32-x64). Existinggithub-copilot-*.tgzlauncher bundles remain untouched and are never published to npm.dist.integrityfor safe partial reruns. Use a version-specific npm tag for an older missing version instead of movinglatestorprereleasebackward. Fail explicitly when a stale dist-tag needs npm-admin repair rather than silently skipping it.Validation
node --test test/publish-npm-release.test.mjs(13 passing contract tests using real test tarballs and stubbed GitHub/npm boundaries, including mixed legacy/new assets, legacy-only rejection, and mislabeled new assets).git diff --check.v1.0.90-4release has nonpm-github-copilot-*.tgzassets and is rejected before downloading or publishing.Required setup / cutover blocker
Configure npm trusted publishing with direct
npm publishpermission for all nine@github/copilot*packages, using repositorygithub/copilot-cliand workflow filenamepublish-npm.yml. The runtime release artifact producer must attach the nine actual npm package tarballs under the newnpm-github-copilot-asset names while preserving existing assets. Do not cut over runtime npm publication until this PR is merged, all nine npm trusted publishers are configured, and the new release assets are present.