Skip to content

ci: publish to npm on tag push - #5

Merged
vib795 merged 1 commit into
mainfrom
ci/release-on-tag
Aug 8, 2026
Merged

ci: publish to npm on tag push#5
vib795 merged 1 commit into
mainfrom
ci/release-on-tag

Conversation

@vib795

@vib795vib795 commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Publishing 0.1.0 cost a 2FA recovery code. The codes are finite and single-use, which is a poor place for a release process to live.

What a v* tag now does

  1. Runs the full test matrix (test.yml gained a workflow_call trigger so this reuses it rather than duplicating it)
  2. Asserts the tag matches package.json version — a mismatch means someone tagged the wrong commit or skipped the bump, and npm never gives a version number back
  3. Asserts the version is not already published — turns a post-upload 403 into a one-line failure
  4. Publishes with --provenance, which ties the tarball to the commit and workflow run and shows the badge on npm
  5. Cuts the GitHub Release with --verify-tag

The matrix runs here rather than trusting the run on main, because a tag can point at any commit — including one main never saw.

Before this can work

Add an NPM_TOKEN repository secret: a granular access token scoped to @vib795, read+write, with bypass 2FA enabled. Without it the publish step fails on auth.

Not retroactive

v0.1.0 was tagged and published by hand before this existed, so this takes effect from the next tag.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Improved the release process with automated package publishing and GitHub Release creation.
    • Added version validation to help prevent publishing mismatched or duplicate releases.
    • Releases now include provenance information for improved package authenticity and traceability.
    • Automated testing runs as part of the release process to help ensure published versions meet quality standards.

Releases were blocked on a human with a 2FA recovery code, which is a bad
place for a release process to live: the codes are finite, single-use, and
spending one is not something you want between a fix and its users.
A v* tag now runs the full test matrix, asserts the tag agrees with
package.json, asserts the version is not already on the registry, publishes
with provenance, and cuts the GitHub Release.
The matrix runs again here rather than trusting the run on main, because a
tag can point at any commit, including one main never saw.
Requires the NPM_TOKEN repository secret: a granular access token scoped to
@vib795 with 2FA bypass enabled.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The workflows add reusable test execution and a tag-triggered release process. The release process validates the tag and package version, prevents duplicate npm publication, publishes with provenance, and creates a GitHub Release.

Changes

Release Pipeline

Layer / File(s)Summary
Reusable test workflow
.github/workflows/test.yml
The test workflow now supports workflow_call in addition to its existing triggers.
Tagged package release
.github/workflows/release.yml
The new workflow runs tests, validates version data, publishes the package to npm, and creates a GitHub Release for v* tags.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
participant GitHubTag
participant TestWorkflow
participant PublishJob
participant NpmRegistry
participant GitHubRelease
GitHubTag->>TestWorkflow: invoke reusable tests
TestWorkflow-->>PublishJob: return test result
PublishJob->>PublishJob: validate tag and package version
PublishJob->>NpmRegistry: publish package with provenance
PublishJob->>GitHubRelease: create release with generated notes
Loading

Poem

I’m a rabbit with a tagged release,
Tests hop first, then checks bring peace.
npm gets a provenance bow,
GitHub notes are written now.
One clean carrot-sized deploy!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the main change: automated npm publishing triggered by tag pushes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/release-on-tag

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@vib795
vib795 merged commit 8a1107c into mainAug 8, 2026
9 of 10 checks passed
@vib795
vib795 deleted the ci/release-on-tag branch August 8, 2026 00:24

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 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/release.yml:
- Around line 65-78: Make the Publish and Cut the GitHub Release steps
independently idempotent: retry npm publication when the package version is
absent, but skip it only after confirming that exact version already exists;
separately check whether the GitHub release for GITHUB_REF_NAME exists and
create it when missing, so reruns can restore only the release without being
blocked by npm view.
- Line 27: Update the actions/checkout@v4 step in the publish job to set
persist-credentials to false, while preserving the explicit GH_TOKEN used by gh
release create.
- Around line 51-60: Update the “Version must not already be published” step to
provide NODE_AUTH_TOKEN to the npm view lookup, distinguish a confirmed
not-found result from authentication, registry, or network errors, and fail the
workflow for every result except confirmed absence; retain the existing error
and success messages for published and unpublished versions.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d4443e0f-9b1a-49ab-b76c-3b1fc0d657e4

📥 Commits

Reviewing files that changed from the base of the PR and between 01dd384 and 07cb679.

📒 Files selected for processing (2)
  • .github/workflows/release.yml
  • .github/workflows/test.yml

contents: write # cut the GitHub Release
id-token: write # sign the npm provenance attestation
steps:
- uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"== workflow excerpt =="
sed -n '1,110p' .github/workflows/release.yml
echoecho"== checkout occurrences =="
rg -n "actions/checkout|persist-credentials|permissions:|contents:" .github/workflows/release.yml

Repository: vib795/agent-memory

Length of output: 3213


🌐 Web query:

actions/checkout v4 action.yml persist-credentials default true

💡 Result:

In the actions/checkout v4 action, the persist-credentials input has a default value of true [1][2][3]. When this setting is enabled (the default), the action configures the repository's local git configuration to include the authentication token or SSH key used for the checkout [2][4]. This allows subsequent git commands executed within the runner to be authenticated automatically [2][4]. The action removes this token during the post-job cleanup phase [2][4]. If you wish to prevent the action from adding these credentials to the local git configuration, you must explicitly set persist-credentials to false in your workflow file [2][4][5]: - uses: actions/checkout@v4 with: persist-credentials: false Disabling this setting is often recommended if you are concerned about credential exposure (for example, if you archive and upload the repository as a workflow artifact) [5].

Citations:


Disable checkout credential persistence in the publish job.

actions/checkout@v4 leaves persist-credentials enabled by default, so the write-capable checkout token remains available to later commands in this job. Set persist-credentials: false; gh release create already receives a token explicitly through GH_TOKEN.

Suggested change
 - uses: actions/checkout@v4
+ with:+ persist-credentials: false
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.29.0)

[warning] 27-27: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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/release.yml at line 27, Update the actions/checkout@v4
step in the publish job to set persist-credentials to false, while preserving
the explicit GH_TOKEN used by gh release create.

Sources: MCP tools, Linters/SAST tools

Comment on lines +51 to +60
- name: Version must not already be published
run: |
set -euo pipefail
name=$(node -p "require('./package.json').name")
ver=$(node -p "require('./package.json').version")
if npm view "$name@$ver" version >/dev/null 2>&1; then
echo "::error::$name@$ver is already on the registry"
exit 1
fi
echo "$name@$ver is unpublished; proceeding"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"## workflow excerpt"
nl -ba .github/workflows/release.yml | sed -n '1,120p'echoecho"## node/npm usage in workflow"
grep -nE 'NODE_AUTH_TOKEN|npm|setup-node|package-lock.json|package\.json|registry' .github/workflows/release.yml ||trueechoecho"## package registry/auth hints"
sed -n '1,220p' package.json ||true
[ -f package-lock.json ] && sed -n '1,80p' package-lock.json ||true

Repository: vib795/agent-memory

Length of output: 217


🌐 Web query:

npm view command exit code 404 response npm 404 error exit code documentation

💡 Result:

When the npm CLI encounters an E404 error—most commonly when a requested package or version cannot be found in the registry—it typically exits with a non-zero exit code (specifically 1) [1][2][3]. Key details regarding npm view and E404 behavior include: 1. Exit Code: When npm view fails to find a package or a specific version, it reports an E404 error and terminates with a non-zero exit code (typically 1) [1][2][3]. This ensures that automated scripts and CI/CD pipelines can detect the failure [1][2]. 2. Error Context: The E404 error is explicitly logged to stderr, detailing that the requested resource is not available in the registry [2][3][4]. 3. Notable Edge Cases: There have been documented instances where npm commands may exit with code 0 despite a failure to find specific tags (such as npm view package@latest when the tag itself is missing), which has been a subject of bug reports [1]. 4. General Error Handling: The npm CLI determines exit codes based on error codes (like E404) or defaults to 1 for general failures [5]. If you are encountering this in an automated environment, you should rely on the non-zero exit code to signal that the lookup was unsuccessful, rather than relying solely on the presence or absence of output to stdout [1][2].

Citations:


🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"## release workflow excerpt"
awk '{printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml | sed -n '1,130p'echoecho"## auth/npm related lines"
awk '{if (/NODE_AUTH_TOKEN|npm|setup-node|registry|package-lock|package\.json/) printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml
echoecho"## package registry/auth hints"
awk '{printf "%6d\t%s\n", NR, $0}' package.json | sed -n '1,220p'
[ -f package-lock.json ] && awk '{printf "%6d\t%s\n", NR, $0}' package-lock.json | sed -n '1,80p'

Repository: vib795/agent-memory

Length of output: 6378


🌐 Web query:

GitHub Actions setup-node NODE_AUTH_TOKEN npm view npm publish publishConfig registry-url scoped package

💡 Result:

To publish a scoped package to a specific registry using GitHub Actions and the setup-node action, you must correctly configure both the authentication environment and the registry mapping [1][2]. The setup-node action automates the creation of an.npmrc file that configures your registry and authentication [1][3]. Workflow Configuration 1. Use the setup-node action to define the target registry and the package scope [4][1]. 2. Provide an authentication token via the NODE_AUTH_TOKEN environment variable [1]. Example: - uses: actions/setup-node@v4 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org/' # Or your private registry URL scope: '@your-scope' - run: npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} Key Components - registry-url: This input instructs setup-node to write the registry URL to a project-level.npmrc file [4][3]. - scope: When provided, setup-node configures the.npmrc to associate this scope with the specified registry [3][5]. If not provided, it may default to the repository owner when using the GitHub Packages registry [4][2]. - NODE_AUTH_TOKEN: This environment variable is required by npm to authenticate requests [1]. The setup-node action automatically injects this token into the generated.npmrc [1][3]. Handling publishConfig If you need to ensure a package is always published to a specific registry regardless of local or global.npmrc settings, you can define it in your package.json [6]: { "publishConfig": { "@your-scope:registry": "https://registry.npmjs.org/" } } This configuration is particularly useful for scoped packages to avoid conflicts with default registry settings [7][8]. When using this method, ensure your registry credentials are still properly configured in the environment (e.g., via setup-node) [1]. Important Note: GitHub Packages (GPR) exclusively supports scoped packages (e.g., @owner/package-name) [5][9]. Ensure your package name in package.json adheres to this format if you are targeting GPR [5].

Citations:


🌐 Web query:

npm cli npm view private package 404 E404 non-zero exit code npm 404

💡 Result:

When you receive an E404 error with a non-zero exit code while running npm view on a private package, it generally indicates that the npm CLI could not find the package manifest at the specified or default registry [1][2]. This error typically occurs for the following reasons: 1. Lack of Authentication: If the package is private (e.g., restricted access) and you are not authenticated, the registry will return a 404 (Not Found) instead of a 403 (Forbidden) to prevent leaking the existence of private packages to unauthenticated users [3]. Ensure you are logged in (npm login) or have the correct authentication token (e.g., NODE_AUTH_TOKEN) configured for your environment [3]. 2. Incorrect Registry Configuration: npm might be looking at the public registry (registry.npmjs.org) instead of your private registry [4][5]. Check your.npmrc file to ensure your scope is correctly mapped to the intended private registry URL (e.g., @mycompany:registry=https://npm.pkg.github.com/) [5][2]. 3. Workspace/Bulk Operations: If you are running npm view with workspace flags (-ws), the command may fail and exit if it encounters a 404 for any individual workspace, including private ones that have not yet been published or are inaccessible [1][6]. Recent versions of the npm CLI have introduced improvements to handle these workspace-related 404 errors more gracefully [1]. 4. Package or Tag Absence: The package itself, or the specific version/tag you are querying, may genuinely not exist in the targeted registry [7][2]. To debug, you can run the command with increased verbosity to see exactly which registry and URL the CLI is attempting to access: npm view -dddd [5][2] This will help you verify if the CLI is resolving to the registry you expect and if the authentication headers are being included in the request [5][2].

Citations:


🌐 Web query:

npm view npm view package version output empty stderr exit code 0

💡 Result:

When you run the npm view command and it returns an empty output with an exit code of 0, it typically indicates that the command successfully executed but could not find the specific package, version, or tag you requested [1][2][3]. Historical context and behavior: - Legacy Behavior: In older versions of the npm CLI, npm view would frequently return an empty string and a success exit code (0) when a requested version or tag did not exist in the registry [4][5][6]. This was often used by automated scripts to verify if a package was missing [4][5]. - Recent Changes: Newer versions of the npm CLI have been updated to treat these cases as errors, generally returning an E404 error code and a non-zero exit code [4][7][6]. If you are encountering an empty output with a zero exit code, you are likely using an older version of npm or interacting with a specific registry configuration that causes this behavior [2][3][6]. - Underlying Cause: The primary cause is often that the package does not have a version tagged as "latest" (which is the default tag if none is specified), or the specific version/tag requested does not exist on the target registry [1][2][4]. Recommendations: - Check your npm version: Run npm -v to see if you are using an older version. Upgrading may provide more consistent error reporting [6]. - Verify the registry: If you are using a private registry (like Nexus or GitHub Packages), ensure it is configured correctly, as some third-party registries may not handle metadata requests in the exact way the npm CLI expects [1][2][3]. - Handle empty output in scripts: If you must rely on existing behavior, ensure your scripts are designed to handle both empty output and potential error states, especially as newer versions of npm are moving toward stricter E404 reporting [4][5].

Citations:


Fail closed when checking npm publication state.

The current check treats every failed npm view result as “unpublished”, including auth failures, registry errors, and network failures. NODE_AUTH_TOKEN is only provided during npm publish, so npm view runs as an anonymous public lookup and cannot distinguish an unpublished version from a private package or transient failure. Provide the token on this step and abort unless the lookup is confirmed absent.

🤖 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/release.yml around lines 51 - 60, Update the “Version must
not already be published” step to provide NODE_AUTH_TOKEN to the npm view
lookup, distinguish a confirmed not-found result from authentication, registry,
or network errors, and fail the workflow for every result except confirmed
absence; retain the existing error and success messages for published and
unpublished versions.

Source: MCP tools

Comment on lines +65 to +78
- name: Publish
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Cut the GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
gh release create "$GITHUB_REF_NAME" \
--title "$GITHUB_REF_NAME" \
--generate-notes \
--verify-tag

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"== workflow excerpt =="if [ -f .github/workflows/release.yml ];then
sed -n '1,120p' .github/workflows/release.yml | cat -n
elseecho"missing .github/workflows/release.yml"fiecho"== release workflow search =="
rg -n "npm publish|gh release create|verify-tag|package.json|RELEASE|GITHUB_REF_NAME|GH_TOKEN|NPM_TOKEN|version" .github/workflows/release.yml .github/workflows 2>/dev/null ||trueecho"== package manifests =="forfin package.json pnpm-lock.yaml package-lock.json yarn.lock;doif [ -f"$f" ];thenecho"--- $f ---"
rg -n '"version"|"name"|engines|private|publishConfig|workspaces|npm'"$f" -m 50 ||truefidone

Repository: vib795/agent-memory

Length of output: 7244


Make npm publication and GitHub Release creation recoverable.

The workflow writes npm and GitHub independently. If npm publish succeeds but gh release create fails, rerunning the workflow skips the Release step after npm view "$name@$ver" succeeds. Add an idempotent recovery path that lets a rerun publish-only failures be retried and skip a confirmed existing package version when restoring only the missing GitHub Release.

🤖 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/release.yml around lines 65 - 78, Make the Publish and Cut
the GitHub Release steps independently idempotent: retry npm publication when
the package version is absent, but skip it only after confirming that exact
version already exists; separately check whether the GitHub release for
GITHUB_REF_NAME exists and create it when missing, so reruns can restore only
the release without being blocked by npm view.

@vib795vib795 mentioned this pull request Aug 8, 2026
vib795 added a commit that referenced this pull request Aug 8, 2026
No functional change. This exercises the tag-triggered publish path added in #5
end to end: matrix gate, version guards, provenance signing, GitHub Release.
A release pipeline that has never run is not a release pipeline, and a patch
with nothing in it is the cheapest way to find that out.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@vib795
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
ci: publish to npm on tag push by vib795 · Pull Request #5 · vib795/agent-memory · GitHub
Skip to content

ci: publish to npm on tag push - #5

Merged
vib795 merged 1 commit into
mainfrom
ci/release-on-tag
Aug 8, 2026
Merged

ci: publish to npm on tag push#5
vib795 merged 1 commit into
mainfrom
ci/release-on-tag

Conversation

@vib795

@vib795vib795 commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Publishing 0.1.0 cost a 2FA recovery code. The codes are finite and single-use, which is a poor place for a release process to live.

What a v* tag now does

  1. Runs the full test matrix (test.yml gained a workflow_call trigger so this reuses it rather than duplicating it)
  2. Asserts the tag matches package.json version — a mismatch means someone tagged the wrong commit or skipped the bump, and npm never gives a version number back
  3. Asserts the version is not already published — turns a post-upload 403 into a one-line failure
  4. Publishes with --provenance, which ties the tarball to the commit and workflow run and shows the badge on npm
  5. Cuts the GitHub Release with --verify-tag

The matrix runs here rather than trusting the run on main, because a tag can point at any commit — including one main never saw.

Before this can work

Add an NPM_TOKEN repository secret: a granular access token scoped to @vib795, read+write, with bypass 2FA enabled. Without it the publish step fails on auth.

Not retroactive

v0.1.0 was tagged and published by hand before this existed, so this takes effect from the next tag.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Improved the release process with automated package publishing and GitHub Release creation.
    • Added version validation to help prevent publishing mismatched or duplicate releases.
    • Releases now include provenance information for improved package authenticity and traceability.
    • Automated testing runs as part of the release process to help ensure published versions meet quality standards.

Releases were blocked on a human with a 2FA recovery code, which is a bad
place for a release process to live: the codes are finite, single-use, and
spending one is not something you want between a fix and its users.
A v* tag now runs the full test matrix, asserts the tag agrees with
package.json, asserts the version is not already on the registry, publishes
with provenance, and cuts the GitHub Release.
The matrix runs again here rather than trusting the run on main, because a
tag can point at any commit, including one main never saw.
Requires the NPM_TOKEN repository secret: a granular access token scoped to
@vib795 with 2FA bypass enabled.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The workflows add reusable test execution and a tag-triggered release process. The release process validates the tag and package version, prevents duplicate npm publication, publishes with provenance, and creates a GitHub Release.

Changes

Release Pipeline

Layer / File(s)Summary
Reusable test workflow
.github/workflows/test.yml
The test workflow now supports workflow_call in addition to its existing triggers.
Tagged package release
.github/workflows/release.yml
The new workflow runs tests, validates version data, publishes the package to npm, and creates a GitHub Release for v* tags.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
participant GitHubTag
participant TestWorkflow
participant PublishJob
participant NpmRegistry
participant GitHubRelease
GitHubTag->>TestWorkflow: invoke reusable tests
TestWorkflow-->>PublishJob: return test result
PublishJob->>PublishJob: validate tag and package version
PublishJob->>NpmRegistry: publish package with provenance
PublishJob->>GitHubRelease: create release with generated notes
Loading

Poem

I’m a rabbit with a tagged release,
Tests hop first, then checks bring peace.
npm gets a provenance bow,
GitHub notes are written now.
One clean carrot-sized deploy!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the main change: automated npm publishing triggered by tag pushes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/release-on-tag

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@vib795
vib795 merged commit 8a1107c into mainAug 8, 2026
9 of 10 checks passed
@vib795
vib795 deleted the ci/release-on-tag branch August 8, 2026 00:24

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 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/release.yml:
- Around line 65-78: Make the Publish and Cut the GitHub Release steps
independently idempotent: retry npm publication when the package version is
absent, but skip it only after confirming that exact version already exists;
separately check whether the GitHub release for GITHUB_REF_NAME exists and
create it when missing, so reruns can restore only the release without being
blocked by npm view.
- Line 27: Update the actions/checkout@v4 step in the publish job to set
persist-credentials to false, while preserving the explicit GH_TOKEN used by gh
release create.
- Around line 51-60: Update the “Version must not already be published” step to
provide NODE_AUTH_TOKEN to the npm view lookup, distinguish a confirmed
not-found result from authentication, registry, or network errors, and fail the
workflow for every result except confirmed absence; retain the existing error
and success messages for published and unpublished versions.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d4443e0f-9b1a-49ab-b76c-3b1fc0d657e4

📥 Commits

Reviewing files that changed from the base of the PR and between 01dd384 and 07cb679.

📒 Files selected for processing (2)
  • .github/workflows/release.yml
  • .github/workflows/test.yml

contents: write # cut the GitHub Release
id-token: write # sign the npm provenance attestation
steps:
- uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"== workflow excerpt =="
sed -n '1,110p' .github/workflows/release.yml
echoecho"== checkout occurrences =="
rg -n "actions/checkout|persist-credentials|permissions:|contents:" .github/workflows/release.yml

Repository: vib795/agent-memory

Length of output: 3213


🌐 Web query:

actions/checkout v4 action.yml persist-credentials default true

💡 Result:

In the actions/checkout v4 action, the persist-credentials input has a default value of true [1][2][3]. When this setting is enabled (the default), the action configures the repository's local git configuration to include the authentication token or SSH key used for the checkout [2][4]. This allows subsequent git commands executed within the runner to be authenticated automatically [2][4]. The action removes this token during the post-job cleanup phase [2][4]. If you wish to prevent the action from adding these credentials to the local git configuration, you must explicitly set persist-credentials to false in your workflow file [2][4][5]: - uses: actions/checkout@v4 with: persist-credentials: false Disabling this setting is often recommended if you are concerned about credential exposure (for example, if you archive and upload the repository as a workflow artifact) [5].

Citations:


Disable checkout credential persistence in the publish job.

actions/checkout@v4 leaves persist-credentials enabled by default, so the write-capable checkout token remains available to later commands in this job. Set persist-credentials: false; gh release create already receives a token explicitly through GH_TOKEN.

Suggested change
 - uses: actions/checkout@v4
+ with:+ persist-credentials: false
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.29.0)

[warning] 27-27: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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/release.yml at line 27, Update the actions/checkout@v4
step in the publish job to set persist-credentials to false, while preserving
the explicit GH_TOKEN used by gh release create.

Sources: MCP tools, Linters/SAST tools

Comment on lines +51 to +60
- name: Version must not already be published
run: |
set -euo pipefail
name=$(node -p "require('./package.json').name")
ver=$(node -p "require('./package.json').version")
if npm view "$name@$ver" version >/dev/null 2>&1; then
echo "::error::$name@$ver is already on the registry"
exit 1
fi
echo "$name@$ver is unpublished; proceeding"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"## workflow excerpt"
nl -ba .github/workflows/release.yml | sed -n '1,120p'echoecho"## node/npm usage in workflow"
grep -nE 'NODE_AUTH_TOKEN|npm|setup-node|package-lock.json|package\.json|registry' .github/workflows/release.yml ||trueechoecho"## package registry/auth hints"
sed -n '1,220p' package.json ||true
[ -f package-lock.json ] && sed -n '1,80p' package-lock.json ||true

Repository: vib795/agent-memory

Length of output: 217


🌐 Web query:

npm view command exit code 404 response npm 404 error exit code documentation

💡 Result:

When the npm CLI encounters an E404 error—most commonly when a requested package or version cannot be found in the registry—it typically exits with a non-zero exit code (specifically 1) [1][2][3]. Key details regarding npm view and E404 behavior include: 1. Exit Code: When npm view fails to find a package or a specific version, it reports an E404 error and terminates with a non-zero exit code (typically 1) [1][2][3]. This ensures that automated scripts and CI/CD pipelines can detect the failure [1][2]. 2. Error Context: The E404 error is explicitly logged to stderr, detailing that the requested resource is not available in the registry [2][3][4]. 3. Notable Edge Cases: There have been documented instances where npm commands may exit with code 0 despite a failure to find specific tags (such as npm view package@latest when the tag itself is missing), which has been a subject of bug reports [1]. 4. General Error Handling: The npm CLI determines exit codes based on error codes (like E404) or defaults to 1 for general failures [5]. If you are encountering this in an automated environment, you should rely on the non-zero exit code to signal that the lookup was unsuccessful, rather than relying solely on the presence or absence of output to stdout [1][2].

Citations:


🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"## release workflow excerpt"
awk '{printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml | sed -n '1,130p'echoecho"## auth/npm related lines"
awk '{if (/NODE_AUTH_TOKEN|npm|setup-node|registry|package-lock|package\.json/) printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml
echoecho"## package registry/auth hints"
awk '{printf "%6d\t%s\n", NR, $0}' package.json | sed -n '1,220p'
[ -f package-lock.json ] && awk '{printf "%6d\t%s\n", NR, $0}' package-lock.json | sed -n '1,80p'

Repository: vib795/agent-memory

Length of output: 6378


🌐 Web query:

GitHub Actions setup-node NODE_AUTH_TOKEN npm view npm publish publishConfig registry-url scoped package

💡 Result:

To publish a scoped package to a specific registry using GitHub Actions and the setup-node action, you must correctly configure both the authentication environment and the registry mapping [1][2]. The setup-node action automates the creation of an.npmrc file that configures your registry and authentication [1][3]. Workflow Configuration 1. Use the setup-node action to define the target registry and the package scope [4][1]. 2. Provide an authentication token via the NODE_AUTH_TOKEN environment variable [1]. Example: - uses: actions/setup-node@v4 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org/' # Or your private registry URL scope: '@your-scope' - run: npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} Key Components - registry-url: This input instructs setup-node to write the registry URL to a project-level.npmrc file [4][3]. - scope: When provided, setup-node configures the.npmrc to associate this scope with the specified registry [3][5]. If not provided, it may default to the repository owner when using the GitHub Packages registry [4][2]. - NODE_AUTH_TOKEN: This environment variable is required by npm to authenticate requests [1]. The setup-node action automatically injects this token into the generated.npmrc [1][3]. Handling publishConfig If you need to ensure a package is always published to a specific registry regardless of local or global.npmrc settings, you can define it in your package.json [6]: { "publishConfig": { "@your-scope:registry": "https://registry.npmjs.org/" } } This configuration is particularly useful for scoped packages to avoid conflicts with default registry settings [7][8]. When using this method, ensure your registry credentials are still properly configured in the environment (e.g., via setup-node) [1]. Important Note: GitHub Packages (GPR) exclusively supports scoped packages (e.g., @owner/package-name) [5][9]. Ensure your package name in package.json adheres to this format if you are targeting GPR [5].

Citations:


🌐 Web query:

npm cli npm view private package 404 E404 non-zero exit code npm 404

💡 Result:

When you receive an E404 error with a non-zero exit code while running npm view on a private package, it generally indicates that the npm CLI could not find the package manifest at the specified or default registry [1][2]. This error typically occurs for the following reasons: 1. Lack of Authentication: If the package is private (e.g., restricted access) and you are not authenticated, the registry will return a 404 (Not Found) instead of a 403 (Forbidden) to prevent leaking the existence of private packages to unauthenticated users [3]. Ensure you are logged in (npm login) or have the correct authentication token (e.g., NODE_AUTH_TOKEN) configured for your environment [3]. 2. Incorrect Registry Configuration: npm might be looking at the public registry (registry.npmjs.org) instead of your private registry [4][5]. Check your.npmrc file to ensure your scope is correctly mapped to the intended private registry URL (e.g., @mycompany:registry=https://npm.pkg.github.com/) [5][2]. 3. Workspace/Bulk Operations: If you are running npm view with workspace flags (-ws), the command may fail and exit if it encounters a 404 for any individual workspace, including private ones that have not yet been published or are inaccessible [1][6]. Recent versions of the npm CLI have introduced improvements to handle these workspace-related 404 errors more gracefully [1]. 4. Package or Tag Absence: The package itself, or the specific version/tag you are querying, may genuinely not exist in the targeted registry [7][2]. To debug, you can run the command with increased verbosity to see exactly which registry and URL the CLI is attempting to access: npm view -dddd [5][2] This will help you verify if the CLI is resolving to the registry you expect and if the authentication headers are being included in the request [5][2].

Citations:


🌐 Web query:

npm view npm view package version output empty stderr exit code 0

💡 Result:

When you run the npm view command and it returns an empty output with an exit code of 0, it typically indicates that the command successfully executed but could not find the specific package, version, or tag you requested [1][2][3]. Historical context and behavior: - Legacy Behavior: In older versions of the npm CLI, npm view would frequently return an empty string and a success exit code (0) when a requested version or tag did not exist in the registry [4][5][6]. This was often used by automated scripts to verify if a package was missing [4][5]. - Recent Changes: Newer versions of the npm CLI have been updated to treat these cases as errors, generally returning an E404 error code and a non-zero exit code [4][7][6]. If you are encountering an empty output with a zero exit code, you are likely using an older version of npm or interacting with a specific registry configuration that causes this behavior [2][3][6]. - Underlying Cause: The primary cause is often that the package does not have a version tagged as "latest" (which is the default tag if none is specified), or the specific version/tag requested does not exist on the target registry [1][2][4]. Recommendations: - Check your npm version: Run npm -v to see if you are using an older version. Upgrading may provide more consistent error reporting [6]. - Verify the registry: If you are using a private registry (like Nexus or GitHub Packages), ensure it is configured correctly, as some third-party registries may not handle metadata requests in the exact way the npm CLI expects [1][2][3]. - Handle empty output in scripts: If you must rely on existing behavior, ensure your scripts are designed to handle both empty output and potential error states, especially as newer versions of npm are moving toward stricter E404 reporting [4][5].

Citations:


Fail closed when checking npm publication state.

The current check treats every failed npm view result as “unpublished”, including auth failures, registry errors, and network failures. NODE_AUTH_TOKEN is only provided during npm publish, so npm view runs as an anonymous public lookup and cannot distinguish an unpublished version from a private package or transient failure. Provide the token on this step and abort unless the lookup is confirmed absent.

🤖 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/release.yml around lines 51 - 60, Update the “Version must
not already be published” step to provide NODE_AUTH_TOKEN to the npm view
lookup, distinguish a confirmed not-found result from authentication, registry,
or network errors, and fail the workflow for every result except confirmed
absence; retain the existing error and success messages for published and
unpublished versions.

Source: MCP tools

Comment on lines +65 to +78
- name: Publish
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Cut the GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
gh release create "$GITHUB_REF_NAME" \
--title "$GITHUB_REF_NAME" \
--generate-notes \
--verify-tag

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"== workflow excerpt =="if [ -f .github/workflows/release.yml ];then
sed -n '1,120p' .github/workflows/release.yml | cat -n
elseecho"missing .github/workflows/release.yml"fiecho"== release workflow search =="
rg -n "npm publish|gh release create|verify-tag|package.json|RELEASE|GITHUB_REF_NAME|GH_TOKEN|NPM_TOKEN|version" .github/workflows/release.yml .github/workflows 2>/dev/null ||trueecho"== package manifests =="forfin package.json pnpm-lock.yaml package-lock.json yarn.lock;doif [ -f"$f" ];thenecho"--- $f ---"
rg -n '"version"|"name"|engines|private|publishConfig|workspaces|npm'"$f" -m 50 ||truefidone

Repository: vib795/agent-memory

Length of output: 7244


Make npm publication and GitHub Release creation recoverable.

The workflow writes npm and GitHub independently. If npm publish succeeds but gh release create fails, rerunning the workflow skips the Release step after npm view "$name@$ver" succeeds. Add an idempotent recovery path that lets a rerun publish-only failures be retried and skip a confirmed existing package version when restoring only the missing GitHub Release.

🤖 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/release.yml around lines 65 - 78, Make the Publish and Cut
the GitHub Release steps independently idempotent: retry npm publication when
the package version is absent, but skip it only after confirming that exact
version already exists; separately check whether the GitHub release for
GITHUB_REF_NAME exists and create it when missing, so reruns can restore only
the release without being blocked by npm view.

@vib795vib795 mentioned this pull request Aug 8, 2026
vib795 added a commit that referenced this pull request Aug 8, 2026
No functional change. This exercises the tag-triggered publish path added in #5
end to end: matrix gate, version guards, provenance signing, GitHub Release.
A release pipeline that has never run is not a release pipeline, and a patch
with nothing in it is the cheapest way to find that out.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@vib795
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' ci: publish to npm on tag push by vib795 · Pull Request #5 · vib795/agent-memory · GitHub
Skip to content

ci: publish to npm on tag push - #5

Merged
vib795 merged 1 commit into
mainfrom
ci/release-on-tag
Aug 8, 2026
Merged

ci: publish to npm on tag push#5
vib795 merged 1 commit into
mainfrom
ci/release-on-tag

Conversation

@vib795

@vib795vib795 commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Publishing 0.1.0 cost a 2FA recovery code. The codes are finite and single-use, which is a poor place for a release process to live.

What a v* tag now does

  1. Runs the full test matrix (test.yml gained a workflow_call trigger so this reuses it rather than duplicating it)
  2. Asserts the tag matches package.json version — a mismatch means someone tagged the wrong commit or skipped the bump, and npm never gives a version number back
  3. Asserts the version is not already published — turns a post-upload 403 into a one-line failure
  4. Publishes with --provenance, which ties the tarball to the commit and workflow run and shows the badge on npm
  5. Cuts the GitHub Release with --verify-tag

The matrix runs here rather than trusting the run on main, because a tag can point at any commit — including one main never saw.

Before this can work

Add an NPM_TOKEN repository secret: a granular access token scoped to @vib795, read+write, with bypass 2FA enabled. Without it the publish step fails on auth.

Not retroactive

v0.1.0 was tagged and published by hand before this existed, so this takes effect from the next tag.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Improved the release process with automated package publishing and GitHub Release creation.
    • Added version validation to help prevent publishing mismatched or duplicate releases.
    • Releases now include provenance information for improved package authenticity and traceability.
    • Automated testing runs as part of the release process to help ensure published versions meet quality standards.

Releases were blocked on a human with a 2FA recovery code, which is a bad
place for a release process to live: the codes are finite, single-use, and
spending one is not something you want between a fix and its users.
A v* tag now runs the full test matrix, asserts the tag agrees with
package.json, asserts the version is not already on the registry, publishes
with provenance, and cuts the GitHub Release.
The matrix runs again here rather than trusting the run on main, because a
tag can point at any commit, including one main never saw.
Requires the NPM_TOKEN repository secret: a granular access token scoped to
@vib795 with 2FA bypass enabled.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The workflows add reusable test execution and a tag-triggered release process. The release process validates the tag and package version, prevents duplicate npm publication, publishes with provenance, and creates a GitHub Release.

Changes

Release Pipeline

Layer / File(s)Summary
Reusable test workflow
.github/workflows/test.yml
The test workflow now supports workflow_call in addition to its existing triggers.
Tagged package release
.github/workflows/release.yml
The new workflow runs tests, validates version data, publishes the package to npm, and creates a GitHub Release for v* tags.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
participant GitHubTag
participant TestWorkflow
participant PublishJob
participant NpmRegistry
participant GitHubRelease
GitHubTag->>TestWorkflow: invoke reusable tests
TestWorkflow-->>PublishJob: return test result
PublishJob->>PublishJob: validate tag and package version
PublishJob->>NpmRegistry: publish package with provenance
PublishJob->>GitHubRelease: create release with generated notes
Loading

Poem

I’m a rabbit with a tagged release,
Tests hop first, then checks bring peace.
npm gets a provenance bow,
GitHub notes are written now.
One clean carrot-sized deploy!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the main change: automated npm publishing triggered by tag pushes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/release-on-tag

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@vib795
vib795 merged commit 8a1107c into mainAug 8, 2026
9 of 10 checks passed
@vib795
vib795 deleted the ci/release-on-tag branch August 8, 2026 00:24

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 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/release.yml:
- Around line 65-78: Make the Publish and Cut the GitHub Release steps
independently idempotent: retry npm publication when the package version is
absent, but skip it only after confirming that exact version already exists;
separately check whether the GitHub release for GITHUB_REF_NAME exists and
create it when missing, so reruns can restore only the release without being
blocked by npm view.
- Line 27: Update the actions/checkout@v4 step in the publish job to set
persist-credentials to false, while preserving the explicit GH_TOKEN used by gh
release create.
- Around line 51-60: Update the “Version must not already be published” step to
provide NODE_AUTH_TOKEN to the npm view lookup, distinguish a confirmed
not-found result from authentication, registry, or network errors, and fail the
workflow for every result except confirmed absence; retain the existing error
and success messages for published and unpublished versions.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d4443e0f-9b1a-49ab-b76c-3b1fc0d657e4

📥 Commits

Reviewing files that changed from the base of the PR and between 01dd384 and 07cb679.

📒 Files selected for processing (2)
  • .github/workflows/release.yml
  • .github/workflows/test.yml

contents: write # cut the GitHub Release
id-token: write # sign the npm provenance attestation
steps:
- uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"== workflow excerpt =="
sed -n '1,110p' .github/workflows/release.yml
echoecho"== checkout occurrences =="
rg -n "actions/checkout|persist-credentials|permissions:|contents:" .github/workflows/release.yml

Repository: vib795/agent-memory

Length of output: 3213


🌐 Web query:

actions/checkout v4 action.yml persist-credentials default true

💡 Result:

In the actions/checkout v4 action, the persist-credentials input has a default value of true [1][2][3]. When this setting is enabled (the default), the action configures the repository's local git configuration to include the authentication token or SSH key used for the checkout [2][4]. This allows subsequent git commands executed within the runner to be authenticated automatically [2][4]. The action removes this token during the post-job cleanup phase [2][4]. If you wish to prevent the action from adding these credentials to the local git configuration, you must explicitly set persist-credentials to false in your workflow file [2][4][5]: - uses: actions/checkout@v4 with: persist-credentials: false Disabling this setting is often recommended if you are concerned about credential exposure (for example, if you archive and upload the repository as a workflow artifact) [5].

Citations:


Disable checkout credential persistence in the publish job.

actions/checkout@v4 leaves persist-credentials enabled by default, so the write-capable checkout token remains available to later commands in this job. Set persist-credentials: false; gh release create already receives a token explicitly through GH_TOKEN.

Suggested change
 - uses: actions/checkout@v4
+ with:+ persist-credentials: false
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.29.0)

[warning] 27-27: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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/release.yml at line 27, Update the actions/checkout@v4
step in the publish job to set persist-credentials to false, while preserving
the explicit GH_TOKEN used by gh release create.

Sources: MCP tools, Linters/SAST tools

Comment on lines +51 to +60
- name: Version must not already be published
run: |
set -euo pipefail
name=$(node -p "require('./package.json').name")
ver=$(node -p "require('./package.json').version")
if npm view "$name@$ver" version >/dev/null 2>&1; then
echo "::error::$name@$ver is already on the registry"
exit 1
fi
echo "$name@$ver is unpublished; proceeding"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"## workflow excerpt"
nl -ba .github/workflows/release.yml | sed -n '1,120p'echoecho"## node/npm usage in workflow"
grep -nE 'NODE_AUTH_TOKEN|npm|setup-node|package-lock.json|package\.json|registry' .github/workflows/release.yml ||trueechoecho"## package registry/auth hints"
sed -n '1,220p' package.json ||true
[ -f package-lock.json ] && sed -n '1,80p' package-lock.json ||true

Repository: vib795/agent-memory

Length of output: 217


🌐 Web query:

npm view command exit code 404 response npm 404 error exit code documentation

💡 Result:

When the npm CLI encounters an E404 error—most commonly when a requested package or version cannot be found in the registry—it typically exits with a non-zero exit code (specifically 1) [1][2][3]. Key details regarding npm view and E404 behavior include: 1. Exit Code: When npm view fails to find a package or a specific version, it reports an E404 error and terminates with a non-zero exit code (typically 1) [1][2][3]. This ensures that automated scripts and CI/CD pipelines can detect the failure [1][2]. 2. Error Context: The E404 error is explicitly logged to stderr, detailing that the requested resource is not available in the registry [2][3][4]. 3. Notable Edge Cases: There have been documented instances where npm commands may exit with code 0 despite a failure to find specific tags (such as npm view package@latest when the tag itself is missing), which has been a subject of bug reports [1]. 4. General Error Handling: The npm CLI determines exit codes based on error codes (like E404) or defaults to 1 for general failures [5]. If you are encountering this in an automated environment, you should rely on the non-zero exit code to signal that the lookup was unsuccessful, rather than relying solely on the presence or absence of output to stdout [1][2].

Citations:


🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"## release workflow excerpt"
awk '{printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml | sed -n '1,130p'echoecho"## auth/npm related lines"
awk '{if (/NODE_AUTH_TOKEN|npm|setup-node|registry|package-lock|package\.json/) printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml
echoecho"## package registry/auth hints"
awk '{printf "%6d\t%s\n", NR, $0}' package.json | sed -n '1,220p'
[ -f package-lock.json ] && awk '{printf "%6d\t%s\n", NR, $0}' package-lock.json | sed -n '1,80p'

Repository: vib795/agent-memory

Length of output: 6378


🌐 Web query:

GitHub Actions setup-node NODE_AUTH_TOKEN npm view npm publish publishConfig registry-url scoped package

💡 Result:

To publish a scoped package to a specific registry using GitHub Actions and the setup-node action, you must correctly configure both the authentication environment and the registry mapping [1][2]. The setup-node action automates the creation of an.npmrc file that configures your registry and authentication [1][3]. Workflow Configuration 1. Use the setup-node action to define the target registry and the package scope [4][1]. 2. Provide an authentication token via the NODE_AUTH_TOKEN environment variable [1]. Example: - uses: actions/setup-node@v4 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org/' # Or your private registry URL scope: '@your-scope' - run: npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} Key Components - registry-url: This input instructs setup-node to write the registry URL to a project-level.npmrc file [4][3]. - scope: When provided, setup-node configures the.npmrc to associate this scope with the specified registry [3][5]. If not provided, it may default to the repository owner when using the GitHub Packages registry [4][2]. - NODE_AUTH_TOKEN: This environment variable is required by npm to authenticate requests [1]. The setup-node action automatically injects this token into the generated.npmrc [1][3]. Handling publishConfig If you need to ensure a package is always published to a specific registry regardless of local or global.npmrc settings, you can define it in your package.json [6]: { "publishConfig": { "@your-scope:registry": "https://registry.npmjs.org/" } } This configuration is particularly useful for scoped packages to avoid conflicts with default registry settings [7][8]. When using this method, ensure your registry credentials are still properly configured in the environment (e.g., via setup-node) [1]. Important Note: GitHub Packages (GPR) exclusively supports scoped packages (e.g., @owner/package-name) [5][9]. Ensure your package name in package.json adheres to this format if you are targeting GPR [5].

Citations:


🌐 Web query:

npm cli npm view private package 404 E404 non-zero exit code npm 404

💡 Result:

When you receive an E404 error with a non-zero exit code while running npm view on a private package, it generally indicates that the npm CLI could not find the package manifest at the specified or default registry [1][2]. This error typically occurs for the following reasons: 1. Lack of Authentication: If the package is private (e.g., restricted access) and you are not authenticated, the registry will return a 404 (Not Found) instead of a 403 (Forbidden) to prevent leaking the existence of private packages to unauthenticated users [3]. Ensure you are logged in (npm login) or have the correct authentication token (e.g., NODE_AUTH_TOKEN) configured for your environment [3]. 2. Incorrect Registry Configuration: npm might be looking at the public registry (registry.npmjs.org) instead of your private registry [4][5]. Check your.npmrc file to ensure your scope is correctly mapped to the intended private registry URL (e.g., @mycompany:registry=https://npm.pkg.github.com/) [5][2]. 3. Workspace/Bulk Operations: If you are running npm view with workspace flags (-ws), the command may fail and exit if it encounters a 404 for any individual workspace, including private ones that have not yet been published or are inaccessible [1][6]. Recent versions of the npm CLI have introduced improvements to handle these workspace-related 404 errors more gracefully [1]. 4. Package or Tag Absence: The package itself, or the specific version/tag you are querying, may genuinely not exist in the targeted registry [7][2]. To debug, you can run the command with increased verbosity to see exactly which registry and URL the CLI is attempting to access: npm view -dddd [5][2] This will help you verify if the CLI is resolving to the registry you expect and if the authentication headers are being included in the request [5][2].

Citations:


🌐 Web query:

npm view npm view package version output empty stderr exit code 0

💡 Result:

When you run the npm view command and it returns an empty output with an exit code of 0, it typically indicates that the command successfully executed but could not find the specific package, version, or tag you requested [1][2][3]. Historical context and behavior: - Legacy Behavior: In older versions of the npm CLI, npm view would frequently return an empty string and a success exit code (0) when a requested version or tag did not exist in the registry [4][5][6]. This was often used by automated scripts to verify if a package was missing [4][5]. - Recent Changes: Newer versions of the npm CLI have been updated to treat these cases as errors, generally returning an E404 error code and a non-zero exit code [4][7][6]. If you are encountering an empty output with a zero exit code, you are likely using an older version of npm or interacting with a specific registry configuration that causes this behavior [2][3][6]. - Underlying Cause: The primary cause is often that the package does not have a version tagged as "latest" (which is the default tag if none is specified), or the specific version/tag requested does not exist on the target registry [1][2][4]. Recommendations: - Check your npm version: Run npm -v to see if you are using an older version. Upgrading may provide more consistent error reporting [6]. - Verify the registry: If you are using a private registry (like Nexus or GitHub Packages), ensure it is configured correctly, as some third-party registries may not handle metadata requests in the exact way the npm CLI expects [1][2][3]. - Handle empty output in scripts: If you must rely on existing behavior, ensure your scripts are designed to handle both empty output and potential error states, especially as newer versions of npm are moving toward stricter E404 reporting [4][5].

Citations:


Fail closed when checking npm publication state.

The current check treats every failed npm view result as “unpublished”, including auth failures, registry errors, and network failures. NODE_AUTH_TOKEN is only provided during npm publish, so npm view runs as an anonymous public lookup and cannot distinguish an unpublished version from a private package or transient failure. Provide the token on this step and abort unless the lookup is confirmed absent.

🤖 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/release.yml around lines 51 - 60, Update the “Version must
not already be published” step to provide NODE_AUTH_TOKEN to the npm view
lookup, distinguish a confirmed not-found result from authentication, registry,
or network errors, and fail the workflow for every result except confirmed
absence; retain the existing error and success messages for published and
unpublished versions.

Source: MCP tools

Comment on lines +65 to +78
- name: Publish
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Cut the GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
gh release create "$GITHUB_REF_NAME" \
--title "$GITHUB_REF_NAME" \
--generate-notes \
--verify-tag

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"== workflow excerpt =="if [ -f .github/workflows/release.yml ];then
sed -n '1,120p' .github/workflows/release.yml | cat -n
elseecho"missing .github/workflows/release.yml"fiecho"== release workflow search =="
rg -n "npm publish|gh release create|verify-tag|package.json|RELEASE|GITHUB_REF_NAME|GH_TOKEN|NPM_TOKEN|version" .github/workflows/release.yml .github/workflows 2>/dev/null ||trueecho"== package manifests =="forfin package.json pnpm-lock.yaml package-lock.json yarn.lock;doif [ -f"$f" ];thenecho"--- $f ---"
rg -n '"version"|"name"|engines|private|publishConfig|workspaces|npm'"$f" -m 50 ||truefidone

Repository: vib795/agent-memory

Length of output: 7244


Make npm publication and GitHub Release creation recoverable.

The workflow writes npm and GitHub independently. If npm publish succeeds but gh release create fails, rerunning the workflow skips the Release step after npm view "$name@$ver" succeeds. Add an idempotent recovery path that lets a rerun publish-only failures be retried and skip a confirmed existing package version when restoring only the missing GitHub Release.

🤖 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/release.yml around lines 65 - 78, Make the Publish and Cut
the GitHub Release steps independently idempotent: retry npm publication when
the package version is absent, but skip it only after confirming that exact
version already exists; separately check whether the GitHub release for
GITHUB_REF_NAME exists and create it when missing, so reruns can restore only
the release without being blocked by npm view.

@vib795vib795 mentioned this pull request Aug 8, 2026
vib795 added a commit that referenced this pull request Aug 8, 2026
No functional change. This exercises the tag-triggered publish path added in #5
end to end: matrix gate, version guards, provenance signing, GitHub Release.
A release pipeline that has never run is not a release pipeline, and a patch
with nothing in it is the cheapest way to find that out.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@vib795
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' ci: publish to npm on tag push by vib795 · Pull Request #5 · vib795/agent-memory · GitHub
Skip to content

ci: publish to npm on tag push - #5

Merged
vib795 merged 1 commit into
mainfrom
ci/release-on-tag
Aug 8, 2026
Merged

ci: publish to npm on tag push#5
vib795 merged 1 commit into
mainfrom
ci/release-on-tag

Conversation

@vib795

@vib795vib795 commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Publishing 0.1.0 cost a 2FA recovery code. The codes are finite and single-use, which is a poor place for a release process to live.

What a v* tag now does

  1. Runs the full test matrix (test.yml gained a workflow_call trigger so this reuses it rather than duplicating it)
  2. Asserts the tag matches package.json version — a mismatch means someone tagged the wrong commit or skipped the bump, and npm never gives a version number back
  3. Asserts the version is not already published — turns a post-upload 403 into a one-line failure
  4. Publishes with --provenance, which ties the tarball to the commit and workflow run and shows the badge on npm
  5. Cuts the GitHub Release with --verify-tag

The matrix runs here rather than trusting the run on main, because a tag can point at any commit — including one main never saw.

Before this can work

Add an NPM_TOKEN repository secret: a granular access token scoped to @vib795, read+write, with bypass 2FA enabled. Without it the publish step fails on auth.

Not retroactive

v0.1.0 was tagged and published by hand before this existed, so this takes effect from the next tag.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Improved the release process with automated package publishing and GitHub Release creation.
    • Added version validation to help prevent publishing mismatched or duplicate releases.
    • Releases now include provenance information for improved package authenticity and traceability.
    • Automated testing runs as part of the release process to help ensure published versions meet quality standards.

Releases were blocked on a human with a 2FA recovery code, which is a bad
place for a release process to live: the codes are finite, single-use, and
spending one is not something you want between a fix and its users.
A v* tag now runs the full test matrix, asserts the tag agrees with
package.json, asserts the version is not already on the registry, publishes
with provenance, and cuts the GitHub Release.
The matrix runs again here rather than trusting the run on main, because a
tag can point at any commit, including one main never saw.
Requires the NPM_TOKEN repository secret: a granular access token scoped to
@vib795 with 2FA bypass enabled.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The workflows add reusable test execution and a tag-triggered release process. The release process validates the tag and package version, prevents duplicate npm publication, publishes with provenance, and creates a GitHub Release.

Changes

Release Pipeline

Layer / File(s)Summary
Reusable test workflow
.github/workflows/test.yml
The test workflow now supports workflow_call in addition to its existing triggers.
Tagged package release
.github/workflows/release.yml
The new workflow runs tests, validates version data, publishes the package to npm, and creates a GitHub Release for v* tags.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
participant GitHubTag
participant TestWorkflow
participant PublishJob
participant NpmRegistry
participant GitHubRelease
GitHubTag->>TestWorkflow: invoke reusable tests
TestWorkflow-->>PublishJob: return test result
PublishJob->>PublishJob: validate tag and package version
PublishJob->>NpmRegistry: publish package with provenance
PublishJob->>GitHubRelease: create release with generated notes
Loading

Poem

I’m a rabbit with a tagged release,
Tests hop first, then checks bring peace.
npm gets a provenance bow,
GitHub notes are written now.
One clean carrot-sized deploy!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the main change: automated npm publishing triggered by tag pushes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/release-on-tag

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@vib795
vib795 merged commit 8a1107c into mainAug 8, 2026
9 of 10 checks passed
@vib795
vib795 deleted the ci/release-on-tag branch August 8, 2026 00:24

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 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/release.yml:
- Around line 65-78: Make the Publish and Cut the GitHub Release steps
independently idempotent: retry npm publication when the package version is
absent, but skip it only after confirming that exact version already exists;
separately check whether the GitHub release for GITHUB_REF_NAME exists and
create it when missing, so reruns can restore only the release without being
blocked by npm view.
- Line 27: Update the actions/checkout@v4 step in the publish job to set
persist-credentials to false, while preserving the explicit GH_TOKEN used by gh
release create.
- Around line 51-60: Update the “Version must not already be published” step to
provide NODE_AUTH_TOKEN to the npm view lookup, distinguish a confirmed
not-found result from authentication, registry, or network errors, and fail the
workflow for every result except confirmed absence; retain the existing error
and success messages for published and unpublished versions.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d4443e0f-9b1a-49ab-b76c-3b1fc0d657e4

📥 Commits

Reviewing files that changed from the base of the PR and between 01dd384 and 07cb679.

📒 Files selected for processing (2)
  • .github/workflows/release.yml
  • .github/workflows/test.yml

contents: write # cut the GitHub Release
id-token: write # sign the npm provenance attestation
steps:
- uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"== workflow excerpt =="
sed -n '1,110p' .github/workflows/release.yml
echoecho"== checkout occurrences =="
rg -n "actions/checkout|persist-credentials|permissions:|contents:" .github/workflows/release.yml

Repository: vib795/agent-memory

Length of output: 3213


🌐 Web query:

actions/checkout v4 action.yml persist-credentials default true

💡 Result:

In the actions/checkout v4 action, the persist-credentials input has a default value of true [1][2][3]. When this setting is enabled (the default), the action configures the repository's local git configuration to include the authentication token or SSH key used for the checkout [2][4]. This allows subsequent git commands executed within the runner to be authenticated automatically [2][4]. The action removes this token during the post-job cleanup phase [2][4]. If you wish to prevent the action from adding these credentials to the local git configuration, you must explicitly set persist-credentials to false in your workflow file [2][4][5]: - uses: actions/checkout@v4 with: persist-credentials: false Disabling this setting is often recommended if you are concerned about credential exposure (for example, if you archive and upload the repository as a workflow artifact) [5].

Citations:


Disable checkout credential persistence in the publish job.

actions/checkout@v4 leaves persist-credentials enabled by default, so the write-capable checkout token remains available to later commands in this job. Set persist-credentials: false; gh release create already receives a token explicitly through GH_TOKEN.

Suggested change
 - uses: actions/checkout@v4
+ with:+ persist-credentials: false
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.29.0)

[warning] 27-27: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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/release.yml at line 27, Update the actions/checkout@v4
step in the publish job to set persist-credentials to false, while preserving
the explicit GH_TOKEN used by gh release create.

Sources: MCP tools, Linters/SAST tools

Comment on lines +51 to +60
- name: Version must not already be published
run: |
set -euo pipefail
name=$(node -p "require('./package.json').name")
ver=$(node -p "require('./package.json').version")
if npm view "$name@$ver" version >/dev/null 2>&1; then
echo "::error::$name@$ver is already on the registry"
exit 1
fi
echo "$name@$ver is unpublished; proceeding"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"## workflow excerpt"
nl -ba .github/workflows/release.yml | sed -n '1,120p'echoecho"## node/npm usage in workflow"
grep -nE 'NODE_AUTH_TOKEN|npm|setup-node|package-lock.json|package\.json|registry' .github/workflows/release.yml ||trueechoecho"## package registry/auth hints"
sed -n '1,220p' package.json ||true
[ -f package-lock.json ] && sed -n '1,80p' package-lock.json ||true

Repository: vib795/agent-memory

Length of output: 217


🌐 Web query:

npm view command exit code 404 response npm 404 error exit code documentation

💡 Result:

When the npm CLI encounters an E404 error—most commonly when a requested package or version cannot be found in the registry—it typically exits with a non-zero exit code (specifically 1) [1][2][3]. Key details regarding npm view and E404 behavior include: 1. Exit Code: When npm view fails to find a package or a specific version, it reports an E404 error and terminates with a non-zero exit code (typically 1) [1][2][3]. This ensures that automated scripts and CI/CD pipelines can detect the failure [1][2]. 2. Error Context: The E404 error is explicitly logged to stderr, detailing that the requested resource is not available in the registry [2][3][4]. 3. Notable Edge Cases: There have been documented instances where npm commands may exit with code 0 despite a failure to find specific tags (such as npm view package@latest when the tag itself is missing), which has been a subject of bug reports [1]. 4. General Error Handling: The npm CLI determines exit codes based on error codes (like E404) or defaults to 1 for general failures [5]. If you are encountering this in an automated environment, you should rely on the non-zero exit code to signal that the lookup was unsuccessful, rather than relying solely on the presence or absence of output to stdout [1][2].

Citations:


🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"## release workflow excerpt"
awk '{printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml | sed -n '1,130p'echoecho"## auth/npm related lines"
awk '{if (/NODE_AUTH_TOKEN|npm|setup-node|registry|package-lock|package\.json/) printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml
echoecho"## package registry/auth hints"
awk '{printf "%6d\t%s\n", NR, $0}' package.json | sed -n '1,220p'
[ -f package-lock.json ] && awk '{printf "%6d\t%s\n", NR, $0}' package-lock.json | sed -n '1,80p'

Repository: vib795/agent-memory

Length of output: 6378


🌐 Web query:

GitHub Actions setup-node NODE_AUTH_TOKEN npm view npm publish publishConfig registry-url scoped package

💡 Result:

To publish a scoped package to a specific registry using GitHub Actions and the setup-node action, you must correctly configure both the authentication environment and the registry mapping [1][2]. The setup-node action automates the creation of an.npmrc file that configures your registry and authentication [1][3]. Workflow Configuration 1. Use the setup-node action to define the target registry and the package scope [4][1]. 2. Provide an authentication token via the NODE_AUTH_TOKEN environment variable [1]. Example: - uses: actions/setup-node@v4 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org/' # Or your private registry URL scope: '@your-scope' - run: npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} Key Components - registry-url: This input instructs setup-node to write the registry URL to a project-level.npmrc file [4][3]. - scope: When provided, setup-node configures the.npmrc to associate this scope with the specified registry [3][5]. If not provided, it may default to the repository owner when using the GitHub Packages registry [4][2]. - NODE_AUTH_TOKEN: This environment variable is required by npm to authenticate requests [1]. The setup-node action automatically injects this token into the generated.npmrc [1][3]. Handling publishConfig If you need to ensure a package is always published to a specific registry regardless of local or global.npmrc settings, you can define it in your package.json [6]: { "publishConfig": { "@your-scope:registry": "https://registry.npmjs.org/" } } This configuration is particularly useful for scoped packages to avoid conflicts with default registry settings [7][8]. When using this method, ensure your registry credentials are still properly configured in the environment (e.g., via setup-node) [1]. Important Note: GitHub Packages (GPR) exclusively supports scoped packages (e.g., @owner/package-name) [5][9]. Ensure your package name in package.json adheres to this format if you are targeting GPR [5].

Citations:


🌐 Web query:

npm cli npm view private package 404 E404 non-zero exit code npm 404

💡 Result:

When you receive an E404 error with a non-zero exit code while running npm view on a private package, it generally indicates that the npm CLI could not find the package manifest at the specified or default registry [1][2]. This error typically occurs for the following reasons: 1. Lack of Authentication: If the package is private (e.g., restricted access) and you are not authenticated, the registry will return a 404 (Not Found) instead of a 403 (Forbidden) to prevent leaking the existence of private packages to unauthenticated users [3]. Ensure you are logged in (npm login) or have the correct authentication token (e.g., NODE_AUTH_TOKEN) configured for your environment [3]. 2. Incorrect Registry Configuration: npm might be looking at the public registry (registry.npmjs.org) instead of your private registry [4][5]. Check your.npmrc file to ensure your scope is correctly mapped to the intended private registry URL (e.g., @mycompany:registry=https://npm.pkg.github.com/) [5][2]. 3. Workspace/Bulk Operations: If you are running npm view with workspace flags (-ws), the command may fail and exit if it encounters a 404 for any individual workspace, including private ones that have not yet been published or are inaccessible [1][6]. Recent versions of the npm CLI have introduced improvements to handle these workspace-related 404 errors more gracefully [1]. 4. Package or Tag Absence: The package itself, or the specific version/tag you are querying, may genuinely not exist in the targeted registry [7][2]. To debug, you can run the command with increased verbosity to see exactly which registry and URL the CLI is attempting to access: npm view -dddd [5][2] This will help you verify if the CLI is resolving to the registry you expect and if the authentication headers are being included in the request [5][2].

Citations:


🌐 Web query:

npm view npm view package version output empty stderr exit code 0

💡 Result:

When you run the npm view command and it returns an empty output with an exit code of 0, it typically indicates that the command successfully executed but could not find the specific package, version, or tag you requested [1][2][3]. Historical context and behavior: - Legacy Behavior: In older versions of the npm CLI, npm view would frequently return an empty string and a success exit code (0) when a requested version or tag did not exist in the registry [4][5][6]. This was often used by automated scripts to verify if a package was missing [4][5]. - Recent Changes: Newer versions of the npm CLI have been updated to treat these cases as errors, generally returning an E404 error code and a non-zero exit code [4][7][6]. If you are encountering an empty output with a zero exit code, you are likely using an older version of npm or interacting with a specific registry configuration that causes this behavior [2][3][6]. - Underlying Cause: The primary cause is often that the package does not have a version tagged as "latest" (which is the default tag if none is specified), or the specific version/tag requested does not exist on the target registry [1][2][4]. Recommendations: - Check your npm version: Run npm -v to see if you are using an older version. Upgrading may provide more consistent error reporting [6]. - Verify the registry: If you are using a private registry (like Nexus or GitHub Packages), ensure it is configured correctly, as some third-party registries may not handle metadata requests in the exact way the npm CLI expects [1][2][3]. - Handle empty output in scripts: If you must rely on existing behavior, ensure your scripts are designed to handle both empty output and potential error states, especially as newer versions of npm are moving toward stricter E404 reporting [4][5].

Citations:


Fail closed when checking npm publication state.

The current check treats every failed npm view result as “unpublished”, including auth failures, registry errors, and network failures. NODE_AUTH_TOKEN is only provided during npm publish, so npm view runs as an anonymous public lookup and cannot distinguish an unpublished version from a private package or transient failure. Provide the token on this step and abort unless the lookup is confirmed absent.

🤖 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/release.yml around lines 51 - 60, Update the “Version must
not already be published” step to provide NODE_AUTH_TOKEN to the npm view
lookup, distinguish a confirmed not-found result from authentication, registry,
or network errors, and fail the workflow for every result except confirmed
absence; retain the existing error and success messages for published and
unpublished versions.

Source: MCP tools

Comment on lines +65 to +78
- name: Publish
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Cut the GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
gh release create "$GITHUB_REF_NAME" \
--title "$GITHUB_REF_NAME" \
--generate-notes \
--verify-tag

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"== workflow excerpt =="if [ -f .github/workflows/release.yml ];then
sed -n '1,120p' .github/workflows/release.yml | cat -n
elseecho"missing .github/workflows/release.yml"fiecho"== release workflow search =="
rg -n "npm publish|gh release create|verify-tag|package.json|RELEASE|GITHUB_REF_NAME|GH_TOKEN|NPM_TOKEN|version" .github/workflows/release.yml .github/workflows 2>/dev/null ||trueecho"== package manifests =="forfin package.json pnpm-lock.yaml package-lock.json yarn.lock;doif [ -f"$f" ];thenecho"--- $f ---"
rg -n '"version"|"name"|engines|private|publishConfig|workspaces|npm'"$f" -m 50 ||truefidone

Repository: vib795/agent-memory

Length of output: 7244


Make npm publication and GitHub Release creation recoverable.

The workflow writes npm and GitHub independently. If npm publish succeeds but gh release create fails, rerunning the workflow skips the Release step after npm view "$name@$ver" succeeds. Add an idempotent recovery path that lets a rerun publish-only failures be retried and skip a confirmed existing package version when restoring only the missing GitHub Release.

🤖 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/release.yml around lines 65 - 78, Make the Publish and Cut
the GitHub Release steps independently idempotent: retry npm publication when
the package version is absent, but skip it only after confirming that exact
version already exists; separately check whether the GitHub release for
GITHUB_REF_NAME exists and create it when missing, so reruns can restore only
the release without being blocked by npm view.

@vib795vib795 mentioned this pull request Aug 8, 2026
vib795 added a commit that referenced this pull request Aug 8, 2026
No functional change. This exercises the tag-triggered publish path added in #5
end to end: matrix gate, version guards, provenance signing, GitHub Release.
A release pipeline that has never run is not a release pipeline, and a patch
with nothing in it is the cheapest way to find that out.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@vib795
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' ci: publish to npm on tag push by vib795 · Pull Request #5 · vib795/agent-memory · GitHub
Skip to content

ci: publish to npm on tag push - #5

Merged
vib795 merged 1 commit into
mainfrom
ci/release-on-tag
Aug 8, 2026
Merged

ci: publish to npm on tag push#5
vib795 merged 1 commit into
mainfrom
ci/release-on-tag

Conversation

@vib795

@vib795vib795 commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Publishing 0.1.0 cost a 2FA recovery code. The codes are finite and single-use, which is a poor place for a release process to live.

What a v* tag now does

  1. Runs the full test matrix (test.yml gained a workflow_call trigger so this reuses it rather than duplicating it)
  2. Asserts the tag matches package.json version — a mismatch means someone tagged the wrong commit or skipped the bump, and npm never gives a version number back
  3. Asserts the version is not already published — turns a post-upload 403 into a one-line failure
  4. Publishes with --provenance, which ties the tarball to the commit and workflow run and shows the badge on npm
  5. Cuts the GitHub Release with --verify-tag

The matrix runs here rather than trusting the run on main, because a tag can point at any commit — including one main never saw.

Before this can work

Add an NPM_TOKEN repository secret: a granular access token scoped to @vib795, read+write, with bypass 2FA enabled. Without it the publish step fails on auth.

Not retroactive

v0.1.0 was tagged and published by hand before this existed, so this takes effect from the next tag.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Improved the release process with automated package publishing and GitHub Release creation.
    • Added version validation to help prevent publishing mismatched or duplicate releases.
    • Releases now include provenance information for improved package authenticity and traceability.
    • Automated testing runs as part of the release process to help ensure published versions meet quality standards.

Releases were blocked on a human with a 2FA recovery code, which is a bad
place for a release process to live: the codes are finite, single-use, and
spending one is not something you want between a fix and its users.
A v* tag now runs the full test matrix, asserts the tag agrees with
package.json, asserts the version is not already on the registry, publishes
with provenance, and cuts the GitHub Release.
The matrix runs again here rather than trusting the run on main, because a
tag can point at any commit, including one main never saw.
Requires the NPM_TOKEN repository secret: a granular access token scoped to
@vib795 with 2FA bypass enabled.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The workflows add reusable test execution and a tag-triggered release process. The release process validates the tag and package version, prevents duplicate npm publication, publishes with provenance, and creates a GitHub Release.

Changes

Release Pipeline

Layer / File(s)Summary
Reusable test workflow
.github/workflows/test.yml
The test workflow now supports workflow_call in addition to its existing triggers.
Tagged package release
.github/workflows/release.yml
The new workflow runs tests, validates version data, publishes the package to npm, and creates a GitHub Release for v* tags.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
participant GitHubTag
participant TestWorkflow
participant PublishJob
participant NpmRegistry
participant GitHubRelease
GitHubTag->>TestWorkflow: invoke reusable tests
TestWorkflow-->>PublishJob: return test result
PublishJob->>PublishJob: validate tag and package version
PublishJob->>NpmRegistry: publish package with provenance
PublishJob->>GitHubRelease: create release with generated notes
Loading

Poem

I’m a rabbit with a tagged release,
Tests hop first, then checks bring peace.
npm gets a provenance bow,
GitHub notes are written now.
One clean carrot-sized deploy!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the main change: automated npm publishing triggered by tag pushes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/release-on-tag

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@vib795
vib795 merged commit 8a1107c into mainAug 8, 2026
9 of 10 checks passed
@vib795
vib795 deleted the ci/release-on-tag branch August 8, 2026 00:24

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 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/release.yml:
- Around line 65-78: Make the Publish and Cut the GitHub Release steps
independently idempotent: retry npm publication when the package version is
absent, but skip it only after confirming that exact version already exists;
separately check whether the GitHub release for GITHUB_REF_NAME exists and
create it when missing, so reruns can restore only the release without being
blocked by npm view.
- Line 27: Update the actions/checkout@v4 step in the publish job to set
persist-credentials to false, while preserving the explicit GH_TOKEN used by gh
release create.
- Around line 51-60: Update the “Version must not already be published” step to
provide NODE_AUTH_TOKEN to the npm view lookup, distinguish a confirmed
not-found result from authentication, registry, or network errors, and fail the
workflow for every result except confirmed absence; retain the existing error
and success messages for published and unpublished versions.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d4443e0f-9b1a-49ab-b76c-3b1fc0d657e4

📥 Commits

Reviewing files that changed from the base of the PR and between 01dd384 and 07cb679.

📒 Files selected for processing (2)
  • .github/workflows/release.yml
  • .github/workflows/test.yml

contents: write # cut the GitHub Release
id-token: write # sign the npm provenance attestation
steps:
- uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"== workflow excerpt =="
sed -n '1,110p' .github/workflows/release.yml
echoecho"== checkout occurrences =="
rg -n "actions/checkout|persist-credentials|permissions:|contents:" .github/workflows/release.yml

Repository: vib795/agent-memory

Length of output: 3213


🌐 Web query:

actions/checkout v4 action.yml persist-credentials default true

💡 Result:

In the actions/checkout v4 action, the persist-credentials input has a default value of true [1][2][3]. When this setting is enabled (the default), the action configures the repository's local git configuration to include the authentication token or SSH key used for the checkout [2][4]. This allows subsequent git commands executed within the runner to be authenticated automatically [2][4]. The action removes this token during the post-job cleanup phase [2][4]. If you wish to prevent the action from adding these credentials to the local git configuration, you must explicitly set persist-credentials to false in your workflow file [2][4][5]: - uses: actions/checkout@v4 with: persist-credentials: false Disabling this setting is often recommended if you are concerned about credential exposure (for example, if you archive and upload the repository as a workflow artifact) [5].

Citations:


Disable checkout credential persistence in the publish job.

actions/checkout@v4 leaves persist-credentials enabled by default, so the write-capable checkout token remains available to later commands in this job. Set persist-credentials: false; gh release create already receives a token explicitly through GH_TOKEN.

Suggested change
 - uses: actions/checkout@v4
+ with:+ persist-credentials: false
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.29.0)

[warning] 27-27: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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/release.yml at line 27, Update the actions/checkout@v4
step in the publish job to set persist-credentials to false, while preserving
the explicit GH_TOKEN used by gh release create.

Sources: MCP tools, Linters/SAST tools

Comment on lines +51 to +60
- name: Version must not already be published
run: |
set -euo pipefail
name=$(node -p "require('./package.json').name")
ver=$(node -p "require('./package.json').version")
if npm view "$name@$ver" version >/dev/null 2>&1; then
echo "::error::$name@$ver is already on the registry"
exit 1
fi
echo "$name@$ver is unpublished; proceeding"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"## workflow excerpt"
nl -ba .github/workflows/release.yml | sed -n '1,120p'echoecho"## node/npm usage in workflow"
grep -nE 'NODE_AUTH_TOKEN|npm|setup-node|package-lock.json|package\.json|registry' .github/workflows/release.yml ||trueechoecho"## package registry/auth hints"
sed -n '1,220p' package.json ||true
[ -f package-lock.json ] && sed -n '1,80p' package-lock.json ||true

Repository: vib795/agent-memory

Length of output: 217


🌐 Web query:

npm view command exit code 404 response npm 404 error exit code documentation

💡 Result:

When the npm CLI encounters an E404 error—most commonly when a requested package or version cannot be found in the registry—it typically exits with a non-zero exit code (specifically 1) [1][2][3]. Key details regarding npm view and E404 behavior include: 1. Exit Code: When npm view fails to find a package or a specific version, it reports an E404 error and terminates with a non-zero exit code (typically 1) [1][2][3]. This ensures that automated scripts and CI/CD pipelines can detect the failure [1][2]. 2. Error Context: The E404 error is explicitly logged to stderr, detailing that the requested resource is not available in the registry [2][3][4]. 3. Notable Edge Cases: There have been documented instances where npm commands may exit with code 0 despite a failure to find specific tags (such as npm view package@latest when the tag itself is missing), which has been a subject of bug reports [1]. 4. General Error Handling: The npm CLI determines exit codes based on error codes (like E404) or defaults to 1 for general failures [5]. If you are encountering this in an automated environment, you should rely on the non-zero exit code to signal that the lookup was unsuccessful, rather than relying solely on the presence or absence of output to stdout [1][2].

Citations:


🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"## release workflow excerpt"
awk '{printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml | sed -n '1,130p'echoecho"## auth/npm related lines"
awk '{if (/NODE_AUTH_TOKEN|npm|setup-node|registry|package-lock|package\.json/) printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml
echoecho"## package registry/auth hints"
awk '{printf "%6d\t%s\n", NR, $0}' package.json | sed -n '1,220p'
[ -f package-lock.json ] && awk '{printf "%6d\t%s\n", NR, $0}' package-lock.json | sed -n '1,80p'

Repository: vib795/agent-memory

Length of output: 6378


🌐 Web query:

GitHub Actions setup-node NODE_AUTH_TOKEN npm view npm publish publishConfig registry-url scoped package

💡 Result:

To publish a scoped package to a specific registry using GitHub Actions and the setup-node action, you must correctly configure both the authentication environment and the registry mapping [1][2]. The setup-node action automates the creation of an.npmrc file that configures your registry and authentication [1][3]. Workflow Configuration 1. Use the setup-node action to define the target registry and the package scope [4][1]. 2. Provide an authentication token via the NODE_AUTH_TOKEN environment variable [1]. Example: - uses: actions/setup-node@v4 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org/' # Or your private registry URL scope: '@your-scope' - run: npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} Key Components - registry-url: This input instructs setup-node to write the registry URL to a project-level.npmrc file [4][3]. - scope: When provided, setup-node configures the.npmrc to associate this scope with the specified registry [3][5]. If not provided, it may default to the repository owner when using the GitHub Packages registry [4][2]. - NODE_AUTH_TOKEN: This environment variable is required by npm to authenticate requests [1]. The setup-node action automatically injects this token into the generated.npmrc [1][3]. Handling publishConfig If you need to ensure a package is always published to a specific registry regardless of local or global.npmrc settings, you can define it in your package.json [6]: { "publishConfig": { "@your-scope:registry": "https://registry.npmjs.org/" } } This configuration is particularly useful for scoped packages to avoid conflicts with default registry settings [7][8]. When using this method, ensure your registry credentials are still properly configured in the environment (e.g., via setup-node) [1]. Important Note: GitHub Packages (GPR) exclusively supports scoped packages (e.g., @owner/package-name) [5][9]. Ensure your package name in package.json adheres to this format if you are targeting GPR [5].

Citations:


🌐 Web query:

npm cli npm view private package 404 E404 non-zero exit code npm 404

💡 Result:

When you receive an E404 error with a non-zero exit code while running npm view on a private package, it generally indicates that the npm CLI could not find the package manifest at the specified or default registry [1][2]. This error typically occurs for the following reasons: 1. Lack of Authentication: If the package is private (e.g., restricted access) and you are not authenticated, the registry will return a 404 (Not Found) instead of a 403 (Forbidden) to prevent leaking the existence of private packages to unauthenticated users [3]. Ensure you are logged in (npm login) or have the correct authentication token (e.g., NODE_AUTH_TOKEN) configured for your environment [3]. 2. Incorrect Registry Configuration: npm might be looking at the public registry (registry.npmjs.org) instead of your private registry [4][5]. Check your.npmrc file to ensure your scope is correctly mapped to the intended private registry URL (e.g., @mycompany:registry=https://npm.pkg.github.com/) [5][2]. 3. Workspace/Bulk Operations: If you are running npm view with workspace flags (-ws), the command may fail and exit if it encounters a 404 for any individual workspace, including private ones that have not yet been published or are inaccessible [1][6]. Recent versions of the npm CLI have introduced improvements to handle these workspace-related 404 errors more gracefully [1]. 4. Package or Tag Absence: The package itself, or the specific version/tag you are querying, may genuinely not exist in the targeted registry [7][2]. To debug, you can run the command with increased verbosity to see exactly which registry and URL the CLI is attempting to access: npm view -dddd [5][2] This will help you verify if the CLI is resolving to the registry you expect and if the authentication headers are being included in the request [5][2].

Citations:


🌐 Web query:

npm view npm view package version output empty stderr exit code 0

💡 Result:

When you run the npm view command and it returns an empty output with an exit code of 0, it typically indicates that the command successfully executed but could not find the specific package, version, or tag you requested [1][2][3]. Historical context and behavior: - Legacy Behavior: In older versions of the npm CLI, npm view would frequently return an empty string and a success exit code (0) when a requested version or tag did not exist in the registry [4][5][6]. This was often used by automated scripts to verify if a package was missing [4][5]. - Recent Changes: Newer versions of the npm CLI have been updated to treat these cases as errors, generally returning an E404 error code and a non-zero exit code [4][7][6]. If you are encountering an empty output with a zero exit code, you are likely using an older version of npm or interacting with a specific registry configuration that causes this behavior [2][3][6]. - Underlying Cause: The primary cause is often that the package does not have a version tagged as "latest" (which is the default tag if none is specified), or the specific version/tag requested does not exist on the target registry [1][2][4]. Recommendations: - Check your npm version: Run npm -v to see if you are using an older version. Upgrading may provide more consistent error reporting [6]. - Verify the registry: If you are using a private registry (like Nexus or GitHub Packages), ensure it is configured correctly, as some third-party registries may not handle metadata requests in the exact way the npm CLI expects [1][2][3]. - Handle empty output in scripts: If you must rely on existing behavior, ensure your scripts are designed to handle both empty output and potential error states, especially as newer versions of npm are moving toward stricter E404 reporting [4][5].

Citations:


Fail closed when checking npm publication state.

The current check treats every failed npm view result as “unpublished”, including auth failures, registry errors, and network failures. NODE_AUTH_TOKEN is only provided during npm publish, so npm view runs as an anonymous public lookup and cannot distinguish an unpublished version from a private package or transient failure. Provide the token on this step and abort unless the lookup is confirmed absent.

🤖 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/release.yml around lines 51 - 60, Update the “Version must
not already be published” step to provide NODE_AUTH_TOKEN to the npm view
lookup, distinguish a confirmed not-found result from authentication, registry,
or network errors, and fail the workflow for every result except confirmed
absence; retain the existing error and success messages for published and
unpublished versions.

Source: MCP tools

Comment on lines +65 to +78
- name: Publish
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Cut the GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
gh release create "$GITHUB_REF_NAME" \
--title "$GITHUB_REF_NAME" \
--generate-notes \
--verify-tag

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"== workflow excerpt =="if [ -f .github/workflows/release.yml ];then
sed -n '1,120p' .github/workflows/release.yml | cat -n
elseecho"missing .github/workflows/release.yml"fiecho"== release workflow search =="
rg -n "npm publish|gh release create|verify-tag|package.json|RELEASE|GITHUB_REF_NAME|GH_TOKEN|NPM_TOKEN|version" .github/workflows/release.yml .github/workflows 2>/dev/null ||trueecho"== package manifests =="forfin package.json pnpm-lock.yaml package-lock.json yarn.lock;doif [ -f"$f" ];thenecho"--- $f ---"
rg -n '"version"|"name"|engines|private|publishConfig|workspaces|npm'"$f" -m 50 ||truefidone

Repository: vib795/agent-memory

Length of output: 7244


Make npm publication and GitHub Release creation recoverable.

The workflow writes npm and GitHub independently. If npm publish succeeds but gh release create fails, rerunning the workflow skips the Release step after npm view "$name@$ver" succeeds. Add an idempotent recovery path that lets a rerun publish-only failures be retried and skip a confirmed existing package version when restoring only the missing GitHub Release.

🤖 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/release.yml around lines 65 - 78, Make the Publish and Cut
the GitHub Release steps independently idempotent: retry npm publication when
the package version is absent, but skip it only after confirming that exact
version already exists; separately check whether the GitHub release for
GITHUB_REF_NAME exists and create it when missing, so reruns can restore only
the release without being blocked by npm view.

@vib795vib795 mentioned this pull request Aug 8, 2026
vib795 added a commit that referenced this pull request Aug 8, 2026
No functional change. This exercises the tag-triggered publish path added in #5
end to end: matrix gate, version guards, provenance signing, GitHub Release.
A release pipeline that has never run is not a release pipeline, and a patch
with nothing in it is the cheapest way to find that out.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@vib795
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' ci: publish to npm on tag push by vib795 · Pull Request #5 · vib795/agent-memory · GitHub
Skip to content

ci: publish to npm on tag push - #5

Merged
vib795 merged 1 commit into
mainfrom
ci/release-on-tag
Aug 8, 2026
Merged

ci: publish to npm on tag push#5
vib795 merged 1 commit into
mainfrom
ci/release-on-tag

Conversation

@vib795

@vib795vib795 commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Publishing 0.1.0 cost a 2FA recovery code. The codes are finite and single-use, which is a poor place for a release process to live.

What a v* tag now does

  1. Runs the full test matrix (test.yml gained a workflow_call trigger so this reuses it rather than duplicating it)
  2. Asserts the tag matches package.json version — a mismatch means someone tagged the wrong commit or skipped the bump, and npm never gives a version number back
  3. Asserts the version is not already published — turns a post-upload 403 into a one-line failure
  4. Publishes with --provenance, which ties the tarball to the commit and workflow run and shows the badge on npm
  5. Cuts the GitHub Release with --verify-tag

The matrix runs here rather than trusting the run on main, because a tag can point at any commit — including one main never saw.

Before this can work

Add an NPM_TOKEN repository secret: a granular access token scoped to @vib795, read+write, with bypass 2FA enabled. Without it the publish step fails on auth.

Not retroactive

v0.1.0 was tagged and published by hand before this existed, so this takes effect from the next tag.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Improved the release process with automated package publishing and GitHub Release creation.
    • Added version validation to help prevent publishing mismatched or duplicate releases.
    • Releases now include provenance information for improved package authenticity and traceability.
    • Automated testing runs as part of the release process to help ensure published versions meet quality standards.

Releases were blocked on a human with a 2FA recovery code, which is a bad
place for a release process to live: the codes are finite, single-use, and
spending one is not something you want between a fix and its users.
A v* tag now runs the full test matrix, asserts the tag agrees with
package.json, asserts the version is not already on the registry, publishes
with provenance, and cuts the GitHub Release.
The matrix runs again here rather than trusting the run on main, because a
tag can point at any commit, including one main never saw.
Requires the NPM_TOKEN repository secret: a granular access token scoped to
@vib795 with 2FA bypass enabled.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The workflows add reusable test execution and a tag-triggered release process. The release process validates the tag and package version, prevents duplicate npm publication, publishes with provenance, and creates a GitHub Release.

Changes

Release Pipeline

Layer / File(s)Summary
Reusable test workflow
.github/workflows/test.yml
The test workflow now supports workflow_call in addition to its existing triggers.
Tagged package release
.github/workflows/release.yml
The new workflow runs tests, validates version data, publishes the package to npm, and creates a GitHub Release for v* tags.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
participant GitHubTag
participant TestWorkflow
participant PublishJob
participant NpmRegistry
participant GitHubRelease
GitHubTag->>TestWorkflow: invoke reusable tests
TestWorkflow-->>PublishJob: return test result
PublishJob->>PublishJob: validate tag and package version
PublishJob->>NpmRegistry: publish package with provenance
PublishJob->>GitHubRelease: create release with generated notes
Loading

Poem

I’m a rabbit with a tagged release,
Tests hop first, then checks bring peace.
npm gets a provenance bow,
GitHub notes are written now.
One clean carrot-sized deploy!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the main change: automated npm publishing triggered by tag pushes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/release-on-tag

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@vib795
vib795 merged commit 8a1107c into mainAug 8, 2026
9 of 10 checks passed
@vib795
vib795 deleted the ci/release-on-tag branch August 8, 2026 00:24

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 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/release.yml:
- Around line 65-78: Make the Publish and Cut the GitHub Release steps
independently idempotent: retry npm publication when the package version is
absent, but skip it only after confirming that exact version already exists;
separately check whether the GitHub release for GITHUB_REF_NAME exists and
create it when missing, so reruns can restore only the release without being
blocked by npm view.
- Line 27: Update the actions/checkout@v4 step in the publish job to set
persist-credentials to false, while preserving the explicit GH_TOKEN used by gh
release create.
- Around line 51-60: Update the “Version must not already be published” step to
provide NODE_AUTH_TOKEN to the npm view lookup, distinguish a confirmed
not-found result from authentication, registry, or network errors, and fail the
workflow for every result except confirmed absence; retain the existing error
and success messages for published and unpublished versions.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d4443e0f-9b1a-49ab-b76c-3b1fc0d657e4

📥 Commits

Reviewing files that changed from the base of the PR and between 01dd384 and 07cb679.

📒 Files selected for processing (2)
  • .github/workflows/release.yml
  • .github/workflows/test.yml

contents: write # cut the GitHub Release
id-token: write # sign the npm provenance attestation
steps:
- uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"== workflow excerpt =="
sed -n '1,110p' .github/workflows/release.yml
echoecho"== checkout occurrences =="
rg -n "actions/checkout|persist-credentials|permissions:|contents:" .github/workflows/release.yml

Repository: vib795/agent-memory

Length of output: 3213


🌐 Web query:

actions/checkout v4 action.yml persist-credentials default true

💡 Result:

In the actions/checkout v4 action, the persist-credentials input has a default value of true [1][2][3]. When this setting is enabled (the default), the action configures the repository's local git configuration to include the authentication token or SSH key used for the checkout [2][4]. This allows subsequent git commands executed within the runner to be authenticated automatically [2][4]. The action removes this token during the post-job cleanup phase [2][4]. If you wish to prevent the action from adding these credentials to the local git configuration, you must explicitly set persist-credentials to false in your workflow file [2][4][5]: - uses: actions/checkout@v4 with: persist-credentials: false Disabling this setting is often recommended if you are concerned about credential exposure (for example, if you archive and upload the repository as a workflow artifact) [5].

Citations:


Disable checkout credential persistence in the publish job.

actions/checkout@v4 leaves persist-credentials enabled by default, so the write-capable checkout token remains available to later commands in this job. Set persist-credentials: false; gh release create already receives a token explicitly through GH_TOKEN.

Suggested change
 - uses: actions/checkout@v4
+ with:+ persist-credentials: false
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.29.0)

[warning] 27-27: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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/release.yml at line 27, Update the actions/checkout@v4
step in the publish job to set persist-credentials to false, while preserving
the explicit GH_TOKEN used by gh release create.

Sources: MCP tools, Linters/SAST tools

Comment on lines +51 to +60
- name: Version must not already be published
run: |
set -euo pipefail
name=$(node -p "require('./package.json').name")
ver=$(node -p "require('./package.json').version")
if npm view "$name@$ver" version >/dev/null 2>&1; then
echo "::error::$name@$ver is already on the registry"
exit 1
fi
echo "$name@$ver is unpublished; proceeding"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"## workflow excerpt"
nl -ba .github/workflows/release.yml | sed -n '1,120p'echoecho"## node/npm usage in workflow"
grep -nE 'NODE_AUTH_TOKEN|npm|setup-node|package-lock.json|package\.json|registry' .github/workflows/release.yml ||trueechoecho"## package registry/auth hints"
sed -n '1,220p' package.json ||true
[ -f package-lock.json ] && sed -n '1,80p' package-lock.json ||true

Repository: vib795/agent-memory

Length of output: 217


🌐 Web query:

npm view command exit code 404 response npm 404 error exit code documentation

💡 Result:

When the npm CLI encounters an E404 error—most commonly when a requested package or version cannot be found in the registry—it typically exits with a non-zero exit code (specifically 1) [1][2][3]. Key details regarding npm view and E404 behavior include: 1. Exit Code: When npm view fails to find a package or a specific version, it reports an E404 error and terminates with a non-zero exit code (typically 1) [1][2][3]. This ensures that automated scripts and CI/CD pipelines can detect the failure [1][2]. 2. Error Context: The E404 error is explicitly logged to stderr, detailing that the requested resource is not available in the registry [2][3][4]. 3. Notable Edge Cases: There have been documented instances where npm commands may exit with code 0 despite a failure to find specific tags (such as npm view package@latest when the tag itself is missing), which has been a subject of bug reports [1]. 4. General Error Handling: The npm CLI determines exit codes based on error codes (like E404) or defaults to 1 for general failures [5]. If you are encountering this in an automated environment, you should rely on the non-zero exit code to signal that the lookup was unsuccessful, rather than relying solely on the presence or absence of output to stdout [1][2].

Citations:


🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"## release workflow excerpt"
awk '{printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml | sed -n '1,130p'echoecho"## auth/npm related lines"
awk '{if (/NODE_AUTH_TOKEN|npm|setup-node|registry|package-lock|package\.json/) printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml
echoecho"## package registry/auth hints"
awk '{printf "%6d\t%s\n", NR, $0}' package.json | sed -n '1,220p'
[ -f package-lock.json ] && awk '{printf "%6d\t%s\n", NR, $0}' package-lock.json | sed -n '1,80p'

Repository: vib795/agent-memory

Length of output: 6378


🌐 Web query:

GitHub Actions setup-node NODE_AUTH_TOKEN npm view npm publish publishConfig registry-url scoped package

💡 Result:

To publish a scoped package to a specific registry using GitHub Actions and the setup-node action, you must correctly configure both the authentication environment and the registry mapping [1][2]. The setup-node action automates the creation of an.npmrc file that configures your registry and authentication [1][3]. Workflow Configuration 1. Use the setup-node action to define the target registry and the package scope [4][1]. 2. Provide an authentication token via the NODE_AUTH_TOKEN environment variable [1]. Example: - uses: actions/setup-node@v4 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org/' # Or your private registry URL scope: '@your-scope' - run: npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} Key Components - registry-url: This input instructs setup-node to write the registry URL to a project-level.npmrc file [4][3]. - scope: When provided, setup-node configures the.npmrc to associate this scope with the specified registry [3][5]. If not provided, it may default to the repository owner when using the GitHub Packages registry [4][2]. - NODE_AUTH_TOKEN: This environment variable is required by npm to authenticate requests [1]. The setup-node action automatically injects this token into the generated.npmrc [1][3]. Handling publishConfig If you need to ensure a package is always published to a specific registry regardless of local or global.npmrc settings, you can define it in your package.json [6]: { "publishConfig": { "@your-scope:registry": "https://registry.npmjs.org/" } } This configuration is particularly useful for scoped packages to avoid conflicts with default registry settings [7][8]. When using this method, ensure your registry credentials are still properly configured in the environment (e.g., via setup-node) [1]. Important Note: GitHub Packages (GPR) exclusively supports scoped packages (e.g., @owner/package-name) [5][9]. Ensure your package name in package.json adheres to this format if you are targeting GPR [5].

Citations:


🌐 Web query:

npm cli npm view private package 404 E404 non-zero exit code npm 404

💡 Result:

When you receive an E404 error with a non-zero exit code while running npm view on a private package, it generally indicates that the npm CLI could not find the package manifest at the specified or default registry [1][2]. This error typically occurs for the following reasons: 1. Lack of Authentication: If the package is private (e.g., restricted access) and you are not authenticated, the registry will return a 404 (Not Found) instead of a 403 (Forbidden) to prevent leaking the existence of private packages to unauthenticated users [3]. Ensure you are logged in (npm login) or have the correct authentication token (e.g., NODE_AUTH_TOKEN) configured for your environment [3]. 2. Incorrect Registry Configuration: npm might be looking at the public registry (registry.npmjs.org) instead of your private registry [4][5]. Check your.npmrc file to ensure your scope is correctly mapped to the intended private registry URL (e.g., @mycompany:registry=https://npm.pkg.github.com/) [5][2]. 3. Workspace/Bulk Operations: If you are running npm view with workspace flags (-ws), the command may fail and exit if it encounters a 404 for any individual workspace, including private ones that have not yet been published or are inaccessible [1][6]. Recent versions of the npm CLI have introduced improvements to handle these workspace-related 404 errors more gracefully [1]. 4. Package or Tag Absence: The package itself, or the specific version/tag you are querying, may genuinely not exist in the targeted registry [7][2]. To debug, you can run the command with increased verbosity to see exactly which registry and URL the CLI is attempting to access: npm view -dddd [5][2] This will help you verify if the CLI is resolving to the registry you expect and if the authentication headers are being included in the request [5][2].

Citations:


🌐 Web query:

npm view npm view package version output empty stderr exit code 0

💡 Result:

When you run the npm view command and it returns an empty output with an exit code of 0, it typically indicates that the command successfully executed but could not find the specific package, version, or tag you requested [1][2][3]. Historical context and behavior: - Legacy Behavior: In older versions of the npm CLI, npm view would frequently return an empty string and a success exit code (0) when a requested version or tag did not exist in the registry [4][5][6]. This was often used by automated scripts to verify if a package was missing [4][5]. - Recent Changes: Newer versions of the npm CLI have been updated to treat these cases as errors, generally returning an E404 error code and a non-zero exit code [4][7][6]. If you are encountering an empty output with a zero exit code, you are likely using an older version of npm or interacting with a specific registry configuration that causes this behavior [2][3][6]. - Underlying Cause: The primary cause is often that the package does not have a version tagged as "latest" (which is the default tag if none is specified), or the specific version/tag requested does not exist on the target registry [1][2][4]. Recommendations: - Check your npm version: Run npm -v to see if you are using an older version. Upgrading may provide more consistent error reporting [6]. - Verify the registry: If you are using a private registry (like Nexus or GitHub Packages), ensure it is configured correctly, as some third-party registries may not handle metadata requests in the exact way the npm CLI expects [1][2][3]. - Handle empty output in scripts: If you must rely on existing behavior, ensure your scripts are designed to handle both empty output and potential error states, especially as newer versions of npm are moving toward stricter E404 reporting [4][5].

Citations:


Fail closed when checking npm publication state.

The current check treats every failed npm view result as “unpublished”, including auth failures, registry errors, and network failures. NODE_AUTH_TOKEN is only provided during npm publish, so npm view runs as an anonymous public lookup and cannot distinguish an unpublished version from a private package or transient failure. Provide the token on this step and abort unless the lookup is confirmed absent.

🤖 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/release.yml around lines 51 - 60, Update the “Version must
not already be published” step to provide NODE_AUTH_TOKEN to the npm view
lookup, distinguish a confirmed not-found result from authentication, registry,
or network errors, and fail the workflow for every result except confirmed
absence; retain the existing error and success messages for published and
unpublished versions.

Source: MCP tools

Comment on lines +65 to +78
- name: Publish
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Cut the GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
gh release create "$GITHUB_REF_NAME" \
--title "$GITHUB_REF_NAME" \
--generate-notes \
--verify-tag

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"== workflow excerpt =="if [ -f .github/workflows/release.yml ];then
sed -n '1,120p' .github/workflows/release.yml | cat -n
elseecho"missing .github/workflows/release.yml"fiecho"== release workflow search =="
rg -n "npm publish|gh release create|verify-tag|package.json|RELEASE|GITHUB_REF_NAME|GH_TOKEN|NPM_TOKEN|version" .github/workflows/release.yml .github/workflows 2>/dev/null ||trueecho"== package manifests =="forfin package.json pnpm-lock.yaml package-lock.json yarn.lock;doif [ -f"$f" ];thenecho"--- $f ---"
rg -n '"version"|"name"|engines|private|publishConfig|workspaces|npm'"$f" -m 50 ||truefidone

Repository: vib795/agent-memory

Length of output: 7244


Make npm publication and GitHub Release creation recoverable.

The workflow writes npm and GitHub independently. If npm publish succeeds but gh release create fails, rerunning the workflow skips the Release step after npm view "$name@$ver" succeeds. Add an idempotent recovery path that lets a rerun publish-only failures be retried and skip a confirmed existing package version when restoring only the missing GitHub Release.

🤖 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/release.yml around lines 65 - 78, Make the Publish and Cut
the GitHub Release steps independently idempotent: retry npm publication when
the package version is absent, but skip it only after confirming that exact
version already exists; separately check whether the GitHub release for
GITHUB_REF_NAME exists and create it when missing, so reruns can restore only
the release without being blocked by npm view.

@vib795vib795 mentioned this pull request Aug 8, 2026
vib795 added a commit that referenced this pull request Aug 8, 2026
No functional change. This exercises the tag-triggered publish path added in #5
end to end: matrix gate, version guards, provenance signing, GitHub Release.
A release pipeline that has never run is not a release pipeline, and a patch
with nothing in it is the cheapest way to find that out.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@vib795
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' ci: publish to npm on tag push by vib795 · Pull Request #5 · vib795/agent-memory · GitHub
Skip to content

ci: publish to npm on tag push - #5

Merged
vib795 merged 1 commit into
mainfrom
ci/release-on-tag
Aug 8, 2026
Merged

ci: publish to npm on tag push#5
vib795 merged 1 commit into
mainfrom
ci/release-on-tag

Conversation

@vib795

@vib795vib795 commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Publishing 0.1.0 cost a 2FA recovery code. The codes are finite and single-use, which is a poor place for a release process to live.

What a v* tag now does

  1. Runs the full test matrix (test.yml gained a workflow_call trigger so this reuses it rather than duplicating it)
  2. Asserts the tag matches package.json version — a mismatch means someone tagged the wrong commit or skipped the bump, and npm never gives a version number back
  3. Asserts the version is not already published — turns a post-upload 403 into a one-line failure
  4. Publishes with --provenance, which ties the tarball to the commit and workflow run and shows the badge on npm
  5. Cuts the GitHub Release with --verify-tag

The matrix runs here rather than trusting the run on main, because a tag can point at any commit — including one main never saw.

Before this can work

Add an NPM_TOKEN repository secret: a granular access token scoped to @vib795, read+write, with bypass 2FA enabled. Without it the publish step fails on auth.

Not retroactive

v0.1.0 was tagged and published by hand before this existed, so this takes effect from the next tag.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Improved the release process with automated package publishing and GitHub Release creation.
    • Added version validation to help prevent publishing mismatched or duplicate releases.
    • Releases now include provenance information for improved package authenticity and traceability.
    • Automated testing runs as part of the release process to help ensure published versions meet quality standards.

Releases were blocked on a human with a 2FA recovery code, which is a bad
place for a release process to live: the codes are finite, single-use, and
spending one is not something you want between a fix and its users.
A v* tag now runs the full test matrix, asserts the tag agrees with
package.json, asserts the version is not already on the registry, publishes
with provenance, and cuts the GitHub Release.
The matrix runs again here rather than trusting the run on main, because a
tag can point at any commit, including one main never saw.
Requires the NPM_TOKEN repository secret: a granular access token scoped to
@vib795 with 2FA bypass enabled.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The workflows add reusable test execution and a tag-triggered release process. The release process validates the tag and package version, prevents duplicate npm publication, publishes with provenance, and creates a GitHub Release.

Changes

Release Pipeline

Layer / File(s)Summary
Reusable test workflow
.github/workflows/test.yml
The test workflow now supports workflow_call in addition to its existing triggers.
Tagged package release
.github/workflows/release.yml
The new workflow runs tests, validates version data, publishes the package to npm, and creates a GitHub Release for v* tags.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
participant GitHubTag
participant TestWorkflow
participant PublishJob
participant NpmRegistry
participant GitHubRelease
GitHubTag->>TestWorkflow: invoke reusable tests
TestWorkflow-->>PublishJob: return test result
PublishJob->>PublishJob: validate tag and package version
PublishJob->>NpmRegistry: publish package with provenance
PublishJob->>GitHubRelease: create release with generated notes
Loading

Poem

I’m a rabbit with a tagged release,
Tests hop first, then checks bring peace.
npm gets a provenance bow,
GitHub notes are written now.
One clean carrot-sized deploy!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the main change: automated npm publishing triggered by tag pushes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/release-on-tag

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@vib795
vib795 merged commit 8a1107c into mainAug 8, 2026
9 of 10 checks passed
@vib795
vib795 deleted the ci/release-on-tag branch August 8, 2026 00:24

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 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/release.yml:
- Around line 65-78: Make the Publish and Cut the GitHub Release steps
independently idempotent: retry npm publication when the package version is
absent, but skip it only after confirming that exact version already exists;
separately check whether the GitHub release for GITHUB_REF_NAME exists and
create it when missing, so reruns can restore only the release without being
blocked by npm view.
- Line 27: Update the actions/checkout@v4 step in the publish job to set
persist-credentials to false, while preserving the explicit GH_TOKEN used by gh
release create.
- Around line 51-60: Update the “Version must not already be published” step to
provide NODE_AUTH_TOKEN to the npm view lookup, distinguish a confirmed
not-found result from authentication, registry, or network errors, and fail the
workflow for every result except confirmed absence; retain the existing error
and success messages for published and unpublished versions.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d4443e0f-9b1a-49ab-b76c-3b1fc0d657e4

📥 Commits

Reviewing files that changed from the base of the PR and between 01dd384 and 07cb679.

📒 Files selected for processing (2)
  • .github/workflows/release.yml
  • .github/workflows/test.yml

contents: write # cut the GitHub Release
id-token: write # sign the npm provenance attestation
steps:
- uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"== workflow excerpt =="
sed -n '1,110p' .github/workflows/release.yml
echoecho"== checkout occurrences =="
rg -n "actions/checkout|persist-credentials|permissions:|contents:" .github/workflows/release.yml

Repository: vib795/agent-memory

Length of output: 3213


🌐 Web query:

actions/checkout v4 action.yml persist-credentials default true

💡 Result:

In the actions/checkout v4 action, the persist-credentials input has a default value of true [1][2][3]. When this setting is enabled (the default), the action configures the repository's local git configuration to include the authentication token or SSH key used for the checkout [2][4]. This allows subsequent git commands executed within the runner to be authenticated automatically [2][4]. The action removes this token during the post-job cleanup phase [2][4]. If you wish to prevent the action from adding these credentials to the local git configuration, you must explicitly set persist-credentials to false in your workflow file [2][4][5]: - uses: actions/checkout@v4 with: persist-credentials: false Disabling this setting is often recommended if you are concerned about credential exposure (for example, if you archive and upload the repository as a workflow artifact) [5].

Citations:


Disable checkout credential persistence in the publish job.

actions/checkout@v4 leaves persist-credentials enabled by default, so the write-capable checkout token remains available to later commands in this job. Set persist-credentials: false; gh release create already receives a token explicitly through GH_TOKEN.

Suggested change
 - uses: actions/checkout@v4
+ with:+ persist-credentials: false
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.29.0)

[warning] 27-27: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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/release.yml at line 27, Update the actions/checkout@v4
step in the publish job to set persist-credentials to false, while preserving
the explicit GH_TOKEN used by gh release create.

Sources: MCP tools, Linters/SAST tools

Comment on lines +51 to +60
- name: Version must not already be published
run: |
set -euo pipefail
name=$(node -p "require('./package.json').name")
ver=$(node -p "require('./package.json').version")
if npm view "$name@$ver" version >/dev/null 2>&1; then
echo "::error::$name@$ver is already on the registry"
exit 1
fi
echo "$name@$ver is unpublished; proceeding"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"## workflow excerpt"
nl -ba .github/workflows/release.yml | sed -n '1,120p'echoecho"## node/npm usage in workflow"
grep -nE 'NODE_AUTH_TOKEN|npm|setup-node|package-lock.json|package\.json|registry' .github/workflows/release.yml ||trueechoecho"## package registry/auth hints"
sed -n '1,220p' package.json ||true
[ -f package-lock.json ] && sed -n '1,80p' package-lock.json ||true

Repository: vib795/agent-memory

Length of output: 217


🌐 Web query:

npm view command exit code 404 response npm 404 error exit code documentation

💡 Result:

When the npm CLI encounters an E404 error—most commonly when a requested package or version cannot be found in the registry—it typically exits with a non-zero exit code (specifically 1) [1][2][3]. Key details regarding npm view and E404 behavior include: 1. Exit Code: When npm view fails to find a package or a specific version, it reports an E404 error and terminates with a non-zero exit code (typically 1) [1][2][3]. This ensures that automated scripts and CI/CD pipelines can detect the failure [1][2]. 2. Error Context: The E404 error is explicitly logged to stderr, detailing that the requested resource is not available in the registry [2][3][4]. 3. Notable Edge Cases: There have been documented instances where npm commands may exit with code 0 despite a failure to find specific tags (such as npm view package@latest when the tag itself is missing), which has been a subject of bug reports [1]. 4. General Error Handling: The npm CLI determines exit codes based on error codes (like E404) or defaults to 1 for general failures [5]. If you are encountering this in an automated environment, you should rely on the non-zero exit code to signal that the lookup was unsuccessful, rather than relying solely on the presence or absence of output to stdout [1][2].

Citations:


🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"## release workflow excerpt"
awk '{printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml | sed -n '1,130p'echoecho"## auth/npm related lines"
awk '{if (/NODE_AUTH_TOKEN|npm|setup-node|registry|package-lock|package\.json/) printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml
echoecho"## package registry/auth hints"
awk '{printf "%6d\t%s\n", NR, $0}' package.json | sed -n '1,220p'
[ -f package-lock.json ] && awk '{printf "%6d\t%s\n", NR, $0}' package-lock.json | sed -n '1,80p'

Repository: vib795/agent-memory

Length of output: 6378


🌐 Web query:

GitHub Actions setup-node NODE_AUTH_TOKEN npm view npm publish publishConfig registry-url scoped package

💡 Result:

To publish a scoped package to a specific registry using GitHub Actions and the setup-node action, you must correctly configure both the authentication environment and the registry mapping [1][2]. The setup-node action automates the creation of an.npmrc file that configures your registry and authentication [1][3]. Workflow Configuration 1. Use the setup-node action to define the target registry and the package scope [4][1]. 2. Provide an authentication token via the NODE_AUTH_TOKEN environment variable [1]. Example: - uses: actions/setup-node@v4 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org/' # Or your private registry URL scope: '@your-scope' - run: npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} Key Components - registry-url: This input instructs setup-node to write the registry URL to a project-level.npmrc file [4][3]. - scope: When provided, setup-node configures the.npmrc to associate this scope with the specified registry [3][5]. If not provided, it may default to the repository owner when using the GitHub Packages registry [4][2]. - NODE_AUTH_TOKEN: This environment variable is required by npm to authenticate requests [1]. The setup-node action automatically injects this token into the generated.npmrc [1][3]. Handling publishConfig If you need to ensure a package is always published to a specific registry regardless of local or global.npmrc settings, you can define it in your package.json [6]: { "publishConfig": { "@your-scope:registry": "https://registry.npmjs.org/" } } This configuration is particularly useful for scoped packages to avoid conflicts with default registry settings [7][8]. When using this method, ensure your registry credentials are still properly configured in the environment (e.g., via setup-node) [1]. Important Note: GitHub Packages (GPR) exclusively supports scoped packages (e.g., @owner/package-name) [5][9]. Ensure your package name in package.json adheres to this format if you are targeting GPR [5].

Citations:


🌐 Web query:

npm cli npm view private package 404 E404 non-zero exit code npm 404

💡 Result:

When you receive an E404 error with a non-zero exit code while running npm view on a private package, it generally indicates that the npm CLI could not find the package manifest at the specified or default registry [1][2]. This error typically occurs for the following reasons: 1. Lack of Authentication: If the package is private (e.g., restricted access) and you are not authenticated, the registry will return a 404 (Not Found) instead of a 403 (Forbidden) to prevent leaking the existence of private packages to unauthenticated users [3]. Ensure you are logged in (npm login) or have the correct authentication token (e.g., NODE_AUTH_TOKEN) configured for your environment [3]. 2. Incorrect Registry Configuration: npm might be looking at the public registry (registry.npmjs.org) instead of your private registry [4][5]. Check your.npmrc file to ensure your scope is correctly mapped to the intended private registry URL (e.g., @mycompany:registry=https://npm.pkg.github.com/) [5][2]. 3. Workspace/Bulk Operations: If you are running npm view with workspace flags (-ws), the command may fail and exit if it encounters a 404 for any individual workspace, including private ones that have not yet been published or are inaccessible [1][6]. Recent versions of the npm CLI have introduced improvements to handle these workspace-related 404 errors more gracefully [1]. 4. Package or Tag Absence: The package itself, or the specific version/tag you are querying, may genuinely not exist in the targeted registry [7][2]. To debug, you can run the command with increased verbosity to see exactly which registry and URL the CLI is attempting to access: npm view -dddd [5][2] This will help you verify if the CLI is resolving to the registry you expect and if the authentication headers are being included in the request [5][2].

Citations:


🌐 Web query:

npm view npm view package version output empty stderr exit code 0

💡 Result:

When you run the npm view command and it returns an empty output with an exit code of 0, it typically indicates that the command successfully executed but could not find the specific package, version, or tag you requested [1][2][3]. Historical context and behavior: - Legacy Behavior: In older versions of the npm CLI, npm view would frequently return an empty string and a success exit code (0) when a requested version or tag did not exist in the registry [4][5][6]. This was often used by automated scripts to verify if a package was missing [4][5]. - Recent Changes: Newer versions of the npm CLI have been updated to treat these cases as errors, generally returning an E404 error code and a non-zero exit code [4][7][6]. If you are encountering an empty output with a zero exit code, you are likely using an older version of npm or interacting with a specific registry configuration that causes this behavior [2][3][6]. - Underlying Cause: The primary cause is often that the package does not have a version tagged as "latest" (which is the default tag if none is specified), or the specific version/tag requested does not exist on the target registry [1][2][4]. Recommendations: - Check your npm version: Run npm -v to see if you are using an older version. Upgrading may provide more consistent error reporting [6]. - Verify the registry: If you are using a private registry (like Nexus or GitHub Packages), ensure it is configured correctly, as some third-party registries may not handle metadata requests in the exact way the npm CLI expects [1][2][3]. - Handle empty output in scripts: If you must rely on existing behavior, ensure your scripts are designed to handle both empty output and potential error states, especially as newer versions of npm are moving toward stricter E404 reporting [4][5].

Citations:


Fail closed when checking npm publication state.

The current check treats every failed npm view result as “unpublished”, including auth failures, registry errors, and network failures. NODE_AUTH_TOKEN is only provided during npm publish, so npm view runs as an anonymous public lookup and cannot distinguish an unpublished version from a private package or transient failure. Provide the token on this step and abort unless the lookup is confirmed absent.

🤖 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/release.yml around lines 51 - 60, Update the “Version must
not already be published” step to provide NODE_AUTH_TOKEN to the npm view
lookup, distinguish a confirmed not-found result from authentication, registry,
or network errors, and fail the workflow for every result except confirmed
absence; retain the existing error and success messages for published and
unpublished versions.

Source: MCP tools

Comment on lines +65 to +78
- name: Publish
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Cut the GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
gh release create "$GITHUB_REF_NAME" \
--title "$GITHUB_REF_NAME" \
--generate-notes \
--verify-tag

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"== workflow excerpt =="if [ -f .github/workflows/release.yml ];then
sed -n '1,120p' .github/workflows/release.yml | cat -n
elseecho"missing .github/workflows/release.yml"fiecho"== release workflow search =="
rg -n "npm publish|gh release create|verify-tag|package.json|RELEASE|GITHUB_REF_NAME|GH_TOKEN|NPM_TOKEN|version" .github/workflows/release.yml .github/workflows 2>/dev/null ||trueecho"== package manifests =="forfin package.json pnpm-lock.yaml package-lock.json yarn.lock;doif [ -f"$f" ];thenecho"--- $f ---"
rg -n '"version"|"name"|engines|private|publishConfig|workspaces|npm'"$f" -m 50 ||truefidone

Repository: vib795/agent-memory

Length of output: 7244


Make npm publication and GitHub Release creation recoverable.

The workflow writes npm and GitHub independently. If npm publish succeeds but gh release create fails, rerunning the workflow skips the Release step after npm view "$name@$ver" succeeds. Add an idempotent recovery path that lets a rerun publish-only failures be retried and skip a confirmed existing package version when restoring only the missing GitHub Release.

🤖 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/release.yml around lines 65 - 78, Make the Publish and Cut
the GitHub Release steps independently idempotent: retry npm publication when
the package version is absent, but skip it only after confirming that exact
version already exists; separately check whether the GitHub release for
GITHUB_REF_NAME exists and create it when missing, so reruns can restore only
the release without being blocked by npm view.

@vib795vib795 mentioned this pull request Aug 8, 2026
vib795 added a commit that referenced this pull request Aug 8, 2026
No functional change. This exercises the tag-triggered publish path added in #5
end to end: matrix gate, version guards, provenance signing, GitHub Release.
A release pipeline that has never run is not a release pipeline, and a patch
with nothing in it is the cheapest way to find that out.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@vib795
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); ci: publish to npm on tag push by vib795 · Pull Request #5 · vib795/agent-memory · GitHub
Skip to content

ci: publish to npm on tag push - #5

Merged
vib795 merged 1 commit into
mainfrom
ci/release-on-tag
Aug 8, 2026
Merged

ci: publish to npm on tag push#5
vib795 merged 1 commit into
mainfrom
ci/release-on-tag

Conversation

@vib795

@vib795vib795 commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Publishing 0.1.0 cost a 2FA recovery code. The codes are finite and single-use, which is a poor place for a release process to live.

What a v* tag now does

  1. Runs the full test matrix (test.yml gained a workflow_call trigger so this reuses it rather than duplicating it)
  2. Asserts the tag matches package.json version — a mismatch means someone tagged the wrong commit or skipped the bump, and npm never gives a version number back
  3. Asserts the version is not already published — turns a post-upload 403 into a one-line failure
  4. Publishes with --provenance, which ties the tarball to the commit and workflow run and shows the badge on npm
  5. Cuts the GitHub Release with --verify-tag

The matrix runs here rather than trusting the run on main, because a tag can point at any commit — including one main never saw.

Before this can work

Add an NPM_TOKEN repository secret: a granular access token scoped to @vib795, read+write, with bypass 2FA enabled. Without it the publish step fails on auth.

Not retroactive

v0.1.0 was tagged and published by hand before this existed, so this takes effect from the next tag.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Improved the release process with automated package publishing and GitHub Release creation.
    • Added version validation to help prevent publishing mismatched or duplicate releases.
    • Releases now include provenance information for improved package authenticity and traceability.
    • Automated testing runs as part of the release process to help ensure published versions meet quality standards.

Releases were blocked on a human with a 2FA recovery code, which is a bad
place for a release process to live: the codes are finite, single-use, and
spending one is not something you want between a fix and its users.
A v* tag now runs the full test matrix, asserts the tag agrees with
package.json, asserts the version is not already on the registry, publishes
with provenance, and cuts the GitHub Release.
The matrix runs again here rather than trusting the run on main, because a
tag can point at any commit, including one main never saw.
Requires the NPM_TOKEN repository secret: a granular access token scoped to
@vib795 with 2FA bypass enabled.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The workflows add reusable test execution and a tag-triggered release process. The release process validates the tag and package version, prevents duplicate npm publication, publishes with provenance, and creates a GitHub Release.

Changes

Release Pipeline

Layer / File(s)Summary
Reusable test workflow
.github/workflows/test.yml
The test workflow now supports workflow_call in addition to its existing triggers.
Tagged package release
.github/workflows/release.yml
The new workflow runs tests, validates version data, publishes the package to npm, and creates a GitHub Release for v* tags.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
participant GitHubTag
participant TestWorkflow
participant PublishJob
participant NpmRegistry
participant GitHubRelease
GitHubTag->>TestWorkflow: invoke reusable tests
TestWorkflow-->>PublishJob: return test result
PublishJob->>PublishJob: validate tag and package version
PublishJob->>NpmRegistry: publish package with provenance
PublishJob->>GitHubRelease: create release with generated notes
Loading

Poem

I’m a rabbit with a tagged release,
Tests hop first, then checks bring peace.
npm gets a provenance bow,
GitHub notes are written now.
One clean carrot-sized deploy!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the main change: automated npm publishing triggered by tag pushes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/release-on-tag

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@vib795
vib795 merged commit 8a1107c into mainAug 8, 2026
9 of 10 checks passed
@vib795
vib795 deleted the ci/release-on-tag branch August 8, 2026 00:24

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 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/release.yml:
- Around line 65-78: Make the Publish and Cut the GitHub Release steps
independently idempotent: retry npm publication when the package version is
absent, but skip it only after confirming that exact version already exists;
separately check whether the GitHub release for GITHUB_REF_NAME exists and
create it when missing, so reruns can restore only the release without being
blocked by npm view.
- Line 27: Update the actions/checkout@v4 step in the publish job to set
persist-credentials to false, while preserving the explicit GH_TOKEN used by gh
release create.
- Around line 51-60: Update the “Version must not already be published” step to
provide NODE_AUTH_TOKEN to the npm view lookup, distinguish a confirmed
not-found result from authentication, registry, or network errors, and fail the
workflow for every result except confirmed absence; retain the existing error
and success messages for published and unpublished versions.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d4443e0f-9b1a-49ab-b76c-3b1fc0d657e4

📥 Commits

Reviewing files that changed from the base of the PR and between 01dd384 and 07cb679.

📒 Files selected for processing (2)
  • .github/workflows/release.yml
  • .github/workflows/test.yml

contents: write # cut the GitHub Release
id-token: write # sign the npm provenance attestation
steps:
- uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"== workflow excerpt =="
sed -n '1,110p' .github/workflows/release.yml
echoecho"== checkout occurrences =="
rg -n "actions/checkout|persist-credentials|permissions:|contents:" .github/workflows/release.yml

Repository: vib795/agent-memory

Length of output: 3213


🌐 Web query:

actions/checkout v4 action.yml persist-credentials default true

💡 Result:

In the actions/checkout v4 action, the persist-credentials input has a default value of true [1][2][3]. When this setting is enabled (the default), the action configures the repository's local git configuration to include the authentication token or SSH key used for the checkout [2][4]. This allows subsequent git commands executed within the runner to be authenticated automatically [2][4]. The action removes this token during the post-job cleanup phase [2][4]. If you wish to prevent the action from adding these credentials to the local git configuration, you must explicitly set persist-credentials to false in your workflow file [2][4][5]: - uses: actions/checkout@v4 with: persist-credentials: false Disabling this setting is often recommended if you are concerned about credential exposure (for example, if you archive and upload the repository as a workflow artifact) [5].

Citations:


Disable checkout credential persistence in the publish job.

actions/checkout@v4 leaves persist-credentials enabled by default, so the write-capable checkout token remains available to later commands in this job. Set persist-credentials: false; gh release create already receives a token explicitly through GH_TOKEN.

Suggested change
 - uses: actions/checkout@v4
+ with:+ persist-credentials: false
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.29.0)

[warning] 27-27: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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/release.yml at line 27, Update the actions/checkout@v4
step in the publish job to set persist-credentials to false, while preserving
the explicit GH_TOKEN used by gh release create.

Sources: MCP tools, Linters/SAST tools

Comment on lines +51 to +60
- name: Version must not already be published
run: |
set -euo pipefail
name=$(node -p "require('./package.json').name")
ver=$(node -p "require('./package.json').version")
if npm view "$name@$ver" version >/dev/null 2>&1; then
echo "::error::$name@$ver is already on the registry"
exit 1
fi
echo "$name@$ver is unpublished; proceeding"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"## workflow excerpt"
nl -ba .github/workflows/release.yml | sed -n '1,120p'echoecho"## node/npm usage in workflow"
grep -nE 'NODE_AUTH_TOKEN|npm|setup-node|package-lock.json|package\.json|registry' .github/workflows/release.yml ||trueechoecho"## package registry/auth hints"
sed -n '1,220p' package.json ||true
[ -f package-lock.json ] && sed -n '1,80p' package-lock.json ||true

Repository: vib795/agent-memory

Length of output: 217


🌐 Web query:

npm view command exit code 404 response npm 404 error exit code documentation

💡 Result:

When the npm CLI encounters an E404 error—most commonly when a requested package or version cannot be found in the registry—it typically exits with a non-zero exit code (specifically 1) [1][2][3]. Key details regarding npm view and E404 behavior include: 1. Exit Code: When npm view fails to find a package or a specific version, it reports an E404 error and terminates with a non-zero exit code (typically 1) [1][2][3]. This ensures that automated scripts and CI/CD pipelines can detect the failure [1][2]. 2. Error Context: The E404 error is explicitly logged to stderr, detailing that the requested resource is not available in the registry [2][3][4]. 3. Notable Edge Cases: There have been documented instances where npm commands may exit with code 0 despite a failure to find specific tags (such as npm view package@latest when the tag itself is missing), which has been a subject of bug reports [1]. 4. General Error Handling: The npm CLI determines exit codes based on error codes (like E404) or defaults to 1 for general failures [5]. If you are encountering this in an automated environment, you should rely on the non-zero exit code to signal that the lookup was unsuccessful, rather than relying solely on the presence or absence of output to stdout [1][2].

Citations:


🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"## release workflow excerpt"
awk '{printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml | sed -n '1,130p'echoecho"## auth/npm related lines"
awk '{if (/NODE_AUTH_TOKEN|npm|setup-node|registry|package-lock|package\.json/) printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml
echoecho"## package registry/auth hints"
awk '{printf "%6d\t%s\n", NR, $0}' package.json | sed -n '1,220p'
[ -f package-lock.json ] && awk '{printf "%6d\t%s\n", NR, $0}' package-lock.json | sed -n '1,80p'

Repository: vib795/agent-memory

Length of output: 6378


🌐 Web query:

GitHub Actions setup-node NODE_AUTH_TOKEN npm view npm publish publishConfig registry-url scoped package

💡 Result:

To publish a scoped package to a specific registry using GitHub Actions and the setup-node action, you must correctly configure both the authentication environment and the registry mapping [1][2]. The setup-node action automates the creation of an.npmrc file that configures your registry and authentication [1][3]. Workflow Configuration 1. Use the setup-node action to define the target registry and the package scope [4][1]. 2. Provide an authentication token via the NODE_AUTH_TOKEN environment variable [1]. Example: - uses: actions/setup-node@v4 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org/' # Or your private registry URL scope: '@your-scope' - run: npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} Key Components - registry-url: This input instructs setup-node to write the registry URL to a project-level.npmrc file [4][3]. - scope: When provided, setup-node configures the.npmrc to associate this scope with the specified registry [3][5]. If not provided, it may default to the repository owner when using the GitHub Packages registry [4][2]. - NODE_AUTH_TOKEN: This environment variable is required by npm to authenticate requests [1]. The setup-node action automatically injects this token into the generated.npmrc [1][3]. Handling publishConfig If you need to ensure a package is always published to a specific registry regardless of local or global.npmrc settings, you can define it in your package.json [6]: { "publishConfig": { "@your-scope:registry": "https://registry.npmjs.org/" } } This configuration is particularly useful for scoped packages to avoid conflicts with default registry settings [7][8]. When using this method, ensure your registry credentials are still properly configured in the environment (e.g., via setup-node) [1]. Important Note: GitHub Packages (GPR) exclusively supports scoped packages (e.g., @owner/package-name) [5][9]. Ensure your package name in package.json adheres to this format if you are targeting GPR [5].

Citations:


🌐 Web query:

npm cli npm view private package 404 E404 non-zero exit code npm 404

💡 Result:

When you receive an E404 error with a non-zero exit code while running npm view on a private package, it generally indicates that the npm CLI could not find the package manifest at the specified or default registry [1][2]. This error typically occurs for the following reasons: 1. Lack of Authentication: If the package is private (e.g., restricted access) and you are not authenticated, the registry will return a 404 (Not Found) instead of a 403 (Forbidden) to prevent leaking the existence of private packages to unauthenticated users [3]. Ensure you are logged in (npm login) or have the correct authentication token (e.g., NODE_AUTH_TOKEN) configured for your environment [3]. 2. Incorrect Registry Configuration: npm might be looking at the public registry (registry.npmjs.org) instead of your private registry [4][5]. Check your.npmrc file to ensure your scope is correctly mapped to the intended private registry URL (e.g., @mycompany:registry=https://npm.pkg.github.com/) [5][2]. 3. Workspace/Bulk Operations: If you are running npm view with workspace flags (-ws), the command may fail and exit if it encounters a 404 for any individual workspace, including private ones that have not yet been published or are inaccessible [1][6]. Recent versions of the npm CLI have introduced improvements to handle these workspace-related 404 errors more gracefully [1]. 4. Package or Tag Absence: The package itself, or the specific version/tag you are querying, may genuinely not exist in the targeted registry [7][2]. To debug, you can run the command with increased verbosity to see exactly which registry and URL the CLI is attempting to access: npm view -dddd [5][2] This will help you verify if the CLI is resolving to the registry you expect and if the authentication headers are being included in the request [5][2].

Citations:


🌐 Web query:

npm view npm view package version output empty stderr exit code 0

💡 Result:

When you run the npm view command and it returns an empty output with an exit code of 0, it typically indicates that the command successfully executed but could not find the specific package, version, or tag you requested [1][2][3]. Historical context and behavior: - Legacy Behavior: In older versions of the npm CLI, npm view would frequently return an empty string and a success exit code (0) when a requested version or tag did not exist in the registry [4][5][6]. This was often used by automated scripts to verify if a package was missing [4][5]. - Recent Changes: Newer versions of the npm CLI have been updated to treat these cases as errors, generally returning an E404 error code and a non-zero exit code [4][7][6]. If you are encountering an empty output with a zero exit code, you are likely using an older version of npm or interacting with a specific registry configuration that causes this behavior [2][3][6]. - Underlying Cause: The primary cause is often that the package does not have a version tagged as "latest" (which is the default tag if none is specified), or the specific version/tag requested does not exist on the target registry [1][2][4]. Recommendations: - Check your npm version: Run npm -v to see if you are using an older version. Upgrading may provide more consistent error reporting [6]. - Verify the registry: If you are using a private registry (like Nexus or GitHub Packages), ensure it is configured correctly, as some third-party registries may not handle metadata requests in the exact way the npm CLI expects [1][2][3]. - Handle empty output in scripts: If you must rely on existing behavior, ensure your scripts are designed to handle both empty output and potential error states, especially as newer versions of npm are moving toward stricter E404 reporting [4][5].

Citations:


Fail closed when checking npm publication state.

The current check treats every failed npm view result as “unpublished”, including auth failures, registry errors, and network failures. NODE_AUTH_TOKEN is only provided during npm publish, so npm view runs as an anonymous public lookup and cannot distinguish an unpublished version from a private package or transient failure. Provide the token on this step and abort unless the lookup is confirmed absent.

🤖 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/release.yml around lines 51 - 60, Update the “Version must
not already be published” step to provide NODE_AUTH_TOKEN to the npm view
lookup, distinguish a confirmed not-found result from authentication, registry,
or network errors, and fail the workflow for every result except confirmed
absence; retain the existing error and success messages for published and
unpublished versions.

Source: MCP tools

Comment on lines +65 to +78
- name: Publish
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Cut the GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
gh release create "$GITHUB_REF_NAME" \
--title "$GITHUB_REF_NAME" \
--generate-notes \
--verify-tag

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
echo"== workflow excerpt =="if [ -f .github/workflows/release.yml ];then
sed -n '1,120p' .github/workflows/release.yml | cat -n
elseecho"missing .github/workflows/release.yml"fiecho"== release workflow search =="
rg -n "npm publish|gh release create|verify-tag|package.json|RELEASE|GITHUB_REF_NAME|GH_TOKEN|NPM_TOKEN|version" .github/workflows/release.yml .github/workflows 2>/dev/null ||trueecho"== package manifests =="forfin package.json pnpm-lock.yaml package-lock.json yarn.lock;doif [ -f"$f" ];thenecho"--- $f ---"
rg -n '"version"|"name"|engines|private|publishConfig|workspaces|npm'"$f" -m 50 ||truefidone

Repository: vib795/agent-memory

Length of output: 7244


Make npm publication and GitHub Release creation recoverable.

The workflow writes npm and GitHub independently. If npm publish succeeds but gh release create fails, rerunning the workflow skips the Release step after npm view "$name@$ver" succeeds. Add an idempotent recovery path that lets a rerun publish-only failures be retried and skip a confirmed existing package version when restoring only the missing GitHub Release.

🤖 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/release.yml around lines 65 - 78, Make the Publish and Cut
the GitHub Release steps independently idempotent: retry npm publication when
the package version is absent, but skip it only after confirming that exact
version already exists; separately check whether the GitHub release for
GITHUB_REF_NAME exists and create it when missing, so reruns can restore only
the release without being blocked by npm view.

@vib795vib795 mentioned this pull request Aug 8, 2026
vib795 added a commit that referenced this pull request Aug 8, 2026
No functional change. This exercises the tag-triggered publish path added in #5
end to end: matrix gate, version guards, provenance signing, GitHub Release.
A release pipeline that has never run is not a release pipeline, and a patch
with nothing in it is the cheapest way to find that out.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@vib795