with one click
add-spec-version
// Add support for a new Ignition specification version to ignition-config-rs
// Add support for a new Ignition specification version to ignition-config-rs
| name | add-spec-version |
| description | Add support for a new Ignition specification version to ignition-config-rs |
Automates adding a new Ignition specification version to the crate:
src/v3_X/) to create the new onemod.rssrc/lib.rs (module, enum variant, parse branch, test)docs/release-notes.mdignition.json schema and regenerates schema.rscargorustfmt installed# Add a new spec version (schema identical to previous)
/add-spec-version 3.7.0
# Add a new spec version with a new JSON schema
/add-spec-version 3.7.0 --schema path/to/ignition.json
Parse the version argument to extract components. The argument is required.
NEW_VERSION = argument (e.g., "3.7.0")
NEW_MAJOR = 3
NEW_MINOR = 7 (extracted from version)
PREV_MINOR = NEW_MINOR - 1
NEW_MOD = v3_7
PREV_MOD = v3_6
NEW_VARIANT = V3_7
Verify:
src/{PREV_MOD}/ existssrc/{NEW_MOD}/ does NOT existgit status --porcelain produces no outputIf any check fails, stop and report the issue.
Run:
cp -r src/{PREV_MOD} src/{NEW_MOD}
Create the first commit:
git add src/{NEW_MOD}
git commit -m "Copy {NEW_MOD} spec from {PREV_MOD}
Pure cp -r src/{PREV_MOD} src/{NEW_MOD}."
Edit src/{NEW_MOD}/mod.rs. Find the line:
pub(crate) const VERSION: Version = Version::new(3, {PREV_MINOR}, 0);
Replace with:
pub(crate) const VERSION: Version = Version::new(3, {NEW_MINOR}, 0);
If the user provided a --schema path:
ignition.json to src/{NEW_MOD}/ignition.jsoncargo build --features regenerate to regenerate schema.rssrc/{NEW_MOD}/schema.rs to check for:
Option<String> -> String)schema.rs changes introduced new required fields on existing structs, update mod.rs:
Default impls need updatingIgnition::default() needs new fieldsschema.rs was modified (only src/{NEW_MOD}/schema.rs should change)If no schema was provided, skip this step.
src/lib.rsMake exactly 4 insertions in src/lib.rs:
5a. Module declaration -- Find the line pub mod {PREV_MOD}; and insert after it:
pub mod {NEW_MOD};
5b. Config enum variant -- Find {PREV_VARIANT}({PREV_MOD}::Config), in the Config enum and insert after it:
{NEW_VARIANT}({NEW_MOD}::Config),
5c. Parse branch -- Find the block:
} else if version == {PREV_MOD}::VERSION {
Self::{PREV_VARIANT}(parse_warn(v, &mut warnings)?)
} else {
return Err(Error::UnknownVersion(version));
Insert before the } else { / UnknownVersion line:
} else if version == {NEW_MOD}::VERSION {
Self::{NEW_VARIANT}(parse_warn(v, &mut warnings)?)
5d. Test case -- Find the end of the last version's test block in fn parse(). Look for the line:
assert!(warnings.is_empty());
}
#[test]
fn round_trip() {
Insert BEFORE the closing } of the parse() test (i.e., before #[test] fn round_trip):
let mut expected = {NEW_MOD}::Config::default();
expected
.storage
.get_or_insert_with(Default::default)
.files
.get_or_insert_with(Default::default)
.push({NEW_MOD}::File::new("/z".into()));
let (config, warnings) = Config::parse_str(
r#"{{"ignition": {{"version": "{NEW_VERSION}"}}, "storage": {{"files": [{{"path": "/z"}}]}}}}"#,
)
.unwrap();
assert_eq!(config, Config::{NEW_VARIANT}(expected));
assert!(warnings.is_empty());
Edit docs/release-notes.md. Find the first ## heading (the "Upcoming" section) and add the bullet point after the heading line:
- Add Ignition {NEW_VERSION} spec
If there is already content under the heading, add it as the first bullet. If there is a blank line after the heading, insert the bullet after that blank line.
Run all validation commands:
cargo build --all-targets
cargo build --all-targets --features regenerate
cargo test --all-targets
cargo clippy --all-targets -- -D warnings
All must pass. If any fail, fix the issue before proceeding.
After the regenerate build, check that no generated files changed unexpectedly:
git status --porcelain
The only modified files should be in src/{NEW_MOD}/ and src/lib.rs and docs/release-notes.md.
git add -A
git commit -m "Update for {NEW_VERSION} spec"
Summarize what was done:
This skill automates the following from the spec addition process:
ignition.json)mod.rs changes if schema introduces breaking structural changes (e.g., required fields becoming optional, new top-level config sections)Adding Ignition spec version 3.7.0...
Pre-flight checks:
- src/v3_6/ exists
- src/v3_7/ does not exist
- Working tree is clean
Step 1: Copying src/v3_6 -> src/v3_7
Created: src/v3_7/ignition.json
Created: src/v3_7/mod.rs
Created: src/v3_7/schema.rs
Committed: "Copy v3_7 spec from v3_6"
Step 2: Updating VERSION in src/v3_7/mod.rs
Version::new(3, 6, 0) -> Version::new(3, 7, 0)
Step 3: Wiring into src/lib.rs
Added: pub mod v3_7
Added: V3_7(v3_7::Config) enum variant
Added: v3_7::VERSION parse branch
Added: v3_7 test case
Step 4: Updating docs/release-notes.md
Added: "- Add Ignition 3.7.0 spec"
Step 5: Building and testing
cargo build --all-targets .............. OK
cargo build --features regenerate ...... OK
cargo test --all-targets ............... OK (X tests passed)
cargo clippy ........................... OK (no warnings)
Committed: "Update for 3.7.0 spec"
Done! 2 commits created. Files changed:
- src/v3_7/ignition.json (new)
- src/v3_7/mod.rs (new, VERSION updated)
- src/v3_7/schema.rs (new)
- src/lib.rs (4 insertions)
- docs/release-notes.md (1 insertion)
Next steps:
1. Review the changes with `git log -2 -p`
2. Push the branch and open a PR
.opencode/skills/add-spec-version/DESIGN.md.opencode/skills/add-spec-version/examples/v3_6-simple.md.opencode/skills/add-spec-version/examples/v3_5-with-schema-changes.mdDEVELOPMENT.md.github/workflows/rust.ymlbuild.rs