Repository navigation
Description
Problem
The per-version snapshot canon (src/generated/<tag>/) is copy-pasted across repos and has already diverged — including on a safety property.
deployTag() is byte-identical in three script/BuildPointers.sol files today, and a fourth copy is pending:
| repo | deployTag() |
freezing | immutability guard |
|---|---|---|---|
| rainlanguage/raindex | ✅ copy | freezeSnapshot() |
✅ |
| S01-Issuer/st0x.deploy | ✅ copy | inline vm.createDir + a divergent deployTags() (plural) |
❌ |
| rainlanguage/rain.factory | ✅ copy | inline vm.createDir |
❌ |
| rainlanguage/rain.math.float | (pending #253) | freezeSnapshot() |
✅ |
Every copy of deployTag() is the same six lines:
string memory version = vm.parseTomlString(vm.readFile("foundry.toml"), ".package.version");
// ...dots -> underscores...The divergence already costs something real: the guard that reverts rather than rewrite a frozen snapshot without a [package].version bump exists in only two of four. In the other two, regenerating over an existing tag silently rewrites the deployment record consumers pin against. rainix's frozen-snapshots-append-only action backstops this in CI, but that is catching after the fact what the generator itself should refuse to do — and the local guard is what gives the author the actionable message ("bump [package].version for a new release") at the moment they'd otherwise corrupt history.
st0x.deploy has drifted further still, with a plural deployTags() and a different invariant ("BuildPointers: current tag dir missing"), so the repos no longer even agree on what the canon is.
Why here
This is the natural home and already a dependency of every affected repo: each BuildPointers.sol imports LibFs and LibCodeGen from rain-sol-codegen. LibFs.buildFileForContract already owns "write a generated file for a contract" — "freeze that generated file per release tag" is the same concern, one step later.
Putting it here also means the guard ships with the mechanism, so a repo cannot adopt snapshots and accidentally omit the safety property.
Proposal
Add the snapshot helpers to rain-sol-codegen (e.g. LibSnapshot, or extend LibFs):
deployTag(Vm vm) returns (string memory)—foundry.toml[package].versionwith dots→underscores; the single definition of the tag form.freezeSnapshot(Vm vm, string[] memory names)— createsrc/generated/<tag>/, copy each named generated file in, and revert if an existing frozen file's content would change, with the bump-your-version message.
Then migrate the consumers to import it and delete their local copies:
- rainlanguage/raindex
- S01-Issuer/st0x.deploy (also reconciling its
deployTags()divergence) - rainlanguage/rain.factory (gains the guard it currently lacks)
- rainlanguage/rain.math.float (#253 — currently adding a fourth copy; should import instead once this exists)
Related
- Upstream the 'every published soldeer version has its frozen snapshot' check to rainix rainix#271 — upstreams the complementary "every published soldeer version has its snapshot" check to shared CI. Same theme: the canon's mechanism and its enforcement both belong in shared code, not re-implemented per repo.
- refactor(deploy): migrate deploy constants to the per-version snapshot canon rain.math.float#253 — the migration that surfaced this; it knowingly adds the fourth copy rather than block on this issue.
Activity