Skip to content

Prepare the crates for release: keep 0.5.0, add the publish workflow - #378

Merged
milyin merged 5 commits into
mainfrom
release-prep-0.5.0
Aug 6, 2026
Merged

Prepare the crates for release: keep 0.5.0, add the publish workflow#378
milyin merged 5 commits into
mainfrom
release-prep-0.5.0

Conversation

@milyin

@milyin milyin commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Release plumbing for the completed split. The umbrella (#371) is merged, so this targets main directly.

Version: 0.6.0 → back to 0.5.0

main currently says 0.6.0. That bump rode in with #377 and was a mistake — prebindgen has never been published, so its shrinking API breaks no released contract. The split is the 0.5 shape, not a step away from it. This reverts it across manifests, README, crate docs and docs/crate-split.md.

kotlin-codegen is independent in its own repo and is already published — main now depends on kotlin-codegen = "0.2.0" from crates.io, so the sibling path dependency and its checkout wiring are gone.

Release checklist

Publishing is one crate per dispatch, bottom-up — crates.io rejects a crate whose path dependencies are unpublished. Run Publish to crates.io → pick the crate → enter 0.5.0.

Rehearse the whole order with dry_run: true first. That runs every check and cargo publish --dry-run, then stops before touching the registry — no upload, no tag, no release.

Prerequisite (separate repo)

This workspace, in order

# Crate Depends on Done
1 prebindgen [ ]
2 prebindgen-c-runtime — (no deps at all) [ ]
3 prebindgen-jni-runtime jni only [ ]
4 prebindgen-proc-macro prebindgen [ ]
5 prebindgen-flat prebindgen [ ]
6 prebindgen-registry prebindgen-flat, prebindgen [ ]
7 prebindgen-c prebindgen-registry, prebindgen-c-runtime [ ]
8 prebindgen-jni prebindgen-registry, prebindgen-jni-runtime, kotlin-codegen [ ]

1–3 have no workspace dependencies and can go in any order among themselves; everything after needs its predecessors live on crates.io first. Wait for each to appear before dispatching the next.

Before starting

  • Umbrella: split prebindgen into layered crates #371 merged to main (the workflow refuses to dispatch from any other branch)
  • CARGO_REGISTRY_TOKEN secret set, or CRATES_IO_TRUSTED_PUBLISHING repo variable set to true
  • crates-io environment exists on the repo
  • all eight names confirmed free on crates.io
  • this PR mergedmain must read 0.5.0 before the first dispatch
  • full dry run completed, in order, all green

Afterwards

  • downstream zenoh-flat-jni / zenoh-flat-c moved from path deps to published versions

RELEASING.md

New, and the reason for the latest push: the workflow encodes the mechanics, but nothing recorded who has to do what, in which order, or how the first publication gets past Trusted Publishing's chicken-and-egg — it cannot create a crate that does not exist yet, so round one runs on a scoped API token and each crate gains its trusted publisher afterwards.

Modelled on kotlin-codegen's, with what this workspace adds: eight crates sharing one version, dispatched one at a time bottom-up; per-crate <crate>-vX.Y.Z tags; no committed Cargo.lock, so no --locked; and per-crate Trusted Publishing entries that must all exist before the repo-wide CRATES_IO_TRUSTED_PUBLISHING variable is set. Linked from the README.

The publish workflow

Follows milyin/get-cargo-lock: validate the request against Cargo.toml, run the full check suite, refuse to republish a version that already exists from a different commit, verify the uploaded archive came from this SHA, then tag and cut a release.

Two things the reference did not have to solve:

  • A crate selector. One crate per run, because of the interdependence above.
  • Tags are <crate>-vX.Y.Z. Eight crates cannot share vX.Y.Z.

New CI package job

cargo package fails on metadata a normal build never reads — a missing description or license, a path dependency with no version. This job runs it per crate on every PR, so that surfaces on the PR that causes it rather than at release time.

It tolerates the "dependency not yet published" error, which says nothing about the crate under test, and fails on anything else. Verified locally: the three crates with no workspace deps package clean; the other five report pending deps — which is exactly the publish order above, independently confirmed.

Crate metadata

The four new crates gain the readme / keywords / categories the runtime crates already had, so each is publishable on its own.

One judgment call: none of the seven non-prebindgen members inherits documentation any more. The workspace value is https://docs.rs/prebindgen — a sibling, not the crate itself — so inheriting it would point every crate's doc link at the wrong place. Omitted, letting docs.rs derive the right URL. That was already wrong for prebindgen-proc-macro before this split; fixed here too.

README

The Problem and Solution narrative is untouched — the per-language FFI duplication story, and the MaybeUninit example of cbindgen and csbindgen disagreeing, is still exactly what the project is for.

What changed is the crate shape around it: a new Crates table of all eight and what depends on what, leading with the consequence a reader needs — a source crate depends on prebindgen alone; a shipped binding library depends on a ~350-line runtime crate, not the generator. The Stability section no longer mentions features = ["unstable-cbindgen"], because that feature no longer exists.

A stale example, fixed

The C usage snippets in README.md and in prebindgen's own crate docs described an API that no longer existsCbindgenBuilder::new(), a hand-built Flat and Registry, a .resolve() call. They now match what examples/example-cbindgen/build.rs actually compiles. Predates this PR; the split made it visible.

Verification

  • 17 + 80 + 115 + 73 + 250 = 535 lib tests, 34 doc, 20 + 10 — unchanged, as expected for a prose/manifest change
  • regen-check.sh byte-identical
  • clippy + fmt --check clean on 1.85.0 and stable
  • doc links: 23 distinct, none added
  • both workflow files parse; the package gate exercised locally

Still open, not blocking

  • Downstream reposzenoh-flat-jni and zenoh-flat-c manifests, plus the stale .prebindgen-kotlin-output marker → .kotlin-codegen-output. zenoh-flat needs no change.
  • #375 — restore the Emit seal across the crate boundary.

Update: merged main

main moved on (#379, #380) — prebindgen-jni migrated to the kotlin-codegen class model, and the dependency became kotlin-codegen = "0.2.0" from crates.io. Merged in, with two resolutions:

  • Cargo.toml — kept this branch's 0.5.0 for all eight prebindgen crates (main's 0.6.0 is what this PR reverts), took main's crates.io kotlin-codegen.
  • rust.yml / publish.yml — dropped the milyin/kotlin-codegen sibling checkout and KOTLIN_CODEGEN_REV from the package and publish jobs this branch adds. Main removed that wiring from every other job for the same reason; a textual merge left it only in the new ones. docs/crate-split.md's "independent at 0.1.0" note updated to match.

Re-verified on the merged tree: 17 + 80 + 115 + 73 + 246 = 531 lib tests + 20 + 10 + doc tests, 0 failures; fmt --check and clippy --all-targets --all-features -D warnings clean; regen-check.sh byte-identical.

milyin added 2 commits August 5, 2026 21:55
Reverts the 0.6.0 bump. prebindgen has never been published, so its
shrinking API breaks no released contract -- the split IS the 0.5 shape
rather than a step away from it. kotlin-codegen stays independent at
0.1.0 in its own repo.

Adds .github/workflows/publish.yml, following the scheme in
milyin/get-cargo-lock: workflow_dispatch, validate the request against
Cargo.toml, run the full check suite, refuse to republish a version that
already exists from a different commit, verify the uploaded archive came
from this SHA, then tag and cut a release.

Two things the reference did not have to solve. It publishes one crate
per run, chosen from a dropdown, because crates.io rejects a crate whose
path dependencies are unpublished -- so the eight go out bottom-up, and
the workflow header documents that order. And tags are <crate>-vX.Y.Z,
since eight crates cannot share vX.Y.Z.

dry_run runs every check plus `cargo publish --dry-run` and stops before
touching the registry, creating no tag and no release, so the whole
order can be rehearsed first.

CI gains a `package` job so packaging breakage surfaces on the PR that
causes it rather than at release time: `cargo package` fails on metadata
a normal build never reads. It tolerates the "dependency not yet
published" error, which says nothing about the crate under test, and
fails on anything else. Verified locally -- the three crates with no
workspace dependencies package clean, the other five report pending
deps, which is exactly the documented publish order.

535 lib + 34 doc + 20 + 10 unchanged; regen-check byte-identical; clippy
and fmt clean on 1.85.0 and stable.
Every phase landed with umbrella #371; the header and the B2/B4 rows
still described work in flight.

Copilot AI 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.

Pull request overview

This PR adjusts the workspace back to the intended pre-release versioning (0.5.0) after the crate-split, and adds GitHub Actions automation to make crates.io publication repeatable and safer (including a publish workflow and a per-crate cargo package CI gate).

Changes:

  • Revert workspace/crate version references from 0.6.x back to 0.5.x across manifests and docs.
  • Add a Publish to crates.io workflow that publishes one selected crate per dispatch, with optional dry-run and archive/SHA verification.
  • Add a CI package job that runs cargo package per publishable crate to catch packaging metadata issues early.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
README.md Updates stability/version references and dependency snippets to 0.5.
prebindgen/src/lib.rs Updates crate-level docs and example dependency versions to 0.5.
prebindgen-c/src/lib.rs Updates experimental API wording to refer to the 0.5 surface.
docs/crate-split.md Reframes the doc as historical record on main and updates Phase C notes/versioning.
Cargo.toml Reverts workspace package.version and workspace dependency versions to 0.5.0.
.github/workflows/rust.yml Adds a per-crate cargo package CI job to surface packaging breakage on PRs.
.github/workflows/publish.yml Introduces a workflow_dispatch-based publish pipeline with validation, dry-run, tagging, and release creation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/rust.yml Outdated
milyin and others added 3 commits August 5, 2026 22:48
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Resolutions:

- Cargo.toml: keep the branch's 0.5.0 for every prebindgen crate, take
  main's `kotlin-codegen = "0.2.0"` — the crate is published now, so the
  sibling path dependency is gone.
- rust.yml / publish.yml: drop the `milyin/kotlin-codegen` sibling
  checkout and `KOTLIN_CODEGEN_REV` from the jobs this branch adds. Main
  removed that wiring everywhere else for the same reason.
The publish workflow encodes the mechanics; nothing recorded who has to
do what, in which order, or how to get the first publication past the
chicken-and-egg of Trusted Publishing. Modelled on kotlin-codegen's
RELEASING.md, with the two things this workspace adds: eight crates that
share one version must be dispatched one at a time bottom-up, and tags
are per crate.

Copilot AI 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.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

Copilot AI 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.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

Suppressed comments (2)

.github/workflows/rust.yml:89

  • The grep pattern that whitelists the expected “unpublished sibling dependency” failure is missing the closing escaped backtick in the failed to select a version… alternative, so the package job can incorrectly fail even on the expected error output.
            printf '%s\n' "$out" | grep -qE "no matching package named \`prebindgen(-[a-z-]+)?\`|failed to select a version for the requirement \`prebindgen(-[a-z-]+)?" || exit 1

.github/workflows/publish.yml:93

  • This step installs the stable toolchain but then calls cargo metadata without +stable (and without setting a default toolchain). On runners where no default toolchain is configured, this can fail with “no default toolchain configured”. Use cargo +stable here for consistency with the rest of the workflow.
          manifest_version=$(cargo metadata --no-deps --format-version 1 \
            | jq -r --arg c "$RELEASE_CRATE" '.packages[] | select(.name == $c) | .version')

@milyin
milyin merged commit 2a92e82 into main Aug 6, 2026
7 checks passed
milyin added a commit that referenced this pull request Aug 6, 2026
#378 landed the release plumbing, which put its `package` job where this
branch puts `docs`. Both are wanted: kept `docs` then `package`, and the
`docs` comment now names publish.yml, which exists on main as of that
merge.
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