Skip to content

ci: auto-publish every package when a release tag is cut#1014

Merged
thebentern merged 2 commits into
masterfrom
ci/auto-publish-on-tag
Jul 22, 2026
Merged

ci: auto-publish every package when a release tag is cut#1014
thebentern merged 2 commits into
masterfrom
ci/auto-publish-on-tag

Conversation

@jamesarich

@jamesarich jamesarich commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Problem

org.meshtastic:protobufs (the KMP artifact consumed by meshtastic-sdk and TAKPacket-SDK) is a release behind: Maven Central serves 2.7.25, but the repo has been tagged v2.7.26 since 2026-06-20. The npm package is correctly at 2.7.26.

Root cause: create_tag.yml creates the release tag with GITHUB_TOKEN. GitHub's recursion guard means a tag pushed by GITHUB_TOKEN does not fire the push: tags trigger on publish.yml / publish-kmp.yml. Those triggers are effectively dead — publishing has silently depended on a human remembering to workflow_dispatch each publisher after every release. For v2.7.26 the npm publish was hand-dispatched but the KMP one was missed, and nothing surfaced the gap.

Fix

  • workflow_call trigger added to publish.yml and publish-kmp.yml. Their version/dry_run resolution already reads inputs.*, so workflow_call populates the same inputs with no job changes.
  • create_tag.yml calls both publishers via uses: after cutting the tag (secrets: inherit, version passed through).
  • id-token: write granted at create_tag level — a reusable workflow can't exceed the caller's token scope, and publish.yml needs it for JSR OIDC / npm provenance.

Existing push: tags + workflow_dispatch triggers are preserved, so manual dispatch (and any future PAT-pushed tag) still works.

Notes for reviewers

  • All three workflows validated as YAML.
  • The 2.7.26 KMP artifact still needs a one-time manual publish to catch up — this PR only fixes future releases (handled separately; a 2.7.26 dry-run build was validated first).
  • Chose reusable-workflow (workflow_call) over gh workflow run dispatch deliberately: a GITHUB_TOKEN workflow_dispatch is subject to the same recursion guard and could silently no-op.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Release workflows can now directly publish JavaScript and Kotlin packages after version updates.
    • Added support for reusable publishing workflows with version and dry-run options.
    • Enabled OIDC-based authentication for downstream publishing.
  • Improvements

    • Publishing is now coordinated directly within the release process, improving reliability and avoiding trigger-related issues.

create_tag.yml creates the release tag with GITHUB_TOKEN, and GitHub's
recursion guard means a GITHUB_TOKEN-pushed tag does NOT fire the
`push: tags` trigger on publish.yml / publish-kmp.yml. Publishing has
therefore depended on someone manually dispatching each publish
workflow after every release — and when that is missed, an artifact
silently lags its own tag. Concretely: org.meshtastic:protobufs (the
KMP artifact) sat at 2.7.25 while v2.7.26 was tagged a month ago; the
npm package was hand-dispatched to 2.7.26 but the KMP one was not.

Wire the release flow directly instead of relying on the dead tag
trigger:

- Add a `workflow_call` trigger to publish.yml and publish-kmp.yml
  (their version/dry_run logic already reads `inputs.*`, so no job
  changes are needed — workflow_call populates the same inputs).
- create_tag.yml now calls both publishers via `uses:` after cutting
  the tag, passing the new version and `secrets: inherit`.
- Grant `id-token: write` at the create_tag level: a reusable workflow
  cannot exceed the caller's token scope, and publish.yml needs it for
  JSR OIDC / npm provenance.

The existing `push: tags` and `workflow_dispatch` triggers are kept, so
manual dispatch and any future PAT-pushed tags still work; the dead
push trigger simply never fires in the current flow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

Next review available in: 40 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: CHILL

Plan: Pro Plus

Run ID: e8402350-ebcb-45d8-82f6-8d8b3725fbd3

📥 Commits

Reviewing files that changed from the base of the PR and between 0d983b8 and e03a36c.

📒 Files selected for processing (1)
  • .github/workflows/create_tag.yml
📝 Walkthrough

Walkthrough

The release workflow now exposes the computed version, grants OIDC permissions, and directly invokes npm and KMP reusable publishing workflows. Both publishing workflows accept version and optional dry_run inputs through workflow_call.

Changes

Release Publishing

Layer / File(s) Summary
Reusable publish workflow contracts
.github/workflows/publish.yml, .github/workflows/publish-kmp.yml
Both workflows now support direct workflow_call invocation with required version and optional dry_run inputs.
Version propagation and direct publishing
.github/workflows/create_tag.yml
The release workflow exposes new_version, enables OIDC tokens, and invokes npm and KMP publishing with the computed version and inherited secrets.

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

Sequence Diagram(s)

sequenceDiagram
  participant create_tag.yml
  participant increment_version
  participant publish.yml
  participant publish-kmp.yml
  create_tag.yml->>increment_version: compute NEW_VERSION
  increment_version-->>create_tag.yml: expose new_version
  create_tag.yml->>publish.yml: invoke with version and inherited secrets
  create_tag.yml->>publish-kmp.yml: invoke with version and inherited secrets
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: automating package publishing when a release tag is cut.
Description check ✅ Passed The description is substantive and covers the problem, fix, and reviewer notes, though it doesn't follow the template verbatim.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/auto-publish-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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 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/create_tag.yml:
- Around line 88-94: Remove the existing Setup Buf and Push to schema registry
steps from the increment_version job in create_tag.yml, leaving Buf registry
publishing to the push-buf-registry job invoked through publish.yml. Preserve
the version increment and tag creation flow.
- Around line 3-9: Update the workflow-level permissions in the GitHub Actions
workflow to default to read access, then add job-level permissions to
increment_version for contents write and to each reusable publish caller job for
contents read and id-token write. Preserve the existing job dependencies and
workflow behavior while limiting write scopes to only the jobs that require
them.
🪄 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: CHILL

Plan: Pro Plus

Run ID: 2fc01f80-881e-486f-b348-d6526d606f24

📥 Commits

Reviewing files that changed from the base of the PR and between b73e5ad and 0d983b8.

📒 Files selected for processing (3)
  • .github/workflows/create_tag.yml
  • .github/workflows/publish-kmp.yml
  • .github/workflows/publish.yml

Comment thread .github/workflows/create_tag.yml Outdated
Comment on lines +3 to +9
# contents: write — create the release/tag (increment_version).
# id-token: write — required by the called publish.yml for JSR OIDC / npm
# provenance. A reusable workflow cannot exceed the caller's token scope,
# so it must be granted here even though create_tag itself doesn't use it.
permissions:
contents: write
id-token: write

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 | 🟡 Minor | ⚡ Quick win

Scope permissions to the job level.

Zizmor flags that granting contents: write and id-token: write at the workflow level provides overly broad permissions to all jobs. While the comment mentions it must be granted "here" for the called workflow, GitHub Actions actually allows specifying permissions directly on the job that calls a reusable workflow.

You can enforce least privilege by setting default workflow permissions to read and granting specific write permissions only to the jobs that need them.

🛡️ Proposed refactor for least privilege

Update the workflow-level permissions to only grant read access:

-permissions:
-  contents: write
-  id-token: write
+permissions:
+  contents: read

Add job-level permissions to increment_version:

  increment_version:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    # ...

And to the caller jobs:

  publish-npm:
    needs: increment_version
    uses: ./.github/workflows/publish.yml
    permissions:
      contents: read
      id-token: write
    # ...
🧰 Tools
🪛 zizmor (1.26.1)

[error] 8-8: overly broad permissions (excessive-permissions): contents: write is overly broad at the workflow level

(excessive-permissions)


[error] 9-9: overly broad permissions (excessive-permissions): id-token: write is overly broad at the workflow level

(excessive-permissions)

🤖 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/create_tag.yml around lines 3 - 9, Update the
workflow-level permissions in the GitHub Actions workflow to default to read
access, then add job-level permissions to increment_version for contents write
and to each reusable publish caller job for contents read and id-token write.
Preserve the existing job dependencies and workflow behavior while limiting
write scopes to only the jobs that require them.

Source: Linters/SAST tools

Comment thread .github/workflows/create_tag.yml
@vidplace7
vidplace7 self-requested a review July 21, 2026 13:01
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown

The latest Buf updates on your PR. Results from workflow pull-request / build (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedJul 21, 2026, 1:42 PM

- Least-privilege permissions: default the workflow to contents: read
  and grant writes per-job — contents: write to increment_version
  (release+tag), contents+id-token: write to the publish-npm caller,
  contents: read to publish-kmp. (A job that calls a reusable workflow
  can scope its own permissions, so the broad workflow-level grant was
  unnecessary.)
- Remove the Buf schema-registry push from increment_version: now that
  create_tag invokes publish.yml, its push-buf-registry job runs the
  same 'buf push --tag' — keeping it here too pushed the tag twice per
  release. publish.yml now solely owns the Buf push.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
jamesarich added a commit that referenced this pull request Jul 21, 2026
The root README CI badge pointed at a nonexistent workflow (ci.yml), so
it rendered as an error. Point it at the repo's actual PR workflow
(pull_request.yml).

Release-trigger automation for the KMP/npm/JSR publishers is handled
separately in #1014.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jamesarich
jamesarich requested a review from thebentern July 22, 2026 12:16
@thebentern
thebentern merged commit bfd718f into master Jul 22, 2026
2 of 3 checks passed
@thebentern
thebentern deleted the ci/auto-publish-on-tag branch July 22, 2026 12:39
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.

2 participants