Skip to content

chore(deps): Bump openjd-* Rust crates to latest crates.io releases - #346

Merged
leongdl merged 1 commit into
OpenJobDescription:mainlinefrom
leongdl:bump-openjd-rust-deps
Sep 1, 2026
Merged

chore(deps): Bump openjd-* Rust crates to latest crates.io releases#346
leongdl merged 1 commit into
OpenJobDescription:mainlinefrom
leongdl:bump-openjd-rust-deps

Conversation

@leongdl

@leongdl leongdl commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

What changed

Bumps the bindings crate onto the current published openjd-* releases from
crates.io and refreshes the rest of the locked graph.

Crate Before After
openjd-expr 0.4.0 0.5.0
openjd-model 0.5.2 0.5.4
openjd-sessions 0.5.2 0.5.4
pyo3-stub-gen 0.22 0.23

cargo update moved 21 transitive crates to their latest compatible versions —
notably serde-saphyr 1.0.1 → 1.2.0, uuid 1.24.0 → 1.26.0, granit-parser
1.0.1 → 1.2.0. THIRD-PARTY-LICENSES.txt is regenerated with
scripts/check_third_party_licenses.sh --update under cargo-about 0.9.2, the
version CI installs.

pyo3, pyo3-log, tokio, log, serde_json and windows were already at
their latest published versions within the declared ranges, so no manifest change
was needed for them. openjd-cli is the fourth crate under the
openjobdescription keyword but is
not a dependency of this repo.

No source edits: the openjd-expr 0.4 → 0.5 major bump broke no call site.

Known gap: the stub-gen feature still does not build

The pyo3-stub-gen bump does not fix the stub-gen feature under abi3-py39.
0.23.0 still calls impl_exception_stub_type!(PyEncodingWarning, ...) unguarded,
and pyo3 gates that type behind #[cfg(Py_3_10)], which is unset for
abi3-py39. This break predates the bump:

Tree cargo build --workspace --all-features
e7a17b3 (base) fails, 8 errors in pyo3-stub-gen 0.22.3 from pyo3 0.29's downcastcast rename
this branch fails, 1 error: PyEncodingWarning not found

So the bump narrows the failure to exactly the upstream bug that
scripts/generate_stubs.sh already clones-and-patches around. CI builds default
features only (rust_quality.yml runs cargo build --all-targets, not
--all-features), so no gate regresses. Fixing stub generation properly needs an
upstream patch or a [patch.crates-io] entry, and is out of scope here.

Verification

Run locally on macOS (aarch64, cargo 1.96.0):

  • cargo fmt --manifest-path rust-bindings/Cargo.toml --check — clean
  • cargo build --workspace — ok
  • cargo clippy --manifest-path rust-bindings/Cargo.toml --all-targets -- -D warnings — clean
  • cargo test --workspace — ok (bindings crate has no Rust tests; 0 passed)
  • cargo deny --config deny.toml check licenses bans sourcesbans ok, licenses ok, sources ok, with two license-not-encountered warnings for the now-unused ISC
    and MIT-0 allowances in deny.toml
  • hatch run test — 5517 passed, 24 skipped, 3 xfailed; coverage 94.11% against
    the 94% gate. The extension was rebuilt against openjd-expr 0.5.0,
    openjd-model 0.5.4, openjd-sessions 0.5.4 by maturin develop.
  • scripts/check_third_party_licenses.sh — reports the file up to date

The same commit content ran green on all 28 CI checks on
leongdl#1 before being
squashed and retargeted here, including the Linux/macOS/Windows Rust legs and the
THIRD-PARTY-LICENSES check that a stale local cargo-about 0.9.1 had initially
failed.

@leongdl
leongdl requested a review from a team as a code owner September 1, 2026 16:45
Move the bindings crate onto the current published openjd-* releases and
refresh the rest of the locked dependency graph:

  openjd-expr      0.4.0  -> 0.5.0
  openjd-model     0.5.2  -> 0.5.4
  openjd-sessions  0.5.2  -> 0.5.4
  pyo3-stub-gen    0.22   -> 0.23

`cargo update` also moved 21 transitive crates to their latest compatible
versions (notably serde-saphyr 1.0.1 -> 1.2.0, uuid 1.24.0 -> 1.26.0,
granit-parser 1.0.1 -> 1.2.0). THIRD-PARTY-LICENSES.txt is regenerated
with cargo-about 0.9.2, the version CI installs, to match.

pyo3, pyo3-log, tokio, log, serde_json and windows were already at their
latest published versions within the declared ranges; no change needed.
No source edits were required: the openjd-expr 0.4 -> 0.5 major bump
broke no call site.

The pyo3-stub-gen bump does not fix the `stub-gen` feature, which cannot
compile under `abi3-py39`: 0.23.0 still references `PyEncodingWarning`
unguarded, and pyo3 gates that type behind `#[cfg(Py_3_10)]`. That break
predates this change (at e7a17b3, `cargo build --all-features` fails with
8 errors from pyo3 0.29's `downcast` -> `cast` rename; after the bump it
fails with the single PyEncodingWarning error that
scripts/generate_stubs.sh already patches around). CI builds default
features only, so no gate regresses.

Verified: cargo fmt --check, cargo build --all-targets, cargo clippy
-D warnings, cargo test and cargo deny check licenses bans sources all
pass; hatch run test gives 5517 passed, 24 skipped, 3 xfailed with
coverage 94.11% over the 94% gate; scripts/check_third_party_licenses.sh
reports the file up to date.

Signed-off-by: David Leong <116610336+leongdl@users.noreply.github.com>
@leongdl
leongdl force-pushed the bump-openjd-rust-deps branch from c52f9b0 to d083e72 Compare September 1, 2026 16:47
Comment thread rust-bindings/Cargo.toml
openjd-expr = "0.4.0"
openjd-model = "0.5.2"
openjd-sessions = "0.5.2"
openjd-expr = "0.5.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.

openjd-expr 0.4.0 → 0.5.0 is a SemVer-breaking bump, and the ExprRevision mirror in rust-bindings/src/expr/profile.rs is exactly the shape that silently absorbs a new upstream variant:

  • PyExprRevision has a single member V2026_02 (profile.rs:52-53).
  • From<ExprRevision> for PyExprRevision (profile.rs:105-114) carries #[allow(unreachable_patterns)] _ => PyExprRevision::V2026_02, so a new upstream revision is reported to Python as V2026_02 — including __str__() == "2026-02".
  • PyExprRevision::CURRENT (profile.rs:61) is a hardcoded const, not derived from ExprRevision::CURRENT. If 0.5.0 moved CURRENT forward, ExprProfile() builds the profile with the new upstream CURRENT (profile.rs:395 reads ExprRevision::CURRENT directly) while profile.revision and ExprRevision.CURRENT both report V2026_02. Those two disagree, and pickle round-trips through __init__(revision=...) (profile.rs:544) would rewrite the revision.

Because the catch-all makes the match compile, cargo build / cargo clippy -D warnings cannot flag this, and I could not find any Python-side test that pins the binding's ExprRevision member set against upstream. Contrast ModelExtension, which has test/openjd/model_v1/test_version_enums.py::TestModelExtension precisely because this failure mode already shipped once (the WRAP_ACTIONS regression documented in that test's docstring, where the catch-all silently aliased a new variant to EXPR).

Suggest confirming against openjd-expr 0.5.0 that ExprRevision gained no variant and ExprRevision::CURRENT is still V2026_02, and adding a drift guard for ExprRevision (and PyExprRevision::CURRENT vs ExprRevision::CURRENT) analogous to TestModelExtension so the next bump fails loudly instead of silently mislabelling the revision.

Comment thread rust-bindings/Cargo.toml
openjd-model = "0.5.2"
openjd-sessions = "0.5.2"
openjd-expr = "0.5.0"
openjd-model = "0.5.4"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

openjd-model 0.5.2 → 0.5.4: worth checking whether either patch release added a ModelExtension variant, because the existing drift guard cannot detect that.

test/openjd/model_v1/test_version_enums.py::TestModelExtension asserts _rust_extension_members() == {e.value for e in ExtensionName} — but both sides of that equality are in-repo mirrors:

  • _rust_extension_members() reflects over PyModelExtension (rust-bindings/src/model/profile.rs:182-188), maintained by hand in this repo.
  • ExtensionName is the Python enum in src/openjd/model/v2023_09/_model.py:105, also maintained by hand in this repo.

Neither is compared against openjd_model::types::ModelExtension upstream. So if 0.5.4 added a variant and neither mirror was updated, both sets stay equal, the guard passes, and From<ModelExtension> for PyModelExtension (profile.rs:268-269) silently aliases the new variant to EXPR — the exact failure the test's own docstring describes for WRAP_ACTIONS. Guarding mirror-against-mirror only catches the two mirrors drifting apart from each other, not both drifting away from upstream.

The same gap applies to SpecificationRevision (profile.rs:146-154, catch-all _ => PySpecificationRevision::V2023_09), which has no member-set guard at all.

A guard rooted in upstream truth would close this — e.g. expose ModelExtension::ALL / SpecificationRevision's variants through a test-only binding and assert the Python member set matches it, so a bump like this one fails in CI rather than silently mislabelling an extension. Related to my note on openjd-expr/ExprRevision above.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not applicable - we own the end to end.

Comment thread rust-bindings/Cargo.toml
pyo3-log = "0.13"
log = "0.4"
pyo3-stub-gen = { version = "0.22", optional = true }
pyo3-stub-gen = { version = "0.23", optional = true }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This bump does not do anything useful, and it leaves the stub-generation path in a state where src/openjd/_openjd_rs.pyi cannot be regenerated at all.

The commit message says 0.23.0 still references PyEncodingWarning unguarded, so --features stub-gen cannot compile under abi3-py39. scripts/generate_stubs.sh claims to work around that with a patched clone (line 8: "We use a patched local copy at /tmp/pyo3-stub-gen"), but nothing actually redirects the resolver there — there is no [patch.crates-io] entry for pyo3-stub-gen in either rust-bindings/Cargo.toml or the workspace root Cargo.toml. So line 24 of generate_stubs.sh:

cargo build --manifest-path rust-bindings/Cargo.toml --features stub-gen --bin stub_gen

resolves pyo3-stub-gen 0.23.0 from crates.io and hits the same PyEncodingWarning error the clone was meant to patch. The clone at /tmp/pyo3-stub-gen is dead weight.

That matters beyond this PR because _openjd_rs.pyi is checked in and I could not find any CI job that regenerates it and diffs the result (rust_quality.yml runs fmt/build/clippy/test/doc; nothing references generate_stubs.sh or the .pyi). With the generator unbuildable and no freshness check, the committed stub can silently drift from the actual bindings — and dependency bumps like this one are exactly when the surface shifts.

Two things would help: add the missing [patch.crates-io] for pyo3-stub-gen (workspace root, since cargo ignores [patch] in member manifests — the comment at Cargo.toml:8 already notes this) so the documented workaround actually takes effect, and refresh the stale header comment on generate_stubs.sh:7, which still says "pyo3-stub-gen 0.21" and reads as a fixed-in-newer-versions note when the bug persists at 0.23.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Just part of our patching up grade story.

@leongdl
leongdl merged commit 10c0b29 into OpenJobDescription:mainline Sep 1, 2026
31 checks passed
@leongdl
leongdl deleted the bump-openjd-rust-deps branch September 1, 2026 20:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants