Skip to content

ci(releases): add recoverable releases, lighten dev ci load, better p… - #531

Merged
Ryan-Millard merged 3 commits into
devfrom
ci/fix-releases
Jul 30, 2026
Merged

ci(releases): add recoverable releases, lighten dev ci load, better p…#531
Ryan-Millard merged 3 commits into
devfrom
ci/fix-releases

Conversation

@Ryan-Millard

@Ryan-Millard Ryan-Millard commented Jul 26, 2026

Copy link
Copy Markdown
Owner

@coderabbitai I don't have time to update the body of this PR. Please will you do it for me.

  • Force-publish workflow_dispatch mode enables recovering from partial failures. A resolve step overrides rp outputs so "Re-run failed jobs" can finish the publish for an existing tag without re-bumping versions.

  • Full Python wheel matrix only on main/releases; dev builds one smoke wheel.

  • Propagation PRs touch a real file so release-please attributes the commit. Empty commits were likely never mapped to components, so no release triggered.

  • Publish ordering (GH release before PyPI, npm last) allows safe retries.

  • cleanup-drafts job deletes stale dry-run drafts after 7 days.

  • Unpinned actions (upload-artifact, download-artifact, setup-python) pinned; persist-credentials: false added on checkouts.

…ropagation

- Force-publish workflow_dispatch mode enables recovering from partial failures.
  A resolve step overrides rp outputs so "Re-run failed jobs" can finish the
  publish for an existing tag without re-bumping versions.

- Full Python wheel matrix only on main/releases; dev builds one smoke wheel.

- Propagation PRs touch a real file so release-please attributes the commit.
  Empty commits were likely never mapped to components, so no release triggered.

- Publish ordering (GH release before PyPI, npm last) allows safe retries.

- cleanup-drafts job deletes stale dry-run drafts after 7 days.

- Unpinned actions (upload-artifact, download-artifact, setup-python) pinned;
  persist-credentials: false added on checkouts.
@github-actions github-actions Bot added the ci label Jul 26, 2026
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Ryan-Millard, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 34 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8b97d811-c3b8-4857-a1ca-59b9793c770b

📥 Commits

Reviewing files that changed from the base of the PR and between 24b6004 and 9e309ef.

📒 Files selected for processing (1)
  • .github/workflows/release.yml
  • Added force-publish recovery mode to resume publishing for an existing release tag without re-bumping versions.
  • Reduced CI workload by limiting the full Python wheel matrix to main/releases and using a smoke wheel elsewhere.
  • Ordered publishing as GitHub release → PyPI → npm to improve retry/recovery behavior.
  • Improved release-please output resolution and gated recovery actions to prevent re-processing already-updated manifests.
  • Updated propagation PRs to commit real component version marker files for correct attribution.
  • Added cleanup to garbage-collect stale draft GitHub releases older than seven days.
  • Pinned previously unpinned GitHub Actions and disabled persist-credentials on JS/Python checkouts.
Author Lines added Lines removed
Unavailable from provided context 202 39

Walkthrough

The release workflow adds forced component republishing, resolves effective release outputs, adjusts Python artifact builds and publishing paths, creates marker-based propagation PRs, pins actions, and deletes stale draft releases.

Changes

Release workflow

Layer / File(s) Summary
Release output resolution
.github/workflows/release.yml
Manual recovery inputs and effective per-component release outputs support republishing from an existing tag.
Artifact build and publishing
.github/workflows/release.yml
Python build matrices and publishing jobs now distinguish real releases from TestPyPI draft publishing; checkout and artifact actions are updated.
Propagation markers
.github/workflows/release.yml
Propagation PRs commit .core-version or .bindings-c-version marker files and use heredoc PR bodies.
Draft release cleanup
.github/workflows/release.yml
A cleanup job deletes matching draft releases older than seven days.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant WorkflowDispatch
  participant ResolveEffectiveOutputs
  participant PythonBuild
  participant publish-py
  participant publish-py-test
  WorkflowDispatch->>ResolveEffectiveOutputs: provide forced component and tag
  ResolveEffectiveOutputs->>PythonBuild: emit effective py_created, py_tag, and py_version
  PythonBuild->>publish-py: upload artifacts for created Python releases
  PythonBuild->>publish-py-test: upload artifacts for non-created releases
  publish-py->>publish-py: publish to PyPI
  publish-py-test->>publish-py-test: publish to TestPyPI and create draft release
Loading

Possibly related PRs

Suggested labels: github_actions, c/cpp, core, js/ts, python

Poem

A rabbit packed tags in a release-day sack,
Sent wheels to PyPI and TestPyPI back.
Marker files hopped through each branch,
Old drafts vanished in cleanup’s dance.
“Publish with care!” said the bunny in flight.

🚥 Pre-merge checks | ✅ 8
✅ Passed checks (8 passed)
Check name Status Explanation
Title check ✅ Passed The title mentions recoverable releases and reduced CI load, which matches the workflow changes despite being truncated.
Description check ✅ Passed The description accurately summarizes the release recovery, CI load reduction, propagation, publishing, and cleanup changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No Ai Slop Pr Description ✅ Passed The PR description names concrete workflow changes and motivations; it isn’t generic boilerplate.
No Strangely-Named Root Markdown Files ✅ Passed The PR only changes .github/workflows/release.yml; no root-level markdown files were added.
Coderabbit Config Needs Update ✅ Passed Only .github/workflows/release.yml changed; .coderabbit.yaml already covers workflows, and no new language/config file or extension was introduced.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/fix-releases
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch ci/fix-releases

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.

@coderabbitai coderabbitai Bot added c/cpp core github_actions Pull requests that update GitHub Actions code js/ts python changes to python bindings or python code labels Jul 26, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 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 444-468: Make the propagation sequence idempotent in
.github/workflows/release.yml lines 444-468 and 492-513: guard marker updates
and commits so unchanged versions produce no commit failure, push branches with
--force-with-lease, and query for an existing open PR for $BRANCH before
invoking gh pr create. Apply the same behavior at both sites, preferably by
reusing a shared script or composite action if practical.
- Around line 110-116: Update the “Debug resolved outputs” step so the fallback
version is passed through the step’s env block using a dedicated variable, then
reference that environment variable in the run script instead of interpolating
steps.fallback_version.outputs.fallback_version directly. Keep the existing
debug output unchanged.
- Around line 92-101: Add validation in the forced-release branch around
FORCE_COMPONENT and FORCE_TAG to require the tag’s component prefix, using the
configured component names and tag separator (for example,
`${FORCE_COMPONENT}-v`). Reject mismatches with an error and exit before setting
created, tag, or version; preserve the existing missing-tag validation and
valid-tag parsing.
- Around line 372-403: Update the publish-py-test job to avoid attempting
TestPyPI OIDC uploads unless the required trusted publisher is configured;
otherwise make the dry run local-only by removing or bypassing the TestPyPI
publish step while retaining artifact validation. Complete the truncated comment
above publish-py-test so it accurately describes the dry-run behavior and
TestPyPI target.
- Around line 531-536: Update the draft-release filter in the gh api query to
use the release’s own draft creation timestamp rather than created_at,
preserving the existing 7-day cutoff, draft, and tag-name conditions. If no
draft-specific timestamp is available, document the known timestamp skew
explicitly instead of silently treating created_at as draft age.
🪄 Autofix (Beta)

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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: af9f60dd-dab8-42df-895b-8f8af5c4936e

📥 Commits

Reviewing files that changed from the base of the PR and between 1828f68 and 38cee68.

📒 Files selected for processing (1)
  • .github/workflows/release.yml
📜 Review details
⚠️ CI failures not shown inline (2)

GitHub Actions: CI / 3_Set Docker image.txt: ci(releases): add recoverable releases, lighten dev ci load, better p…

Conclusion: failure

View job details

##[group]Run BASE_IMAGE="ghcr.io/ryan-millard/img2num-dev"
 �[36;1mBASE_IMAGE="ghcr.io/ryan-millard/img2num-dev"�[0m
 �[36;1m�[0m
 �[36;1mMAIN_IMAGE="${BASE_IMAGE}:main"�[0m
 �[36;1mDEV_IMAGE="${BASE_IMAGE}:dev"�[0m
 �[36;1m�[0m
 �[36;1mPR_NUMBER="531"�[0m
 �[36;1m�[0m
 �[36;1m# Try PR image first (highest priority)�[0m
 �[36;1mif [[ -n "$PR_NUMBER" ]]; then�[0m
 �[36;1m  PR_TAG="pr-${PR_NUMBER}"�[0m
 �[36;1m  GHCR_IMAGE="ghcr.io/ryan-millard/img2num-dev:${PR_TAG}"�[0m
 �[36;1m  DH_IMAGE="ryan-millard/img2num-dev:${PR_TAG}"�[0m
 �[36;1m�[0m
 �[36;1m  GHCR_IMAGE_EXISTS=$(gh api \�[0m
 �[36;1m    -H "Accept: application/vnd.github+json" \�[0m
 �[36;1m    /users/ryan-millard/packages/container/img2num-dev/versions \�[0m
 �[36;1m    --jq "any(.metadata.container.tags[]? == \"${PR_TAG}\")")�[0m
 �[36;1m�[0m
 �[36;1m  DH_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \�[0m
 �[36;1m    --connect-timeout 2 --max-time 5 \�[0m
 �[36;1m    "https://registry.hub.docker.com/v2/repositories/ryan-millard/img2num-dev/tags/${PR_TAG}/")�[0m
 �[36;1melse�[0m
 �[36;1m  GHCR_IMAGE_EXISTS="false"�[0m
 �[36;1m  DH_STATUS="404"�[0m
 �[36;1mfi�[0m
 �[36;1m�[0m
 �[36;1mif [[ "$GHCR_IMAGE_EXISTS" == "true" ]]; then�[0m
 �[36;1m  echo "image=${GHCR_IMAGE}" >> $GITHUB_OUTPUT�[0m
 �[36;1m  echo "image=${GHCR_IMAGE}"�[0m
 �[36;1melif [[ "$DH_STATUS" == "200" ]]; then�[0m
 �[36;1m  echo "image=${DH_IMAGE}" >> $GITHUB_OUTPUT�[0m
 �[36;1m  echo "image=${DH_IMAGE}"�[0m
 �[36;1melse�[0m
 �[36;1m  # Fallback: main/dev (never PR ref names)�[0m
 �[36;1m  BRANCH="531/merge"�[0m
 �[36;1m�[0m
 �[36;1m  case "$BRANCH" in�[0m
 �[36;1m    main)�[0m
 �[36;1m      IMAGE="$MAIN_IMAGE"�[0m
 �[36;1m      ;;�[0m
 �[36;1m    dev|*)�[0m
 �[36;1m      IMAGE="$DEV_IMAGE"�[0m
 �[36;1m      ;;�[0m
 �[36;1m  esac�[0m
 �[36;1m�[0m
 �[36;1m  echo "image=${IMAGE}" >> $GITHUB_OUTPUT�[0m
 �[36;1m  echo "Using fallback image: ${IMAGE}"�[0m
 �[36;1mfi�[0m
 shell: /usr/bin/bash -e {0}
 env:
   GH_***REDACTED***
 ##[endgroup]
 ...

GitHub Actions: CI / Set Docker image: ci(releases): add recoverable releases, lighten dev ci load, better p…

Conclusion: failure

View job details

##[group]Run BASE_IMAGE="ghcr.io/ryan-millard/img2num-dev"
 �[36;1mBASE_IMAGE="ghcr.io/ryan-millard/img2num-dev"�[0m
 �[36;1m�[0m
 �[36;1mMAIN_IMAGE="${BASE_IMAGE}:main"�[0m
 �[36;1mDEV_IMAGE="${BASE_IMAGE}:dev"�[0m
 �[36;1m�[0m
 �[36;1mPR_NUMBER="531"�[0m
 �[36;1m�[0m
 �[36;1m# Try PR image first (highest priority)�[0m
 �[36;1mif [[ -n "$PR_NUMBER" ]]; then�[0m
 �[36;1m  PR_TAG="pr-${PR_NUMBER}"�[0m
 �[36;1m  GHCR_IMAGE="ghcr.io/ryan-millard/img2num-dev:${PR_TAG}"�[0m
 �[36;1m  DH_IMAGE="ryan-millard/img2num-dev:${PR_TAG}"�[0m
 �[36;1m�[0m
 �[36;1m  GHCR_IMAGE_EXISTS=$(gh api \�[0m
 �[36;1m    -H "Accept: application/vnd.github+json" \�[0m
 �[36;1m    /users/ryan-millard/packages/container/img2num-dev/versions \�[0m
 �[36;1m    --jq "any(.metadata.container.tags[]? == \"${PR_TAG}\")")�[0m
 �[36;1m�[0m
 �[36;1m  DH_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \�[0m
 �[36;1m    --connect-timeout 2 --max-time 5 \�[0m
 �[36;1m    "https://registry.hub.docker.com/v2/repositories/ryan-millard/img2num-dev/tags/${PR_TAG}/")�[0m
 �[36;1melse�[0m
 �[36;1m  GHCR_IMAGE_EXISTS="false"�[0m
 �[36;1m  DH_STATUS="404"�[0m
 �[36;1mfi�[0m
 �[36;1m�[0m
 �[36;1mif [[ "$GHCR_IMAGE_EXISTS" == "true" ]]; then�[0m
 �[36;1m  echo "image=${GHCR_IMAGE}" >> $GITHUB_OUTPUT�[0m
 �[36;1m  echo "image=${GHCR_IMAGE}"�[0m
 �[36;1melif [[ "$DH_STATUS" == "200" ]]; then�[0m
 �[36;1m  echo "image=${DH_IMAGE}" >> $GITHUB_OUTPUT�[0m
 �[36;1m  echo "image=${DH_IMAGE}"�[0m
 �[36;1melse�[0m
 �[36;1m  # Fallback: main/dev (never PR ref names)�[0m
 �[36;1m  BRANCH="531/merge"�[0m
 �[36;1m�[0m
 �[36;1m  case "$BRANCH" in�[0m
 �[36;1m    main)�[0m
 �[36;1m      IMAGE="$MAIN_IMAGE"�[0m
 �[36;1m      ;;�[0m
 �[36;1m    dev|*)�[0m
 �[36;1m      IMAGE="$DEV_IMAGE"�[0m
 �[36;1m      ;;�[0m
 �[36;1m  esac�[0m
 �[36;1m�[0m
 �[36;1m  echo "image=${IMAGE}" >> $GITHUB_OUTPUT�[0m
 �[36;1m  echo "Using fallback image: ${IMAGE}"�[0m
 �[36;1mfi�[0m
 shell: /usr/bin/bash -e {0}
 env:
   GH_***REDACTED***
 ##[endgroup]
 ...
🧰 Additional context used
📓 Path-based instructions (1)
.github/workflows/**

⚙️ CodeRabbit configuration file

.github/workflows/**: GitHub Actions workflows. Review for:

  • SHA-pinned action versions for third-party actions (security best practice).
  • Secrets accessed only via ${{ secrets.* }} — never hardcoded.
  • Least-privilege permissions on each job/workflow.
  • Correct job dependency ordering (needs:) and if/condition logic.

Files:

  • .github/workflows/release.yml
🧠 Learnings (2)
📚 Learning: 2026-05-01T22:50:11.527Z
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 339
File: release-please-config.json:18-47
Timestamp: 2026-05-01T22:50:11.527Z
Learning: In this repo, release-please-action v4 preserves '/' verbatim in slash-containing path-based package keys when emitting GitHub Actions output names (e.g., `bindings/c--release_created`). When referencing these step outputs in `job.outputs` (and other expressions), use bracket notation with the exact output name: `${{ steps.release.outputs['bindings/c--release_created'] }}` rather than dot notation. If needed, map the complex step output to a clean job-level output alias so downstream jobs can use dot notation via that alias.

Applied to files:

  • .github/workflows/release.yml
📚 Learning: 2026-05-19T17:30:09.565Z
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 375
File: .github/workflows/cmake-build.yml:86-88
Timestamp: 2026-05-19T17:30:09.565Z
Learning: In Ryan-Millard/Img2Num CI/workflow YAMLs, any `uv sync` command used for the Python package build must include `--no-build-isolation` (do not remove it). If you need deterministic dependency installs for CI, you may add `--frozen` alongside it (e.g., `uv sync --frozen --no-build-isolation`), and it should not conflict with the repo’s build setup.

Applied to files:

  • .github/workflows/release.yml
🪛 zizmor (1.26.1)
.github/workflows/release.yml

[info] 116-116: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[warning] 344-344: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment

(undocumented-permissions)


[warning] 378-378: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment

(undocumented-permissions)


[info] 339-339: workflow or action definition without a name (anonymous-definition): this job

(anonymous-definition)


[info] 373-373: workflow or action definition without a name (anonymous-definition): this job

(anonymous-definition)


[info] 363-363: action functionality is already included by the runner (superfluous-actions): use gh release in a script step

(superfluous-actions)


[info] 393-393: action functionality is already included by the runner (superfluous-actions): use gh release in a script step

(superfluous-actions)


[warning] 523-523: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment

(undocumented-permissions)


[info] 518-518: workflow or action definition without a name (anonymous-definition): this job

(anonymous-definition)

🔇 Additional comments (6)
.github/workflows/release.yml (6)

7-16: LGTM!


29-53: LGTM!


196-196: LGTM!

Also applies to: 215-215, 262-265


279-309: LGTM!


322-336: LGTM!


338-370: LGTM!

Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.github/workflows/release.yml (2)

103-117: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Reject malformed forced tags before writing job outputs.

The current prefix check also accepts strings like packages-py-v\njs_created=evil\njs_tag=x, and those newlines are written directly to $GITHUB_OUTPUT, creating extra release outputs and causing downstream release/tag/version values to come from the injected output lines. Reject CR/LF and use the exact component version pattern before emitting created, tag, and version.

🤖 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 103 - 117, Validate FORCE_TAG
before assigning tag/version or writing outputs: reject any CR/LF characters and
require the exact expected component tag/version pattern, not merely the
expected prefix. Keep the existing mismatch error path, and only emit the
created, tag, and version outputs after the forced tag passes both validations.

369-381: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Make forced Python publishing retry-safe.

Recovery mode can set py_created=true with the forced tag, so the production Python publish job also re-runs without skip-existing. If a previous run already uploaded any distribution file, retrying will fail due to the naming collision and recovery cannot use “Re-run failed jobs” for this job. Add skip-existing only for forced recovery, or implement per-file reconciliation while keeping normal releases fail-loud.

🤖 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 369 - 381, Update the production
Python publish step using pypa/gh-action-pypi-publish so forced recovery runs
are retry-safe by enabling skip-existing only when the workflow indicates the
forced recovery mode. Keep skip-existing disabled for normal releases so
duplicate uploads still fail loudly, and preserve the existing package directory
and release asset behavior.
🤖 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.

Outside diff comments:
In @.github/workflows/release.yml:
- Around line 103-117: Validate FORCE_TAG before assigning tag/version or
writing outputs: reject any CR/LF characters and require the exact expected
component tag/version pattern, not merely the expected prefix. Keep the existing
mismatch error path, and only emit the created, tag, and version outputs after
the forced tag passes both validations.
- Around line 369-381: Update the production Python publish step using
pypa/gh-action-pypi-publish so forced recovery runs are retry-safe by enabling
skip-existing only when the workflow indicates the forced recovery mode. Keep
skip-existing disabled for normal releases so duplicate uploads still fail
loudly, and preserve the existing package directory and release asset behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 285d3a97-c591-417f-a213-94aac48780e8

📥 Commits

Reviewing files that changed from the base of the PR and between 38cee68 and 24b6004.

📒 Files selected for processing (1)
  • .github/workflows/release.yml
📜 Review details
⏰ Context from checks skipped due to timeout. (4)
  • GitHub Check: Build C/C++ / Build WASM (bindings/js)
  • GitHub Check: Build C/C++ / Build C & C++
  • GitHub Check: Build C/C++ / Build Python
  • GitHub Check: Lint & Validate Code
🧰 Additional context used
📓 Path-based instructions (1)
.github/workflows/**

⚙️ CodeRabbit configuration file

.github/workflows/**: GitHub Actions workflows. Review for:

  • SHA-pinned action versions for third-party actions (security best practice).
  • Secrets accessed only via ${{ secrets.* }} — never hardcoded.
  • Least-privilege permissions on each job/workflow.
  • Correct job dependency ordering (needs:) and if/condition logic.

Files:

  • .github/workflows/release.yml
🧠 Learnings (2)
📚 Learning: 2026-05-01T22:50:11.527Z
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 339
File: release-please-config.json:18-47
Timestamp: 2026-05-01T22:50:11.527Z
Learning: In this repo, release-please-action v4 preserves '/' verbatim in slash-containing path-based package keys when emitting GitHub Actions output names (e.g., `bindings/c--release_created`). When referencing these step outputs in `job.outputs` (and other expressions), use bracket notation with the exact output name: `${{ steps.release.outputs['bindings/c--release_created'] }}` rather than dot notation. If needed, map the complex step output to a clean job-level output alias so downstream jobs can use dot notation via that alias.

Applied to files:

  • .github/workflows/release.yml
📚 Learning: 2026-05-19T17:30:09.565Z
Learnt from: Ryan-Millard
Repo: Ryan-Millard/Img2Num PR: 375
File: .github/workflows/cmake-build.yml:86-88
Timestamp: 2026-05-19T17:30:09.565Z
Learning: In Ryan-Millard/Img2Num CI/workflow YAMLs, any `uv sync` command used for the Python package build must include `--no-build-isolation` (do not remove it). If you need deterministic dependency installs for CI, you may add `--frozen` alongside it (e.g., `uv sync --frozen --no-build-isolation`), and it should not conflict with the repo’s build setup.

Applied to files:

  • .github/workflows/release.yml
🔇 Additional comments (4)
.github/workflows/release.yml (4)

126-126: Duplicate: keep fallback_version out of shell interpolation.

Line 126 still expands a value derived from GITHUB_REF_NAME directly into the run script. Pass it through env and echo the environment variable instead; the prior injection finding remains unresolved.


382-413: Duplicate: verify TestPyPI trusted publishing configuration.

This path still requests OIDC publishing and uploads to TestPyPI. Confirm the repository/workflow is configured as a TestPyPI trusted publisher; otherwise non-release runs will fail after creating the draft release.


454-478: Duplicate: propagation remains non-idempotent.

Retries can still fail on an unchanged marker commit or an already-existing pull request. Guard no-op commits and existing PRs before pushing or invoking gh pr create.

Also applies to: 502-523


7-16: LGTM!

Also applies to: 23-54, 61-102, 120-125, 299-316, 343-368

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 30, 2026
@Ryan-Millard
Ryan-Millard merged commit dcb1040 into dev Jul 30, 2026
14 checks passed
@Ryan-Millard
Ryan-Millard deleted the ci/fix-releases branch July 30, 2026 12:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c/cpp ci core github_actions Pull requests that update GitHub Actions code js/ts python changes to python bindings or python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant