ci: publish JS packages from GitHub Actions with npm trusted publishing - #157
Draft
lucarachiteanu wants to merge 5 commits into
Draft
lucarachiteanu wants to merge 5 commits into
lucarachiteanu wants to merge 5 commits into
Conversation
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…n master Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Moves publishing of the two JS client packages out of ADO and into GitHub Actions, in two steps — a
packjob that produces the.tgzfiles and publish jobs that push those same tarballs — and adds public npmjs as a second target via Trusted Publishing.Depends on #158, which fixes
repository.urlfor the JS client. npm provenance verifies that URL against the repository the build ran in and refuses to publish on a mismatch, so npmjs publishing cannot work until #158 merges.Why
ADO cannot publish to npmjs with Trusted Publishing at all: npm only trusts GitHub Actions OIDC identities. Once publishing has to happen in Actions for npmjs, doing GitHub Packages from the same place costs nothing and removes the
PublishNPMservice connection from the picture — a workflow in this repo gets aGITHUB_TOKENwithpackages: write, and bothcoreipcandcoreipc-webare already linked toUiPath/coreipc.To be clear about the motivation: the GitHub Packages publish is not currently broken. The
continueOnErrorcomment inazp-js.publish-npm.steps.yamlsays it is expected to fail after the May 2026 classic-PAT revocation, butcoreipchas versions dated 2026-07-24 (2.5.2,2.5.2-20260724-01/02), so that comment is stale. This is consolidation and hardening, not a repair.What changed
.github/workflows/cd-npm.yml(new) —repository_dispatch: publish-npm, payload{sha, version}, three jobs:pack— validates the payload (40-char SHA, plain semver), checks out that exact commit, cross-checks the dispatched version against the csproj<Version>at that commit (must equal it, or be it plus a build-number suffix), refuses any commit not merged to master, thennpm ci→ stamp →npm run build→ explicitnpm packof both prepack directories → verifies exactly two correctly-named tarballs → uploads them.publish-github-packages— environmentgithub-packages,packages: write+GITHUB_TOKEN, publishes both tarballs untouched. Runs for every build, prereleases included.publish-npmjs— stable versions only, environmentnpm,id-token: write, npm upgraded to^11.5.1, publishes@uipath/coreipconly.Both publishes skip if that exact version is already on the registry, matching
skip-existing: trueon the PyPI side — so a re-run resumes instead of dying on a duplicate after GitHub Packages has already gone out.@uipath/coreipc-webstays GitHub-Packages-only: it has never been published to npmjs, and a Trusted Publisher can only be configured on a name that already exists.src/CI/azp-js.publish-npm.steps.yaml— the twoNpm@1publish tasks are replaced by a dispatch step. It still downloads and extracts the artifact, but only to read the version out of the packeddist/prepack/node/package.jsonrather than recompute it, so there is one source of truth for what version the CI build actually produced.src/CI/azp-publish.yaml—Publish_NPMgains thegithub-dispatchvariable group; parameter label updated.Security posture
The repo is public, so the trigger and runner choices matter as much as the code:
refs/pull/*on a public repo, and this is what keeps one out.repository_dispatchrequires a token withcontents: write, and it always executes the default-branch copy of the workflow — so a PR cannot modifycd-npm.ymland have its version run.ubuntu-latest, not theuipath-*managed pool, so no untrusted code can reach UiPath machines. This diverges fromcd.yml, which commit 3853f6f (chore: change to centralized managed GitHub pool #150) moved onto the managed pool — worth a decision on whether that migration should hold for publish workflows on a public repo.GITHUB_TOKENis job-scoped; npmjs uses OIDC with no token at all.env:, never interpolated into arun:block. All actions are pinned to commit SHAs.This PR cannot be tested by CI
repository_dispatchalways runs the workflow file from the default branch, socd-npm.ymlwill not run from this branch under any circumstances. There is no green check to wait for here — the first real execution is the first dispatch after merge.cd.ymlhas the same property.Prerequisites before merge
@uipath/coreipc: repoUiPath/coreipc, workflowcd-npm.yml, environmentnpm.npmandgithub-packages, with required reviewers and "Protected branches only". Referencing an environment that does not exist auto-creates it unprotected, so without this the gate is decorative — andgithub-packagesis what replaces the approval ADO'sNPM-Packagesenvironment provided.github-dispatchvariable group is visible to thePublish_NPMstage, not justNotify_GitHub.ubuntu-latestjobs will queue indefinitely rather than fail.Known risk
It is not verified that npm generates provenance when publishing a pre-built tarball rather than from the package directory. If the first stable run fails on provenance, the fix is to move
npm packinto the npmjs job — which costs the guarantee that npmjs and GitHub Packages receive byte-identical artifacts.Not in scope
Build and test stay in ADO. Moving those too is viable — the
uipath-ipc-depsfeed is a transparent mirror (everyresolvedentry inpackage-lock.jsonpoints atregistry.npmjs.org) andNuGet.Configtargets only nuget.org, so nothing here needs an internal feed. But it needsChromeHeadlessand a Windows runner label confirmed first, it changes the prerelease version scheme since Actions has no equivalent of ADO's$(Rev:-rr)per-day counter, and it ends theNotify_GitHub→Publish_NPMcoupling that currently gates public PyPI on npm succeeding.🤖 Generated with Claude Code