Repository navigation
Publish contracts package under @paadev - #9
Conversation
📝 WalkthroughWalkthroughThe package name changed to ChangesPackage Publication
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant GitHubActions
participant Repository
participant NpmRegistry
GitHubActions->>Repository: Check out repository
GitHubActions->>GitHubActions: Configure Node.js 24 and npm trusted publishing
GitHubActions->>GitHubActions: Validate package contents and installation
GitHubActions->>NpmRegistry: Publish `@paadev/paa-contracts` publicly
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Pull request overview
This PR renames the root npm package to @paadev/paa-contracts and introduces a manually triggered GitHub Actions workflow intended to publish the package to npm using GitHub OIDC trusted publishing.
Changes:
- Renamed the npm package scope/name in
package.jsonto@paadev/paa-contracts. - Added a
workflow_dispatch-only npm publish workflow (publish-npm.yml) and pinned its actions to commit SHAs.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| package.json | Renames the npm package to the @paadev scope. |
| .github/workflows/publish-npm.yml | Adds a manual publish workflow intended for npm trusted publishing via GitHub OIDC. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| name: Publish npm package | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
| - name: Publish package | ||
| run: npm publish --access public |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
.github/workflows/publish-npm.yml (1)
3-4: 🔒 Security & Privacy | 🔵 TrivialProtect the manual publication ref.
workflow_dispatchallows a user with write access to select the branch for a run. Checkout then uses that ref. If thenpmenvironment has no required reviewers or branch/tag policy, this job can publish an unreviewed ref. Configure those protections or add an explicit release-ref gate. GitHub environments support required reviewers and branch or tag restrictions. (docs.github.com)Also applies to: 10-12
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/publish-npm.yml around lines 3 - 4, Protect the manual publication ref in the workflow_dispatch configuration and the npm publishing job: restrict the npm environment to approved release branches/tags and require reviewers, or add an explicit gate that rejects unapproved refs before checkout and publishing. Preserve manual dispatch only for authorized release refs.Source: MCP tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/publish-npm.yml:
- Around line 26-27: Add verification steps before the “Publish package” step in
the workflow: run npm pack --dry-run --json to validate the package contents,
then perform a clean public installation test for `@paadev/paa-contracts`@0.1.0.
Ensure both checks complete successfully before npm publish runs.
- Around line 21-24: Update the setup-node configuration in the publish workflow
to use an immutable release that removes the legacy dummy-token fallback for
trusted publishing, or explicitly delete the generated _authToken entry and
unset NODE_AUTH_TOKEN before npm publish. Preserve the existing Node 24 and npm
registry configuration.
---
Nitpick comments:
In @.github/workflows/publish-npm.yml:
- Around line 3-4: Protect the manual publication ref in the workflow_dispatch
configuration and the npm publishing job: restrict the npm environment to
approved release branches/tags and require reviewers, or add an explicit gate
that rejects unapproved refs before checkout and publishing. Preserve manual
dispatch only for authorized release refs.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9863a4af-a83f-48e3-b028-1a6236d22b63
📒 Files selected for processing (2)
.github/workflows/publish-npm.ymlpackage.json
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | ||
| with: | ||
| node-version: 24 | ||
| registry-url: https://registry.npmjs.org |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
npm_version="$(npm --version)"
if [ "$(printf '%s\n' '11.5.1' "$npm_version" | sort -V | head -n1)" != '11.5.1' ]; then
echo "npm $npm_version is below the trusted-publishing minimum."
exit 1
fi
npmrc="${NPM_CONFIG_USERCONFIG:-$HOME/.npmrc}"
if grep -q ':_authToken=' "$npmrc"; then
echo "Token authentication remains configured in $npmrc."
exit 1
fi
if [ -n "${NODE_AUTH_TOKEN:-}" ]; then
echo "NODE_AUTH_TOKEN is still set."
exit 1
fiRepository: RankOneLabs/paa
Length of output: 208
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- workflow ---'
cat -n .github/workflows/publish-npm.yml
printf '%s\n' '--- setup-node authutil at pinned commit ---'
curl -fsSL https://raw.githubusercontent.com/actions/setup-node/49933ea5288caeca8642d1e84afbd3f7d6820020/src/authutil.ts \
| nl -ba \
| sed -n '1,240p'
printf '%s\n' '--- setup-node action metadata at pinned commit ---'
curl -fsSL https://raw.githubusercontent.com/actions/setup-node/49933ea5288caeca8642d1e84afbd3f7d6820020/action.yml \
| nl -ba \
| sed -n '1,180p'Repository: RankOneLabs/paa
Length of output: 1062
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- setup-node authutil at pinned commit ---'
curl -fsSL https://raw.githubusercontent.com/actions/setup-node/49933ea5288caeca8642d1e84afbd3f7d6820020/src/authutil.ts \
| sed -n '1,240p'
printf '%s\n' '--- setup-node action metadata at pinned commit ---'
curl -fsSL https://raw.githubusercontent.com/actions/setup-node/49933ea5288caeca8642d1e84afbd3f7d6820020/action.yml \
| sed -n '1,180p'Repository: RankOneLabs/paa
Length of output: 4835
🌐 Web query:
npm trusted publishing setup-node _authToken NODE_AUTH_TOKEN issue 1551 npm 11.5.1
💡 Result:
The issue described in GitHub issue 1551 regarding actions/setup-node and npm Trusted Publishing (OIDC) stems from how registry-url historically interacted with .npmrc file generation [1]. When registry-url was specified, actions/setup-node previously injected a placeholder _authToken line (e.g., //registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}) into the .npmrc file [1][2]. Because npm CLI interprets the presence of this _authToken as a signal that authentication is "configured," it would attempt to use the token (which remained empty when NODE_AUTH_TOKEN was unset) instead of initiating the OIDC authentication flow, resulting in errors such as ENEEDAUTH or E404 [1][2][3]. Key aspects of this issue and its resolution: 1. Requirement for npm ≥ 11.5.1: npm versions older than 11.5.1 do not reliably support or prefer the OIDC flow when ambiguous authentication configurations exist [4][5][6]. npm 11.5.1 introduced native improvements that allow the CLI to correctly detect OIDC environments and prioritize OIDC over the legacy _authToken token-based flow [4][7][6]. 2. Resolution in actions/setup-node: To prevent this conflict, actions/setup-node was updated (most notably in PR #1558) to stop exporting a "dummy" or placeholder NODE_AUTH_TOKEN when no explicit token is provided [8]. This change ensures the .npmrc does not contain the _authToken directive unless the user specifically intends to use token-based authentication, thereby allowing the OIDC flow to trigger correctly [9][8]. 3. Recommended Setup: For users experiencing this issue, it is recommended to: - Use actions/setup-node@v6 (or later) and pin node-version: '24' (or higher), which includes the compatible npm version [7][6]. - Ensure the workflow has the required permissions: id-token: write [10][6]. - Avoid passing any NODE_AUTH_TOKEN secret to the npm publish step if relying on Trusted Publishing [10][7]. If you are using an older version of the action, you can manually unset the variable in your workflow to clear the conflict: NODE_AUTH_TOKEN="" npm publish or unset NODE_AUTH_TOKEN before the publish command [4].
Citations:
- 1: registry-url writes _authToken line that breaks npm Trusted Publisher OIDC when no NODE_AUTH_TOKEN is set actions/setup-node#1551
- 2: actions/setup-node registry-url interferes with OIDC trigger — example workflow fails with ENEEDAUTH when no NODE_AUTH_TOKEN npm/documentation#1960
- 3: Trusted Publisher documentation actions/setup-node#1445
- 4: Don't default NPM_AUTH_TOKEN to support NPM OIDC actions/setup-node#1440
- 5: Don't default NPM_AUTH_TOKEN to support NPM OIDC actions/setup-node#1440
- 6: https://gitea.rs.h3.ink/actions/setup-node/commit/670825a89dc0abd596e7a3abd0f5e3f6e5faf37c
- 7: https://www.rabinarayanpatra.com/blogs/how-to-enable-npm-trusted-publishing-github-actions-oidc
- 8: Remove dummy NODE_AUTH_TOKEN export actions/setup-node#1558
- 9: fix(#1440): Support NPM OIDC tokens by not exporting default NODE_AUTH_TOKEN actions/setup-node#1477
- 10: https://docs.npmjs.com/trusted-publishers/
🌐 Web query:
site:docs.npmjs.com trusted publishing npmrc _authToken NODE_AUTH_TOKEN
💡 Result:
Trusted publishing and the use of _authToken or NODE_AUTH_TOKEN represent two distinct methods for authenticating with the npm registry, with trusted publishing being the recommended, more secure approach for CI/CD environments [1][2][3]. Trusted Publishing Trusted publishing uses OpenID Connect (OIDC) to establish a trust relationship between your CI/CD provider and npm [1][4]. This eliminates the need for long-lived credentials like access tokens [1][2]. When configured, the npm CLI automatically detects the OIDC environment and performs the necessary token exchange to authenticate your publish operation [1]. No manual handling of tokens or setting _authToken in.npmrc is required for this process [1][3]. _authToken and NODE_AUTH_TOKEN These are traditional methods for providing credentials to npm [2][5]. - _authToken: Typically defined within an.npmrc file using the syntax //registry.npmjs.org/:_authToken=${NPM_TOKEN} [6][2]. It informs the npm CLI of the specific token to use when communicating with the registry [6]. - NODE_AUTH_TOKEN: An environment variable often used in CI/CD workflows to pass an authentication token to the npm CLI [1][2]. When an.npmrc file references an environment variable (as shown above), the CLI reads the value from the environment variable (e.g., NODE_AUTH_TOKEN) and uses it to authenticate [2]. Key Differences - Security: Trusted publishing is the industry-standard, secure approach because it removes the risk of leaking long-lived tokens [1][2]. Traditional tokens (managed via _authToken or NODE_AUTH_TOKEN) are persistent and carry security risks if compromised [1][7]. - Automation: Trusted publishing manages authentication automatically through OIDC claims provided by your CI/CD platform [1][4]. Traditional methods require you to manually generate, store, and inject tokens into your CI/CD environment as secrets [2]. Recommendation For CI/CD workflows, you should prioritize migrating to trusted publishing [2][3]. Traditional authentication using _authToken or NODE_AUTH_TOKEN should generally be reserved for scenarios where trusted publishing is not supported or for local development environments [2].
Citations:
- 1: https://docs.npmjs.com/trusted-publishers/
- 2: https://docs.npmjs.com/using-private-packages-in-a-ci-cd-workflow/
- 3: https://docs.npmjs.com/creating-and-publishing-unscoped-public-packages/
- 4: https://docs.npmjs.com/cli/v12/commands/npm-trust/
- 5: https://docs.npmjs.com/about-access-tokens/
- 6: https://docs.npmjs.com/cli/v11/configuring-npm/npmrc/
- 7: https://docs.npmjs.com/requiring-2fa-for-package-publishing-and-settings-modification/
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- issue 1551 ---'
curl -fsSL https://api.github.com/repos/actions/setup-node/issues/1551 \
| grep -E '"title"|"state"|"body"|"html_url"' \
| sed -n '1,40p'
printf '%s\n' '--- issue 1551 comments containing npm, OIDC, token, or setup-node ---'
curl -fsSL 'https://api.github.com/repos/actions/setup-node/issues/1551/comments?per_page=100' \
| grep -Ei 'npm|oidc|authToken|NODE_AUTH_TOKEN|setup-node|fixed|workaround' \
| sed -n '1,160p'
printf '%s\n' '--- current setup-node authutil ---'
curl -fsSL https://raw.githubusercontent.com/actions/setup-node/main/src/authutil.ts \
| grep -n -A8 -B8 -E 'authString|NODE_AUTH_TOKEN|exportVariable'Repository: RankOneLabs/paa
Length of output: 6231
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- issue 1440 ---'
curl -fsSL https://api.github.com/repos/actions/setup-node/issues/1440 \
| grep -E '"title"|"state"|"body"|"html_url"' \
| sed -n '1,80p'
printf '%s\n' '--- pull request 1558 ---'
curl -fsSL https://api.github.com/repos/actions/setup-node/pulls/1558 \
| grep -E '"title"|"state"|"merged_at"|"body"|"html_url"' \
| sed -n '1,80p'
printf '%s\n' '--- setup-node tags and commits related to auth fallback ---'
curl -fsSL 'https://api.github.com/repos/actions/setup-node/commits?path=src/authutil.ts&per_page=100' \
| grep -E '"sha"|"message"' \
| grep -Ei 'auth|token|oidc|trusted|dummy|placeholder' \
| sed -n '1,120p'Repository: RankOneLabs/paa
Length of output: 4279
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import json
import urllib.request
def get(url):
req = urllib.request.Request(url, headers={"User-Agent": "review-verifier"})
with urllib.request.urlopen(req) as r:
return json.load(r)
for label, url in [
("issue-1440", "https://api.github.com/repos/actions/setup-node/issues/1440"),
("comments-1440", "https://api.github.com/repos/actions/setup-node/issues/1440/comments?per_page=100"),
("comments-1551", "https://api.github.com/repos/actions/setup-node/issues/1551/comments?per_page=100"),
("pr-1558", "https://api.github.com/repos/actions/setup-node/pulls/1558"),
("pinned-commit", "https://api.github.com/repos/actions/setup-node/commits/49933ea5288caeca8642d1e84afbd3f7d6820020"),
]:
data = get(url)
print(f"\n--- {label} ---")
if isinstance(data, list):
for item in data:
print(f"{item.get('user', {}).get('login')}:")
print(item.get("body", ""))
else:
print("title:", data.get("title"))
print("state:", data.get("state"))
print("merged_at:", data.get("merged_at"))
print("sha:", data.get("sha"))
print("date:", data.get("commit", {}).get("committer", {}).get("date"))
print("body:", data.get("body", ""))
PYRepository: RankOneLabs/paa
Length of output: 2473
🏁 Script executed:
#!/bin/bash
set -euo pipefail
show_comments() {
curl -fsSL "$1" | python3 -c '
import json, sys
for item in json.load(sys.stdin):
print("USER:", item.get("user", {}).get("login"))
print("CREATED:", item.get("created_at"))
print(item.get("body", ""))
print("---")
'
}
printf '%s\n' '--- issue 1440 comments ---'
show_comments 'https://api.github.com/repos/actions/setup-node/issues/1440/comments?per_page=100'
printf '%s\n' '--- issue 1551 comments ---'
show_comments 'https://api.github.com/repos/actions/setup-node/issues/1551/comments?per_page=100'
printf '%s\n' '--- pull request 1558 ---'
curl -fsSL https://api.github.com/repos/actions/setup-node/pulls/1558 \
| python3 -c '
import json, sys
x=json.load(sys.stdin)
for k in ("title", "state", "created_at", "updated_at", "merged_at", "merge_commit_sha", "body"):
print(f"{k}: {x.get(k)}")
'
printf '%s\n' '--- pinned commit metadata ---'
curl -fsSL https://api.github.com/repos/actions/setup-node/commits/49933ea5288caeca8642d1e84afbd3f7d6820020 \
| python3 -c '
import json, sys
x=json.load(sys.stdin)
print("sha:", x.get("sha"))
print("date:", x.get("commit", {}).get("committer", {}).get("date"))
print("message:", x.get("commit", {}).get("message"))
'Repository: RankOneLabs/paa
Length of output: 36402
Remove the legacy token fallback before trusted publishing.
This pinned setup-node commit writes an _authToken entry and exports NODE_AUTH_TOKEN=XXXXX-... when no token exists. This can cause npm publish to use invalid token authentication and fail with ENEEDAUTH, E404, or an invalid OIDC token error. Upgrade to an immutable setup-node release that includes the dummy-token removal, or remove the generated _authToken line and unset NODE_AUTH_TOKEN before publishing.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/publish-npm.yml around lines 21 - 24, Update the
setup-node configuration in the publish workflow to use an immutable release
that removes the legacy dummy-token fallback for trusted publishing, or
explicitly delete the generated _authToken entry and unset NODE_AUTH_TOKEN
before npm publish. Preserve the existing Node 24 and npm registry
configuration.
Source: MCP tools
|
Addressed the latest review round in 4378f11:
Validated the packaging/install sequence locally for No |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/publish-npm.yml:
- Around line 41-43: Update the publish workflow around the existing local
tarball installation and package.json validation to add a separate clean
temporary-directory install of the exact public package spec
`@paadev/paa-contracts`@0.1.0. Run this registry check before publishing when that
version already exists; otherwise run it after publication with retry handling
for registry propagation, while preserving the existing local tarball check.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 8031d1d0-32b2-4b29-8e14-0dea23ed1984
📒 Files selected for processing (1)
.github/workflows/publish-npm.yml
| npm install --ignore-scripts --prefix "$install_dir" "$RUNNER_TEMP/$package_tarball" | ||
| node -e "const p = require(process.argv[1]); if (p.name !== '@paadev/paa-contracts') process.exit(1)" \ | ||
| "$install_dir/node_modules/@paadev/paa-contracts/package.json" |
There was a problem hiding this comment.
Add the public-registry installation check.
This command installs the local tarball. It does not install @paadev/paa-contracts@0.1.0 from the public registry. npm treats a local tarball and a registry name@version spec as different inputs. (docs.npmjs.com)
Keep the local tarball check. Add a separate clean temporary-directory install of the exact public package. Run it before publication when version 0.1.0 already exists. Otherwise, run it after publication with retry handling for registry propagation.
Suggested public installation check
- name: Publish package
run: npm publish --access public
+
+ - name: Verify public installation
+ run: |
+ public_install_dir="$(mktemp -d)"
+ npm install --ignore-scripts --prefer-online \
+ --registry https://registry.npmjs.org \
+ --prefix "$public_install_dir" \
+ '`@paadev/paa-contracts`@0.1.0'
+ node -e "const p = require(process.argv[1]); if (p.name !== '`@paadev/paa-contracts`' || p.version !== '0.1.0') process.exit(1)" \
+ "$public_install_dir/node_modules/@paadev/paa-contracts/package.json"🧰 Tools
🪛 zizmor (1.29.0)
[warning] 41-41: ad-hoc installation of packages (adhoc-packages): installs a package outside of a lockfile
(adhoc-packages)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/publish-npm.yml around lines 41 - 43, Update the publish
workflow around the existing local tarball installation and package.json
validation to add a separate clean temporary-directory install of the exact
public package spec `@paadev/paa-contracts`@0.1.0. Run this registry check before
publishing when that version already exists; otherwise run it after publication
with retry handling for registry propagation, while preserving the existing
local tarball check.
Summary
@paadev/paa-contractsVerification
npm pack --dry-run --json@paadev/paa-contracts@0.1.0verified separatelynpm trusted publisher
Configure the existing package for GitHub Actions with repository
RankOneLabs/paa, workflowpublish-npm.yml, environmentnpm, and publishing allowed.Summary by CodeRabbit
New Features
Changes
@paadev/paa-contracts.