Skip to content

ci: SDK publish workflows (OIDC trusted publishing, tag-gated) - #7601

Merged
lawrencecchen merged 2 commits into
mainfrom
feat-mux-sdk-publish-ci
Jul 8, 2026
Merged

lawrencecchen merged 2 commits into
mainfrom
feat-mux-sdk-publish-ci

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Jul 8, 2026 •

Copy link
Copy Markdown
Contributor

Sets up the release pipeline for the cmux-mux SDKs. Publishes nothing — every workflow triggers only on a mux-sdk-v* tag or manual dispatch (never push/PR), so nothing ships until a maintainer configures trusted publishers and pushes a tag.

Workflow Target Mechanism
sdk-publish-python.yml PyPI cmux OIDC trusted publishing + PEP 740 attestations
sdk-publish-crates.yml crates.io cmux-client short-lived OIDC token, cargo publish -p cmux-client
sdk-publish-npm.yml npm cmux npm publish --provenance, gated behind an explicit confirm input (npm cmux is currently the live cloud-VM CLI)
sdk-publish-go.yml (tag-only) build/vet gate; go get ...@mux-sdk-vX.Y.Z
sdk-publish-java.yml Maven Central TODO stub (needs GPG + com.cmux namespace verification)

Each job validates the tag version matches every package manifest and runs that language's binding e2e as a gate, so a broken or stale binding can't publish. All uses: are SHA-pinned, per-job least-privilege permissions:, actionlint clean. mux/bindings/RELEASING.md documents the one-time registry trusted-publisher setup, the tag scheme, and the security posture. Marks the rust binding publish = true.

Meta/CI-only; no app or runtime behavior changes. First real publish still requires: registry trusted-publisher config (maintainer, out-of-band), a version bump, and a deliberate tag push.


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Note

Medium Risk
CI-only, but tag pushes can ship to PyPI and crates.io once trusted publishers are configured; npm is gated, yet mistaken registry setup or a bad tag could still publish public packages.

Overview
Adds tag-gated CI for mux SDK releases on mux-sdk-v* (or manual workflow_dispatch), with a shared version guard that requires TypeScript, Python, and Rust manifests to match before any publish path runs.

Python and crates.io (cmux-client) publish via OIDC trusted publishing after language-specific binding e2e gates; PyPI uses attestations, Rust uses crates-io-auth-action. Go and Java only validate (Go build/vet; Java ends in a Maven Central TODO stub). npm runs e2e on tags but never publishes on tag push—publish requires manual dispatch plus confirm_npm_cmux: true because the cmux name is a live unrelated package.

mux/bindings/RELEASING.md documents registry setup, the mux-sdk-vX.Y.Z tag scheme, and safety posture. cmux-client is set to publish = true explicitly (overriding workspace publish = false).

Reviewed by Cursor Bugbot for commit 8dd396f. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Add tag-gated CI to validate and publish the cmux SDKs via OIDC trusted publishing. Nothing publishes on push/PR; only mux-sdk-v* tags or manual runs can release.

  • New Features

    • Workflows for Python (PyPI cmux), Rust (crates.io cmux-client), npm (cmux), Go (validate only), and Java (publish stub).
    • Guards: ensure tag version matches TS/Python/Rust manifests; run per-language e2e as a gate before publish.
    • Security: OIDC trusted publishing (no stored tokens), provenance/attestations where supported, SHA-pinned actions, least-privilege perms; runners routed via vars.LINUX_RUNNER with a safe default.
    • Enables Rust crate publishing (publish = true) and adds mux/bindings/RELEASING.md.
  • Migration

    • Set up trusted publishers for PyPI cmux, crates.io cmux-client, and npm cmux.
    • Bump all SDK versions, merge, then push mux-sdk-vX.Y.Z to trigger; Go is tag-consumed (e.g., go get ...@mux-sdk-vX.Y.Z).
    • npm requires a manual dispatch with confirm_npm_cmux: true; Java publish remains TODO until com.cmux verification and signing are ready.

Written for commit 2c3d626. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added automated SDK release workflows for Rust, Go, Java, TypeScript (npm), and Python, including cross-language version alignment checks, end-to-end validation, and publishing steps.
    • Added manual-approval gating for npm publishing.
  • Documentation
    • Added an SDK release guide covering version consistency, workflow triggering rules, and publishing safety practices.
  • Bug Fixes
    • Ensured the Rust cmux-client crate is explicitly marked for publishing.

…hes nothing until triggered)

Adds .github/workflows/sdk-publish-{python,crates,npm,go,java}.yml and
mux/bindings/RELEASING.md. Each workflow triggers only on a mux-sdk-v*
tag or manual dispatch (never push/PR), validates that the tag version
matches every package manifest, runs that language's binding e2e as a
gate, and publishes via OIDC trusted publishing (no stored tokens):

- python -> PyPI (cmux) with PEP 740 attestations
- rust   -> crates.io (cmux-client) via short-lived OIDC token
- npm    -> cmux with --provenance, gated behind an explicit
            confirm input because npm cmux is currently a different
            live package (the cloud-VM CLI)
- go     -> tag-only consumption (build/vet gate, no registry)
- java   -> Maven Central TODO (needs GPG + namespace verification)

Marks the rust binding publish=true. Every uses: is SHA-pinned;
least-privilege per-job permissions; actionlint clean. RELEASING.md
documents the one-time registry trusted-publisher setup, the version
scheme, and the security posture. Nothing publishes until a maintainer
configures trusted publishers and pushes a tag.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@vercel

vercel Bot commented Jul 8, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jul 8, 2026 6:28pm
cmux-staging Building Building Preview, Comment Jul 8, 2026 6:28pm

@coderabbitai

coderabbitai Bot commented Jul 8, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds five GitHub Actions workflows for SDK release validation and publishing, plus release documentation and an explicit Rust crate publish setting.

Changes

SDK publish workflows and release docs

Layer / File(s) Summary
Rust crates.io publish workflow
.github/workflows/sdk-publish-crates.yml, mux/bindings/rust/Cargo.toml
Adds version checking, Rust binding e2e tests, and crates.io trusted publishing for cmux-client; the Rust crate publish flag is set explicitly.
Go SDK publish workflow
.github/workflows/sdk-publish-go.yml
Adds version checking, Go binding e2e tests, and a follow-up go build/go vet validation job.
Java SDK publish workflow
.github/workflows/sdk-publish-java.yml
Adds version checking, Java binding e2e tests, and a placeholder Maven Central job.
npm SDK publish workflow
.github/workflows/sdk-publish-npm.yml
Adds version checking, TypeScript binding e2e tests, and a manual-confirmation npm publish job with provenance.
Python SDK publish workflow
.github/workflows/sdk-publish-python.yml
Adds version checking, Python binding e2e tests, distribution builds, and PyPI publishing with attestations.
Release documentation
mux/bindings/RELEASING.md
Documents the shared tag scheme, registry setup, release steps, and safety checks for the SDK release process.

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

🚥 Pre-merge checks | ✅ 24 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers summary and purpose, but it omits the required Testing, Demo Video, Review Trigger, and Checklist sections. Add the missing template sections, especially Testing, Review Trigger, and Checklist, and include a Demo Video link if applicable.
✅ Passed checks (24 passed)
Check name Status Explanation
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.
Cmux Swift Actor Isolation ✅ Passed PR changes only GitHub Actions workflows; no Swift files or actor-isolation-relevant code were modified.
Cmux Swift Blocking Runtime ✅ Passed No .swift files were changed; the diff only adds GitHub Actions workflows, so the Swift blocking-runtime rule isn’t implicated.
Cmux Browser Automation Off-Main ✅ Passed Diff only adds release workflows and docs; no browser automation code, routing, or policy tests were changed.
Cmux Expensive Synchronous Load ✅ Passed No Swift source files changed; the diff only adds GitHub Actions workflows and docs, so the Swift expensive-sync-load rule is not applicable.
Cmux Cache Substitution Correctness ✅ Passed Only workflow files changed; no production Swift/TS/JS persistence, history, undo, or snapshot code was touched.
Cmux No Hacky Sleeps ✅ Passed Only workflow YAML changed, and the rule explicitly excludes GitHub Actions workflow YAML; no sleeps/polling/timers were introduced.
Cmux Algorithmic Complexity ✅ Passed HEAD only changes .github/workflows/* CI YAMLs; no production Swift/TS/JS/shell/runtime code was modified, so the complexity rule doesn’t apply.
Cmux Swift Concurrency ✅ Passed The diff only changes GitHub workflows and docs; no Swift files or Swift concurrency patterns were introduced or expanded.
Cmux Swift @Concurrent ✅ Passed No Swift files changed in the diff, so the Swift concurrency rule is not applicable.
Cmux Swift File And Package Boundaries ✅ Passed PR diff contains only workflow/docs/Cargo changes; no Swift files or SwiftPM/package-boundary code were touched.
Cmux Swiftpm Lockfiles ✅ Passed HEAD only changes five release workflows; the patch contains no SwiftPM/Xcode/.gitignore/Package.resolved edits, so the rule isn’t violated.
Cmux Swift Logging ✅ Passed No Swift app/runtime files changed in the diff; only GitHub workflow files were added, so the Swift logging rule is not implicated.
Cmux User-Facing Error Privacy ✅ Passed PASS: The diff only adds CI workflows/docs and a Cargo publish flag; no app/UI/API error copy or user-facing alerts were changed.
Cmux Full Internationalization ✅ Passed Only workflows, release docs, and Cargo config changed; no user-facing localized text or locale files were introduced.
Cmux Swiftui State Layout ✅ Passed No SwiftUI files or state/layout code changed; the diff only adds CI workflows/docs and a Cargo.toml publish flag, so the SwiftUI rule doesn’t apply.
Cmux Architecture Rethink ✅ Passed Diff only adds GitHub workflows; no Swift files or architectural changes are present, so the Swift rethink rule doesn't apply.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR only changes GitHub Actions/workflow docs; no .swift files or cmux window code were touched, so the Swift shortcut rule is not applicable.
Cmux Source Artifacts ✅ Passed Changed paths are only workflows, docs, and Cargo.toml; none are local outputs, caches, temp dirs, or copied artifacts.
Cmux No Test Or Debug Seam In Production Source ✅ Passed PR only changes workflows, docs, and Cargo.toml; no Swift files under production Sources/ were touched, so the seam rule isn’t implicated.
Cmux No Ambient Global State ✅ Passed Diff only touches GitHub Actions, docs, and Cargo.toml; no Swift code or new ambient global state was added.
Title check ✅ Passed The title clearly reflects the main change: tag-gated SDK publish workflows with OIDC trusted publishing.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-mux-sdk-publish-ci

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.

@greptile-apps

greptile-apps Bot commented Jul 8, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds release automation for the mux SDK packages.

  • New tag-gated workflows for Python, Rust, npm, Go, and Java SDK release paths.
  • Shared version checks across the TypeScript, Python, and Rust manifests.
  • Binding e2e gates before publish or validation steps.
  • Release documentation for registry setup, tag format, and publish safety.
  • Rust crate publishing enabled for cmux-client.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
.github/workflows/sdk-publish-crates.yml Adds Rust SDK validation and crates.io trusted publishing for cmux-client.
.github/workflows/sdk-publish-go.yml Adds Go SDK validation for the nested Go binding module.
.github/workflows/sdk-publish-java.yml Adds Java SDK validation and leaves Maven Central publishing as an explicit stub.
.github/workflows/sdk-publish-npm.yml Adds TypeScript SDK validation and a manual-only npm publish path.
.github/workflows/sdk-publish-python.yml Adds Python SDK validation, package build, artifact handoff, and PyPI trusted publishing.
mux/bindings/RELEASING.md Documents the shared SDK release process and one-time registry setup.
mux/bindings/rust/Cargo.toml Enables publishing for the cmux-client Rust crate.

Reviews (2): Last reviewed commit: "ci: route sdk-publish workflow runners t..." | Re-trigger Greptile

Comment on lines +5 to +6
tags:
- "mux-sdk-v*"

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.

P1 Nested Go Tag Is Missing

The Go binding is a nested module at mux/bindings/go, but this workflow only validates the shared mux-sdk-v* tag. A release can pass this workflow without creating the module-scoped semver tag Go tooling expects for github.com/manaflow-ai/cmux/mux/bindings/go, so consumers may not be able to install the advertised SDK version with normal go get version resolution.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!


- name: Publish package to npm
working-directory: mux/bindings/typescript
run: npm publish --provenance

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.

P2 Public Access Is Implicit

The package manifest for the npm SDK has no publishConfig.access, and this publish step does not pass --access public. On the first coordinated publish of the unscoped cmux package, npm can reject the publish with an access/payment error instead of shipping the SDK after the validation gate succeeds.

@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: 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/sdk-publish-crates.yml:
- Around line 113-135: Add a brief inline comment in the publish job explaining
why the `id-token: write` permission is set, noting that `publish` uses
`rust-lang/crates-io-auth-action` for OIDC trusted publishing to crates.io.
Place the comment near the `permissions` block so reviewers can easily see the
security rationale when reviewing `sdk-publish-crates.yml`.

In @.github/workflows/sdk-publish-go.yml:
- Around line 21-71: The version validation logic in the version job is
duplicated across multiple SDK publish workflows, so extract it into a reusable
workflow invoked with workflow_call and have each publish workflow call that
shared validator. Keep the existing validation behavior in the reusable workflow
by preserving the tag/dispatch checks and package version comparison logic, and
reference the version job plus its validation step so it’s easy to replace
without hunting through each workflow file.
- Line 104: Disable default module caching in both actions/setup-go invocations
within the sdk-publish-go workflow by adding cache false to the setup-go steps
used in the main release job and the validate-go-module job. Update the setup-go
entries identified by actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c
so the workflow always uses a clean Go module state during release validation.

In @.github/workflows/sdk-publish-java.yml:
- Around line 103-109: The Java version setup step relies on manual PATH
manipulation via JAVA_HOME_17_X64, which is tied to GitHub-hosted Ubuntu
runners. Replace that shell step in the workflow with actions/setup-java in the
Java version job, using a pinned action reference and the desired Java 17
distribution/version so the environment is set up consistently without depending
on runner-specific variables.

In @.github/workflows/sdk-publish-npm.yml:
- Around line 154-156: The npm publish step in the workflow is missing the
authentication token that the generated .npmrc expects, so the publish job will
fail. Update the Publish package to npm step in the sdk-publish-npm workflow to
pass the required npm token from secrets as NODE_AUTH_TOKEN (for example from an
NPM_TOKEN secret in the npm environment), and keep the publish command in the
existing publish job context so npm can authenticate successfully.
🪄 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

Run ID: 27c70e90-05fa-48a6-82fd-e63955084b6f

📥 Commits

Reviewing files that changed from the base of the PR and between fce37f1 and 8dd396f.

📒 Files selected for processing (7)
  • .github/workflows/sdk-publish-crates.yml
  • .github/workflows/sdk-publish-go.yml
  • .github/workflows/sdk-publish-java.yml
  • .github/workflows/sdk-publish-npm.yml
  • .github/workflows/sdk-publish-python.yml
  • mux/bindings/RELEASING.md
  • mux/bindings/rust/Cargo.toml

Comment on lines +113 to +135
publish:
needs: bindings-e2e-rust
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
environment:
name: crates-io
url: https://crates.io/crates/cmux-client
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Authenticate with crates.io trusted publishing
id: auth
uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1.0.5

- name: Publish cmux-client
working-directory: mux
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
run: cargo publish -p cmux-client --locked

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 | 🔵 Trivial | 💤 Low value

Add a comment explaining the id-token: write permission.

The id-token: write permission is required for OIDC trusted publishing via rust-lang/crates-io-auth-action, but it has no explanatory comment. Adding one improves auditability for security reviewers.

📝 Suggested comment
     permissions:
       contents: read
-      id-token: write
+      id-token: write # Required for OIDC trusted publishing to crates.io
📝 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
publish:
needs: bindings-e2e-rust
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
environment:
name: crates-io
url: https://crates.io/crates/cmux-client
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Authenticate with crates.io trusted publishing
id: auth
uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1.0.5
- name: Publish cmux-client
working-directory: mux
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
run: cargo publish -p cmux-client --locked
publish:
needs: bindings-e2e-rust
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Required for OIDC trusted publishing to crates.io
environment:
name: crates-io
url: https://crates.io/crates/cmux-client
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Authenticate with crates.io trusted publishing
id: auth
uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1.0.5
- name: Publish cmux-client
working-directory: mux
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
run: cargo publish -p cmux-client --locked
🧰 Tools
🪛 zizmor (1.26.1)

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

(undocumented-permissions)


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

(anonymous-definition)

🤖 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/sdk-publish-crates.yml around lines 113 - 135, Add a brief
inline comment in the publish job explaining why the `id-token: write`
permission is set, noting that `publish` uses `rust-lang/crates-io-auth-action`
for OIDC trusted publishing to crates.io. Place the comment near the
`permissions` block so reviewers can easily see the security rationale when
reviewing `sdk-publish-crates.yml`.

Source: Linters/SAST tools

Comment on lines +21 to +71
version:
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Validate tag and package versions
id: version
env:
DISPATCH_VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
if [[ "${GITHUB_REF_TYPE:-}" == "tag" ]]; then
[[ "$GITHUB_REF_NAME" =~ ^mux-sdk-v[0-9]+\.[0-9]+\.[0-9]+$ ]] || {
echo "tag must match mux-sdk-vX.Y.Z" >&2
exit 1
}
version="${GITHUB_REF_NAME#mux-sdk-v}"
else
version="$DISPATCH_VERSION"
[[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || {
echo "workflow_dispatch version must match X.Y.Z" >&2
exit 1
}
fi
python3 - "$version" <<'PY'
import json
import pathlib
import sys
import tomllib

expected = sys.argv[1]
root = pathlib.Path.cwd()
versions = {
"typescript package.json": json.loads((root / "mux/bindings/typescript/package.json").read_text())["version"],
"python pyproject.toml": tomllib.loads((root / "mux/bindings/python/pyproject.toml").read_text())["project"]["version"],
"rust Cargo.toml": tomllib.loads((root / "mux/bindings/rust/Cargo.toml").read_text())["package"]["version"],
}
mismatches = {name: got for name, got in versions.items() if got != expected}
if mismatches:
for name, got in mismatches.items():
print(f"{name}: expected {expected}, got {got}", file=sys.stderr)
raise SystemExit(1)
print(f"All package versions match {expected}")
PY
echo "version=$version" >> "$GITHUB_OUTPUT"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Consider extracting the version validation job into a reusable workflow.

The version validation job (lines 21–71) is duplicated verbatim across all four SDK publish workflows. A bug or schema change in the validation logic would require coordinated edits in four files. A reusable workflow (workflow_call) would centralize this and reduce maintenance risk.

🧰 Tools
🪛 zizmor (1.26.1)

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

(anonymous-definition)

🤖 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/sdk-publish-go.yml around lines 21 - 71, The version
validation logic in the version job is duplicated across multiple SDK publish
workflows, so extract it into a reusable workflow invoked with workflow_call and
have each publish workflow call that shared validator. Keep the existing
validation behavior in the reusable workflow by preserving the tag/dispatch
checks and package version comparison logic, and reference the version job plus
its validation step so it’s easy to replace without hunting through each
workflow file.

fi

- name: Set up Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.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.

🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Disable default caching on actions/setup-go in release workflows.

actions/setup-go enables module caching by default. In a release-adjacent workflow, a poisoned cache could compromise validation integrity. Add cache: false to both setup-go steps to ensure reproducible builds from a clean state.

🔒️ Proposed fix
       - name: Set up Go
         uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
         with:
           go-version: "1.22.x"
+          cache: false

Apply the same cache: false addition to the setup-go step in the validate-go-module job (line 129).

Also applies to: 129-129

🧰 Tools
🪛 zizmor (1.26.1)

[error] 104-104: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): enables caching by default

(cache-poisoning)

🤖 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/sdk-publish-go.yml at line 104, Disable default module
caching in both actions/setup-go invocations within the sdk-publish-go workflow
by adding cache false to the setup-go steps used in the main release job and the
validate-go-module job. Update the setup-go entries identified by
actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c so the workflow always
uses a clean Go module state during release validation.

Source: Linters/SAST tools

Comment on lines +103 to +109
- name: Java version
run: |
echo "JAVA_HOME_17_X64=$JAVA_HOME_17_X64"
echo "$JAVA_HOME_17_X64/bin" >> "$GITHUB_PATH"
export PATH="$JAVA_HOME_17_X64/bin:$PATH"
java -version
javac -version

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Prefer actions/setup-java over manual PATH manipulation.

Using actions/setup-java with SHA pinning would be more robust across runner types, clearer in intent, and support caching/validation out of the box. The current approach depends on JAVA_HOME_17_X64 which is specific to GitHub-hosted Ubuntu runners and may not exist on custom runners.

♻️ Proposed refactor
-      - name: Java version
-        run: |
-          echo "JAVA_HOME_17_X64=$JAVA_HOME_17_X64"
-          echo "$JAVA_HOME_17_X64/bin" >> "$GITHUB_PATH"
-          export PATH="$JAVA_HOME_17_X64/bin:$PATH"
-          java -version
-          javac -version
+      - name: Set up Java
+        uses: actions/setup-java@<sha-pin> # v5.x.x
+        with:
+          distribution: temurin
+          java-version: "17"
📝 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
- name: Java version
run: |
echo "JAVA_HOME_17_X64=$JAVA_HOME_17_X64"
echo "$JAVA_HOME_17_X64/bin" >> "$GITHUB_PATH"
export PATH="$JAVA_HOME_17_X64/bin:$PATH"
java -version
javac -version
- name: Set up Java
uses: actions/setup-java@<sha-pin> # v5.x.x
with:
distribution: temurin
java-version: "17"
🤖 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/sdk-publish-java.yml around lines 103 - 109, The Java
version setup step relies on manual PATH manipulation via JAVA_HOME_17_X64,
which is tied to GitHub-hosted Ubuntu runners. Replace that shell step in the
workflow with actions/setup-java in the Java version job, using a pinned action
reference and the desired Java 17 distribution/version so the environment is set
up consistently without depending on runner-specific variables.

Comment on lines +154 to +156
- name: Publish package to npm
working-directory: mux/bindings/typescript
run: npm publish --provenance

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

npm publish will fail without NODE_AUTH_TOKEN environment variable.

actions/setup-node with registry-url creates an .npmrc that references ${NODE_AUTH_TOKEN}, but the publish step never sets this env var. npm does not support OIDC for authentication—--provenance only adds SIGSTORE attestations; a token is still required. The publish step will fail with an authentication error when triggered.

🐛 Proposed fix
       - name: Publish package to npm
         working-directory: mux/bindings/typescript
+        env:
+          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
         run: npm publish --provenance

Store the npm access token as a secret (e.g., NPM_TOKEN) in the npm environment and reference it here. Use a granular access token scoped to publish only the cmux package.

📝 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
- name: Publish package to npm
working-directory: mux/bindings/typescript
run: npm publish --provenance
- name: Publish package to npm
working-directory: mux/bindings/typescript
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npm publish --provenance
🤖 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/sdk-publish-npm.yml around lines 154 - 156, The npm
publish step in the workflow is missing the authentication token that the
generated .npmrc expects, so the publish job will fail. Update the Publish
package to npm step in the sdk-publish-npm workflow to pass the required npm
token from secrets as NODE_AUTH_TOKEN (for example from an NPM_TOKEN secret in
the npm environment), and keep the publish command in the existing publish job
context so npm can authenticate successfully.

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

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2c3d626. Configure here.

working-directory: mux
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
run: cargo publish -p cmux-client --locked

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Publish job lacks Rust toolchain

Medium Severity

The publish job runs cargo publish without the same Rust bootstrap used in bindings-e2e-rust. On runners where cargo is not preinstalled, trusted publishing succeeds but publishing fails even after e2e passed in a separate job.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2c3d626. Configure here.


- name: Publish package to npm
working-directory: mux/bindings/typescript
run: npm publish --provenance

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

npm publish omits built dist

High Severity

The workflow builds TypeScript into dist/ then runs npm publish, but npm packing honors mux/bindings/typescript/.gitignore, which ignores dist/. The published tarball can omit main/types under dist/ despite a successful CI build.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2c3d626. Configure here.

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

♻️ Duplicate comments (2)
.github/workflows/sdk-publish-go.yml (1)

128-131: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Disable default caching on actions/setup-go in the release validation job.

actions/setup-go enables module caching by default. In a release-adjacent workflow, a poisoned cache could cause false validation results. Add cache: false to ensure reproducible builds from a clean state. This was previously flagged and remains unresolved.

🔒️ Proposed fix
       - name: Set up Go
         uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
         with:
           go-version: "1.22.x"
+          cache: false
🤖 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/sdk-publish-go.yml around lines 128 - 131, The Set up Go
step in the release validation job uses actions/setup-go with default module
caching enabled, which can make validation depend on stale or poisoned cache
state. Update the setup-go configuration in the workflow to explicitly disable
caching by adding cache: false alongside the existing go-version setting,
keeping the change scoped to the release validation path.

Source: Linters/SAST tools

.github/workflows/sdk-publish-npm.yml (1)

154-156: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

npm publish will fail without NODE_AUTH_TOKEN environment variable.

actions/setup-node with registry-url creates an .npmrc referencing ${NODE_AUTH_TOKEN}, but the publish step never sets this env var. npm does not support OIDC for authentication — --provenance only adds Sigstore attestations; a token is still required. This was previously flagged and remains unresolved.

🐛 Proposed fix
       - name: Publish package to npm
         working-directory: mux/bindings/typescript
+        env:
+          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
         run: npm publish --provenance

Store a granular npm access token as NPM_TOKEN in the npm environment (line 129) and reference it here.

🤖 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/sdk-publish-npm.yml around lines 154 - 156, The npm
publish step in the workflow will fail because `NODE_AUTH_TOKEN` is never set
even though `actions/setup-node` writes an `.npmrc` that expects it. Update the
`Publish package to npm` step to pass the stored npm token from the existing
`npm` environment as `NODE_AUTH_TOKEN` (or otherwise reference that token
explicitly) so `npm publish --provenance` can authenticate successfully.
🤖 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.

Duplicate comments:
In @.github/workflows/sdk-publish-go.yml:
- Around line 128-131: The Set up Go step in the release validation job uses
actions/setup-go with default module caching enabled, which can make validation
depend on stale or poisoned cache state. Update the setup-go configuration in
the workflow to explicitly disable caching by adding cache: false alongside the
existing go-version setting, keeping the change scoped to the release validation
path.

In @.github/workflows/sdk-publish-npm.yml:
- Around line 154-156: The npm publish step in the workflow will fail because
`NODE_AUTH_TOKEN` is never set even though `actions/setup-node` writes an
`.npmrc` that expects it. Update the `Publish package to npm` step to pass the
stored npm token from the existing `npm` environment as `NODE_AUTH_TOKEN` (or
otherwise reference that token explicitly) so `npm publish --provenance` can
authenticate successfully.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: bb340918-abd8-4152-a21d-210286dbcc78

📥 Commits

Reviewing files that changed from the base of the PR and between 8dd396f and 2c3d626.

📒 Files selected for processing (5)
  • .github/workflows/sdk-publish-crates.yml
  • .github/workflows/sdk-publish-go.yml
  • .github/workflows/sdk-publish-java.yml
  • .github/workflows/sdk-publish-npm.yml
  • .github/workflows/sdk-publish-python.yml

@lawrencecchen
lawrencecchen merged commit a44618f into main Jul 8, 2026
37 of 40 checks passed

This branch was successfully deployed

1 active deployment
Preview – cmux — 2c3d626f Deployed Jul 8, 2026 by vercel[bot]
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.

1 participant