[XELP] Publish releases to GitHub Packages - #5
Conversation
Replace the git tag and xelp/dist shadow release with a workflow that publishes to GitHub Packages as @plexinc/<name>, matching how the other Plex client repos consume private packages. Authentication is the workflow GITHUB_TOKEN, so the repository stores no publishing secret, and the package name is rewritten in CI rather than on xelp/main, leaving upstream merges unaffected. The lint and test suites previously ran as a side effect of npm version, which triggers preversion. This package has no prepublishOnly script, so without that side effect nothing would gate the publish. They now run as their own steps. Consumers keep the upstream package name by installing through an npm alias, so imports, bin names and plugin references do not change.
Both workflows compute the same MAJOR.MINOR.<date><PATCH> version and so want the same tag, and the shadow release force pushes it, so running the two against one commit means one clobbers the other. Park the shadow release rather than delete it, so restoring it is a rename. roku-client is the only consumer of this fork, and it keeps installing from the existing git tag until it moves to the @plexinc package, so nothing depends on this workflow staying runnable in the meantime.
Point the development dependency at the GitHub Packages release rather than a git tag, so a checkout no longer clones the brighterscript repo to build. The .npmrc tells npm where the @plexinc scope lives, matching the other Plex client repos. The peer dependency range is left alone. It is satisfied by the aliased package, which npm installs under the brighterscript name, so consumers resolve it the same way they do today. The swap was made with a targeted npm install rather than by regenerating the lockfile, which changed one entry out of 519. A clean re-resolve floats vscode-languageserver-protocol onto a release that ships exports with no main or types entry, and the TypeScript build then fails with about thirty type errors. That failure predates this change and is not caused by it.
There was a problem hiding this comment.
Pull request overview
Introduces a new manual release workflow to publish the xelp/main build to GitHub Packages (@plexinc/*) and adjusts the development dependency source so builds no longer clone brighterscript from a Git URL.
Changes:
- Switches the
brighterscriptdevDependency to an npm alias of@plexinc/brighterscriptand updates the lockfile accordingly. - Adds repo
.npmrcconfiguration for resolving@plexincpackages from GitHub Packages. - Adds
xelp_npm_release.ymlfor publishing to GitHub Packages and keeps the prior shadow release workflow as a disabled file.
Reviewed changes
Copilot reviewed 3 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Points brighterscript devDependency at npm:@plexinc/brighterscript. |
| package-lock.json | Updates the resolved brighterscript package metadata to GitHub Packages. |
| .npmrc | Configures @plexinc scope to resolve from GitHub Packages. |
| .github/workflows/xelp_shadow_release.yml.disabled | Keeps the old shadow-release workflow in a disabled form. |
| .github/workflows/xelp_npm_release.yml | Adds the new workflow that builds/tests and publishes to GitHub Packages, then tags + creates a GitHub release. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The build workflow runs npm ci, and this package now depends on @plexinc/brighterscript from GitHub Packages, so the install needs a token. Without it the job fails with a 401 before it gets as far as compiling. setup-node points the @plexinc scope at the registry and the token is given only to the install step, which is the only step here that reaches the network.
The token was on the job, which put it in the environment of every step, including any added later. It is only needed by the three steps that talk to the registry: the published version check, the install, and the publish. Building, linting, testing and packing do not reach the network. A step that runs npm against the registry has to opt in from now on, which is easy to forget, so the reason is written next to the first one.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 7 changed files in this pull request and generated 2 comments.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
.npmrc:3
- Project-level
.npmrcconfigures the GitHub Packages registry but does not provide an auth-token hook. Adding an_authTokenline that reads fromNODE_AUTH_TOKENmakes installs work consistently in CI and locally (without relying on a separate user-level npmrc).
@plexinc:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:always-auth=true
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 7 changed files in this pull request and generated 1 comment.
Suppressed comments (3)
Previously missed (1) — in code that hasn't changed since the last review.
.npmrc:3
- Since this repo now routes
@plexincinstalls through GitHub Packages, local development and any CI that doesn't setNODE_AUTH_TOKENwill fail with 401s. Consider expanding the header comment to state the token requirement (PAT with read:packages) to reduce setup friction.
# Use GitHub for @plexinc packages.
@plexinc:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:always-auth=true
.github/workflows/build.yml:23
- This workflow still uses floating action refs (actions/checkout@master and actions/setup-node@master). Because this PR is already touching this step, please pin to a tagged major version to avoid supply-chain risk and unexpected breakages from upstream changes.
registry-url: 'https://npm.pkg.github.com'
.github/workflows/create-package.yml:17
- This workflow uses floating action refs (actions/checkout@master and actions/setup-node@master). Since the PR already modifies this setup-node block, pin these actions to tagged major versions to avoid unexpected changes and improve supply-chain security.
with:
node-version: "14.19.0"
registry-url: 'https://npm.pkg.github.com'
scope: '@plexinc'
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 7 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
.github/workflows/create-package.yml:13
actions/checkout@masterandactions/setup-node@masterare floating references; this can change CI behavior unexpectedly and is a supply-chain risk. Pin to a stable version tag (or a commit SHA).
- uses: actions/checkout@master
- uses: actions/setup-node@master
.github/workflows/build.yml:20
- This workflow still uses floating action refs (
actions/checkout@master/actions/setup-node@master). Even though this hunk only changes thewith:block, pinning the action versions reduces supply-chain risk and avoids unexpected behavior changes.
with:
A repository's own GITHUB_TOKEN cannot read a package owned by another repository, so npm ci fails with a 403 on @plexinc/brighterscript. GH_TOKEN is the token the other Plex client repos already use for this. Only the install steps change. The published version check and the publish act on this repository's own package, where GITHUB_TOKEN is correct and already works. The fallback keeps a fork that has no @plexinc dependencies working on the repo token alone.
e602709 to
5905d07
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 7 changed files in this pull request and generated 1 comment.
Suppressed comments (3)
.github/workflows/xelp_npm_release.yml:161
- The dry-run path says it will “pack” (both in the workflow input description and PR description), but
npm pack --dry-rundoes not produce a tarball; it only prints what would be packed. If the intent is to actually generate the.tgzwithout publishing, runnpm packhere (still safe because it stays local).
- name: Pack without publishing
if: ${{ inputs.dryRun }}
run: npm pack --dry-run
.github/workflows/create-package.yml:16
package-lock.jsonislockfileVersion: 3(npm v7+), but this workflow sets Node 14.x (npm 6.x by default). That combination will typically makenpm cifail on a clean runner. Also, pinning Actions to@masteris a supply-chain risk because it can change without notice. Consider bumping Node to a modern LTS and pinning the Actions to a major tag.
- uses: actions/checkout@master
- uses: actions/setup-node@master
with:
node-version: "14.19.0"
registry-url: 'https://npm.pkg.github.com'
.github/workflows/build.yml:23
package-lock.jsonislockfileVersion: 3(npm v7+), but this workflow sets Node 14.x (which bundles npm 6.x by default). That combination will typically makenpm cifail on a clean runner. Also, pinning Actions to@masteris a supply-chain risk because it can change without notice. Consider bumping Node to a modern LTS and pinning the Actions to a major tag.
- uses: actions/setup-node@master
with:
node-version: "14.18.1"
architecture: 'x64' # fix for macos-latest
registry-url: 'https://npm.pkg.github.com'
The publish runs before the tag is pushed, and a published version cannot be replaced, so a tag that already exists would be discovered only after the package had shipped, leaving a release that no re-run can tag. The shadow release used this same version scheme, so its tags are real candidates. Check for the tag in the same preflight that checks the published version. Reading a dependency from another repository's package is granted through that package's Manage Actions access, which makes GITHUB_TOKEN sufficient. No organization secret reaches these forks, so the GH_TOKEN fallback could never have resolved to anything, and its presence only suggested otherwise. Also state explicitly that CI needs packages: read, rather than depending on a repository default that an organization can tighten, and stop describing the dry run as packing when it only reports what would be packed.
The lockfile became version 3 when the brighterscript pin was last bumped, and npm 6, which ships with the pinned Node 14, cannot read that format. Every job has failed on it since with "Cannot read property 'fs-extra' of undefined". It went unnoticed because these workflows only run on pull requests and on pushes to master, neither of which has happened on this fork since November. Upstream already runs 18.20.4, so this is picking up a version this fork was left behind on rather than diverging further. Its npm reads the lockfile, and the build, lint and test suites all pass on it.
Adds
xelp_npm_release.yml, which buildsxelp/mainand publishes it to GitHub Packagesas
@plexinc/bslint, replacing thexelp/distgit tag release. It authenticates with thebuilt in
GITHUB_TOKEN, so there is no publishing secret to store in this repo.Also points the
brighterscriptdevelopment dependency at@plexinc/brighterscript, so acheckout no longer clones that repo to build. The peer dependency range is left alone: npm
installs the aliased package under the
brighterscriptname, so it is satisfied andconsumers resolve it exactly as they do today. The swap was made with a targeted
npm install, which changed one lockfile entry out of 519.xelp_shadow_release.ymlis renamed to.disabledrather than deleted, since bothworkflows derive the same version and would fight over the same tag. Restoring it is a
rename, and it is a separate commit so it can be reverted on its own.
A
workflow_dispatchworkflow is only dispatchable from the default branch, so the firstrun happens after this merges. Run it with
dryRun: truefirst, which builds, lints, testsand packs without publishing.