Skip to content

release: bump the IDL program version - #564

Open
kskalski wants to merge 2 commits into
solana-program:mainfrom
kskalski:ks/release_idl_version
Open

kskalski wants to merge 2 commits into
solana-program:mainfrom
kskalski:ks/release_idl_version

Conversation

@kskalski

@kskalski kskalski commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Problem

  • version drift
    • both IDL files carry the interface crate version
    • cargo release bumps the manifest, so the committed files fall behind
    • the IDL job regenerates the files, then compares them against the tree
    • the job fails after every release, so someone bumps the files by hand

Summary of Changes

  • replace the program version in both IDL files during a release, so the release commit carries them

Testing

A. Semver-job form — mirrors “Set Version” in solana-program/actions publish-rust.yml, run from the repo root:

cargo release minor --manifest-path interface/Cargo.toml \
  --no-tag --no-publish --no-push --no-confirm --execute
git show HEAD

B. Publish-job form — mirrors this repo’s make publish-rust-interface, run inside interface/. The extra --no-publish --no-push --no-tag flags keep the test off crates.io and the remote:

git reset --hard ks/release_idl_version
cd interface
cargo release minor --tag-name "interface@v{{version}}" --execute --no-confirm \
  --dependent-version fix --no-publish --no-push --no-tag
cd ..
git show HEAD

Result. Both forms produce a chore: Release commit containing these hunks:

diff --git a/idl.json b/idl.json
@@ -6,7 +6,7 @@
     "kind": "programNode",
     "name": "stake",
     "publicKey": "Stake11111111111111111111111111111111111111",
-    "version": "5.1.0",
+    "version": "5.2.0",
     "instructions": [
diff --git a/interface-idl.json b/interface-idl.json
@@ -6,7 +6,7 @@
     "kind": "programNode",
     "name": "stake",
     "publicKey": "Stake11111111111111111111111111111111111111",
-    "version": "5.1.0",
+    "version": "5.2.0",
     "instructions": [
diff --git a/interface/Cargo.toml b/interface/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "solana-stake-interface"
-version = "5.1.0"
+version = "5.2.0"
plus three Cargo.lock hunks moving solana-stake-interface from 5.1.0 to 5.2.0.

Problem
- version drift
  - both IDL files carry the interface crate version
  - `cargo release` bumps the manifest, so the committed files fall behind
  - the IDL job regenerates the files, then compares them against the tree
  - the job fails after every release, so someone bumps the files by hand

Summary of Changes
- replace the program version in both IDL files during a release, so the release commit carries them
@kskalski
kskalski marked this pull request as ready for review September 25, 2026 11:15
@kskalski
kskalski requested a review from joncinque September 25, 2026 11:16

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

Looks great to me! This is a great way to solve the problem, and I tested that it works. Just some nits to make it more robust.

cc @lorisleiva since we've discussed some sort of action to do this in the past. This seems like a very neat and easy solution

Comment thread interface/Cargo.toml Outdated

[package.metadata.release]
pre-release-replacements = [
{ file = "../idl.json", search = '("publicKey": "Stake11111111111111111111111111111111111111",\n "version": ")[^"]+', replace = "${1}{{version}}", exactly = 1 },

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.

nit: in case we end up changing the spacing, can we make this slightly more robust?

Suggested change
{ file = "../idl.json", search = '("publicKey": "Stake11111111111111111111111111111111111111",\n "version": ")[^"]+', replace = "${1}{{version}}", exactly = 1 },
{ file = "../idl.json", search = '("publicKey":\s*"Stake11111111111111111111111111111111111111",\s*"version":\s*")[^"]+', replace = "${1}{{version}}", exactly = 1 },

Comment thread interface/Cargo.toml Outdated
[package.metadata.release]
pre-release-replacements = [
{ file = "../idl.json", search = '("publicKey": "Stake11111111111111111111111111111111111111",\n "version": ")[^"]+', replace = "${1}{{version}}", exactly = 1 },
{ file = "../interface-idl.json", search = '("publicKey": "Stake11111111111111111111111111111111111111",\n "version": ")[^"]+', replace = "${1}{{version}}", exactly = 1 },

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.

nit: same here

Suggested change
{ file = "../interface-idl.json", search = '("publicKey": "Stake11111111111111111111111111111111111111",\n "version": ")[^"]+', replace = "${1}{{version}}", exactly = 1 },
{ file = "../interface-idl.json", search = '("publicKey":\s*"Stake11111111111111111111111111111111111111",\s*"version":\s*")[^"]+', replace = "${1}{{version}}", exactly = 1 },

@lorisleiva

Copy link
Copy Markdown
Member

@joncinque If I understand correctly even though the Codama Macros already do use the Cargo.toml to get the IDL version, this is a post-release timing issue that keeps the IDL version to the previous one until it gets regenerated?

@joncinque

Copy link
Copy Markdown
Contributor

@joncinque If I understand correctly even though the Codama Macros already do use the Cargo.toml to get the IDL version, this is a post-release timing issue that keeps the IDL version to the previous one until it gets regenerated?

No not quite, this bumps the IDL version to the new / correct version after the crate is released. Currently, every time we bump the interface crate version, we immediately get CI failures because the IDL version is out of sync. This will make it so we avoid that extra manual step every time.

Unless the better option is to perform a post-bump step to re-run codama to pick up the newest version and commit it?

Problem
- the replacement pattern hardcodes the IDL's current spacing, so a reformat breaks the release

Summary of Changes
- match any whitespace around the `publicKey` and `version` fields
@kskalski

Copy link
Copy Markdown
Contributor Author

We could also run the full script as pre-release-hook, but I think the necessary plumbing is not worth it. At least as long as we are sure the full script only updates those release lines that the replacement catches.

@lorisleiva

Copy link
Copy Markdown
Member

Unless the better option is to perform a post-bump step to re-run codama to pick up the newest version and commit it?

That would have been my go-to solution yeah but I'm not sure how feasible it is to add this post-bump step to the Rust pipeline.

@lorisleiva

Copy link
Copy Markdown
Member

I think the necessary plumbing is not worth it

I don't disagree but I'm also not a fan of the fact that we end up with two places to check when it comes to IDL generation. But again I'm not sure how complex that plumbing is in Rust so happy with the current solution is the trade-off is not worth it.

@kskalski

Copy link
Copy Markdown
Contributor Author

Seems like it will boil down to something like this

[package.metadata.release]
pre-release-hook = ["sh", "-c", '[ "$DRY_RUN" = true ] || make -C "$WORKSPACE_ROOT" generate-idl-interface']

and the cost will be that the release pipeline needs to install the necessary tools... I agree this is cleaner, so let me prepare this one.

This branch has not been deployed

No deployments
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.

3 participants