Skip to content

chore: single source of truth for the release version#477

Merged
pratyush618 merged 5 commits into
masterfrom
chore/version-sync-tooling
Jul 20, 2026
Merged

chore: single source of truth for the release version#477
pratyush618 merged 5 commits into
masterfrom
chore/version-sync-tooling

Conversation

@kartikeya-27

@kartikeya-27 kartikeya-27 commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

The version was hardcoded in nine places across four ecosystems, kept in step by hand and
spot-checked by three different ad-hoc greps in the publish preflights. This makes the root
Cargo.toml the only place it is written, and makes drift a CI failure instead of something
discovered at publish time.

Fewer places to begin with

Two of the duplications had a native fix, so they are gone rather than scripted:

  • Javagroup/version move to sdks/java/gradle.properties, which Gradle applies to
    the root project and every subproject. Five build scripts stop repeating them. Verified by
    generating the Maven POMs: coordinates are byte-identical (org.byteveda:taskito:0.20.0,
    taskito-spring, taskito-processor, taskito-test).
  • Pythonpyproject.toml declares dynamic = ["version"]; maturin already reads the
    version off the crate at tool.maturin.manifest-path, so the wheel cannot drift from the
    core it wraps. Verified: uv sync builds taskito==0.20.0 and taskito.__version__ is
    unchanged at runtime.

scripts/version.mjs

Source of truth: [workspace.package].version in the root Cargo.toml.

node scripts/version.mjs --check       # fail on drift
node scripts/version.mjs --current     # print the declared version
node scripts/version.mjs --set 0.21.0  # bump the source and every mirror

Three mirrors remain (no native path exists): sdks/node/package.json,
sdks/java/gradle.properties, and the source-tree __version__ fallback in
sdks/python/taskito/__init__.py.

CHANGELOG.md is checked but never written — its top ## X.Y.Z section must match, so a
version cannot ship without release notes. The docs changelog page and landing-page badge are
already generated from that file, so they follow for free.

--check also guards against re-hardcoding: it fails if any crates/*/Cargo.toml,
sdks/python/pyproject.toml, or sdks/java/**/build.gradle.kts restates a version instead of
deriving one.

CI

  • New unfiltered versions job in ci.yml — runs on every PR and push, takes seconds.
  • All three publish preflights now run --check and compare the resolved tag against
    --current, replacing their per-SDK greps. This also fixes publish-java.yml, whose grep
    targeted the build.gradle.kts line this PR removes.

Verification

  • node scripts/version.mjs --check green; --set round-tripped 0.20.0 → 0.99.1 → 0.20.0
    with a clean diff, and drift/guard failures confirmed by hand.
  • ./gradlew generatePomFileForMavenPublication across all four published projects.
  • uv sync + uv run ruff check + uv run mypy taskito/ tests/ green.

Summary by CodeRabbit

  • Improvements
    • Added centralized version validation and synchronization across project packages via a dedicated version CLI.
    • CI now verifies version consistency (via a new versions check) before finishing successfully.
    • Publish workflows perform stricter preflight checks to ensure the resolved publish version matches the repository’s declared version.
    • Java build configuration and Python package metadata now inherit version info from shared configuration.
    • Added automated validation that the changelog includes an entry for the current version.
  • Maintenance
    • Enhanced the changelog sync script with a --help option.

Gradle applies both to the root project and every subproject, so the five build scripts no longer repeat them.
maturin reads it off the crate at tool.maturin.manifest-path, so the wheel cannot drift from the core it wraps.
One source of truth plus a --check mode, so drift is detectable instead of discovered at publish time.
Replaces three bespoke per-SDK version asserts in the publish preflights with the shared check.
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fdef4ee6-613a-4acf-8f6e-d1684ce7e5b5

📥 Commits

Reviewing files that changed from the base of the PR and between 4972b88 and 5817e84.

📒 Files selected for processing (2)
  • scripts/sync-changelog.mjs
  • scripts/version.mjs
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/version.mjs

📝 Walkthrough

Walkthrough

This change adds scripts/version.mjs as the canonical version checker and updater, moves SDK version declarations to shared or derived metadata, and integrates version validation into CI and Java, Node, and Python publishing workflows.

Changes

Version synchronization

Layer / File(s) Summary
Version validation and updates
scripts/version.mjs
Adds --check, --current, and --set commands for validating, reporting, and rewriting repository version fields, mirror files, guards, and changelog entries.
SDK version configuration
sdks/java/gradle.properties, sdks/java/*/build.gradle.kts, sdks/python/pyproject.toml, sdks/python/taskito/__init__.py
Moves Java coordinates to shared Gradle properties, removes module-level hardcoded versions, and makes the Python package version dynamic from Rust metadata.
CI and release version gates
.github/workflows/ci.yml, .github/workflows/publish*.yml
Adds CI version validation and updates Java, Node, and Python publish preflight checks to use the centralized version script.
Changelog synchronization help
scripts/sync-changelog.mjs
Adds --help and -h handling with usage text and a successful early exit.

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

Sequence Diagram(s)

sequenceDiagram
  participant CIOrPublish as CI or publish workflow
  participant VersionScript as scripts/version.mjs
  participant Repository as Repository version files
  CIOrPublish->>VersionScript: Run --check
  VersionScript->>Repository: Read canonical and mirrored versions
  VersionScript-->>CIOrPublish: Return validation status
  CIOrPublish->>VersionScript: Run --current
  VersionScript-->>CIOrPublish: Return declared version
  CIOrPublish->>CIOrPublish: Compare resolved release version
Loading

Possibly related PRs

Suggested labels: rust

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: centralizing release version management into a single source of truth.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/version-sync-tooling

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.

🧹 Nitpick comments (1)
scripts/version.mjs (1)

55-60: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Filter the crates directory entries to avoid ENOENT errors on files.

readdirSync returns all entries, including files like .DS_Store or .gitkeep. Attempting to read crates/.DS_Store/Cargo.toml will throw an ENOENT error and crash the script. Filter for directories only to make it resilient.

♻️ Proposed fix
-  const crates = readdirSync(abs("crates")).map((crate) => ({
-    file: `crates/${crate}/Cargo.toml`,
+  const crates = readdirSync(abs("crates"), { withFileTypes: true })
+    .filter((dirent) => dirent.isDirectory())
+    .map((dirent) => ({
+      file: `crates/${dirent.name}/Cargo.toml`,
       pattern: /^version = "/m,
       hint: "use `version.workspace = true`",
     }));
🤖 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 `@scripts/version.mjs` around lines 55 - 60, Update the crates collection in
guards() to include only directory entries from readdirSync(abs("crates"))
before constructing Cargo.toml paths, preventing files such as .DS_Store or
.gitkeep from being processed. Preserve the existing file, pattern, and hint
mappings for valid crate directories.
🤖 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.

Nitpick comments:
In `@scripts/version.mjs`:
- Around line 55-60: Update the crates collection in guards() to include only
directory entries from readdirSync(abs("crates")) before constructing Cargo.toml
paths, preventing files such as .DS_Store or .gitkeep from being processed.
Preserve the existing file, pattern, and hint mappings for valid crate
directories.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ff398bf0-c23b-4274-8076-f211b3ae9203

📥 Commits

Reviewing files that changed from the base of the PR and between 8209da4 and 4972b88.

📒 Files selected for processing (13)
  • .github/workflows/ci.yml
  • .github/workflows/publish-java.yml
  • .github/workflows/publish-node.yml
  • .github/workflows/publish.yml
  • scripts/version.mjs
  • sdks/java/build.gradle.kts
  • sdks/java/graalvm-smoke/build.gradle.kts
  • sdks/java/gradle.properties
  • sdks/java/processor/build.gradle.kts
  • sdks/java/spring/build.gradle.kts
  • sdks/java/test-support/build.gradle.kts
  • sdks/python/pyproject.toml
  • sdks/python/taskito/__init__.py
💤 Files with no reviewable changes (5)
  • sdks/java/build.gradle.kts
  • sdks/java/graalvm-smoke/build.gradle.kts
  • sdks/java/test-support/build.gradle.kts
  • sdks/java/spring/build.gradle.kts
  • sdks/java/processor/build.gradle.kts

@kartikeya-27
kartikeya-27 requested a review from pratyush618 July 20, 2026 19:02
@pratyush618
pratyush618 merged commit d5d0e98 into master Jul 20, 2026
33 checks passed
@pratyush618
pratyush618 deleted the chore/version-sync-tooling branch July 20, 2026 19:35
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.

2 participants