Skip to content

Release: npm publish should not fail when registry propagation-check times out - #273

Closed
google-labs-jules[bot] wants to merge 1 commit into
mainfrom
jules-876042609893764583-1e43b4ee
Closed

google-labs-jules[bot] wants to merge 1 commit into
mainfrom
jules-876042609893764583-1e43b4ee

Conversation

@google-labs-jules

Copy link
Copy Markdown
Contributor

Redesigned verify_integrity in .mise/lib/npm-publish-if-missing.sh so that registry propagation timeouts emit a warning (and GitHub Actions ::warning:: annotation) instead of causing release failure, ensuring remaining packages and downstream release steps complete. Updated .mise/lib/test-npm-release-handoff.sh to verify propagation timeout behavior. (Ref #132, #266)

Fixes #272


PR created automatically by Jules for task 876042609893764583 started by @rabestro

Downgrade npm integrity verification timeouts in verify_integrity
from hard failures (exit 1) to warnings (return 0). This prevents
unbounded npmjs.org CDN propagation delays from aborting the release
pipeline after a successful npm publish.

Ref #132, #266
@google-labs-jules

Copy link
Copy Markdown
Contributor Author

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai

coderabbitai Bot commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository: fortemate/dicechess-engine/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: aff3c614-f68f-4058-9942-f4c472016e50

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@hacktron-app hacktron-app Bot 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.

1 issue found across 1 file

Severity Count
MEDIUM 1

View full scan results

Comment on lines +105 to +110
echo "warning: could not read the published integrity for $PACKAGE_SPEC from $REGISTRY_URL after $attempt attempts" >&2
if [[ -n "${GITHUB_ACTIONS:-}" ]]; then
echo "::warning::could not read the published integrity for $PACKAGE_SPEC from $REGISTRY_URL after $attempt attempts"
fi
sed 's/^/ /' "$VIEW_ERROR" >&2
return 1
return 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

MEDIUM Integrity verification fails open when registry metadata cannot be read

When --expected-integrity is supplied, verify_integrity only returns success after comparing a registry-provided dist.integrity value with the expected SHA-512 digest. However, after all npm view ... dist.integrity attempts fail or return no digest, the final branch emits a warning and returns 0 instead of failing. Because callers invoke this function before declaring an existing package verified, after a successful publish, and on the concurrent-publication path, CI can treat a package as integrity-verified without obtaining any registry digest. The release bundle publisher always supplies --expected-integrity from its manifest, and the workflows use it for both mirror verification and canonical npm publication, so registry metadata unavailability can bypass the intended digest-verification gate.

Steps to Reproduce
  1. Invoke .mise/lib/npm-publish-if-missing.sh with a valid package source, a registry URL, and --expected-integrity sha512-....
  2. Configure npm (or the registry path it contacts) so every npm view <package>@<version> dist.integrity request fails or returns an empty value; set NPM_VERIFY_MAX_ATTEMPTS=1 and NPM_VERIFY_SLEEP_SECONDS=0 to make the test immediate.
  3. Observe that verify_integrity prints the warning at .mise/lib/npm-publish-if-missing.sh:105-109 and returns success at line 110 without comparing a digest.
  4. Observe that the caller proceeds as successful through the existing-package, successful-publish, or concurrent-publication paths.
set -e
TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT
mkdir -p "$TMP/package" "$TMP/bin"
printf '{"name":"@example/pkg","version":"1.0.0"}\n' > "$TMP/package/package.json"
cat > "$TMP/bin/npm" <<'EOF'
#!/usr/bin/env bash
if [[ " $* " == *" dist.integrity "* ]]; then
  echo 'registry metadata unavailable' >&2
  exit 1
fi
if [[ " $* " == *" version "* ]]; then
  printf '1.0.0\n'
  exit 0
fi
exit 0
EOF
chmod +x "$TMP/bin/npm"
PATH="$TMP/bin:$PATH" NPM_VERIFY_MAX_ATTEMPTS=1 NPM_VERIFY_SLEEP_SECONDS=0 \
  bash ./dicechess-engine/.mise/lib/npm-publish-if-missing.sh \
  "$TMP/package" https://registry.example \
  --expected-integrity sha512-YWJj
# The command exits 0 and prints the timeout warning despite never receiving a digest.
Fix with AI

Open in Cursor Open in Claude

A security vulnerability was found by Hacktron.

File: .mise/lib/npm-publish-if-missing.sh
Lines: 105-110
Severity: medium

Vulnerability: Integrity verification fails open when registry metadata cannot be read

Description:
When `--expected-integrity` is supplied, `verify_integrity` only returns success after comparing a registry-provided `dist.integrity` value with the expected SHA-512 digest. However, after all `npm view ... dist.integrity` attempts fail or return no digest, the final branch emits a warning and returns `0` instead of failing. Because callers invoke this function before declaring an existing package verified, after a successful publish, and on the concurrent-publication path, CI can treat a package as integrity-verified without obtaining any registry digest. The release bundle publisher always supplies `--expected-integrity` from its manifest, and the workflows use it for both mirror verification and canonical npm publication, so registry metadata unavailability can bypass the intended digest-verification gate.

Proof of Concept:
**Steps to Reproduce**

1. Invoke `.mise/lib/npm-publish-if-missing.sh` with a valid package source, a registry URL, and `--expected-integrity sha512-...`.
2. Configure `npm` (or the registry path it contacts) so every `npm view <package>@<version> dist.integrity` request fails or returns an empty value; set `NPM_VERIFY_MAX_ATTEMPTS=1` and `NPM_VERIFY_SLEEP_SECONDS=0` to make the test immediate.
3. Observe that `verify_integrity` prints the warning at `.mise/lib/npm-publish-if-missing.sh:105-109` and returns success at line 110 without comparing a digest.
4. Observe that the caller proceeds as successful through the existing-package, successful-publish, or concurrent-publication paths.

```bash
set -e
TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT
mkdir -p "$TMP/package" "$TMP/bin"
printf '{"name":"@example/pkg","version":"1.0.0"}\n' > "$TMP/package/package.json"
cat > "$TMP/bin/npm" <<'EOF'
#!/usr/bin/env bash
if [[ " $* " == *" dist.integrity "* ]]; then
  echo 'registry metadata unavailable' >&2
  exit 1
fi
if [[ " $* " == *" version "* ]]; then
  printf '1.0.0\n'
  exit 0
fi
exit 0
EOF
chmod +x "$TMP/bin/npm"
PATH="$TMP/bin:$PATH" NPM_VERIFY_MAX_ATTEMPTS=1 NPM_VERIFY_SLEEP_SECONDS=0 \
  bash ./dicechess-engine/.mise/lib/npm-publish-if-missing.sh \
  "$TMP/package" https://registry.example \
  --expected-integrity sha512-YWJj
# The command exits 0 and prints the timeout warning despite never receiving a digest.
```

Affected Code:
    if [[ $attempt -ge $max_attempts ]]; then
      echo "warning: could not read the published integrity for $PACKAGE_SPEC from $REGISTRY_URL after $attempt attempts" >&2
      if [[ -n "${GITHUB_ACTIONS:-}" ]]; then
        echo "::warning::could not read the published integrity for $PACKAGE_SPEC from $REGISTRY_URL after $attempt attempts"
      fi
      sed 's/^/  /' "$VIEW_ERROR" >&2
      return 0
    fi

Acceptance criteria:
- Acceptance is defined by the **actual reported behavior**, not by tests passing.
- Reproduce the issue, or narrow the exact code path that produces it, *before* changing code. State what you confirmed.
- Fix the underlying cause. Mitigations that paper over the reported behavior do not count as a fix.
- Add a regression test that fails on the unpatched code and passes on the fix. If a regression test is genuinely impractical (e.g. race condition, infra-level issue), say so and explain why.
- Existing tests passing is **not** the bar. Do not declare done on tests-pass theatre.

Only change what is necessary to fix this vulnerability. Do not refactor adjacent code or modify unrelated files.

Triage: Reply !fp <reason> (false positive), !valid (confirmed), !accepted_risk <reason>, or !fixed (resolved). Any other reply is saved as a triage note.
Reason is optional but improves future scans — e.g. !fp internal endpoint, not user-facing.

View finding in Hacktron

@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to 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.

Release: npm publish should not fail when registry propagation-check times out

1 participant