Skip to content

Move the release version under foundry's [external] section - #136

Merged
thedavidmeister merged 1 commit into
mainfrom
2026-08-18-issue-133-external-package
Aug 18, 2026
Merged

Move the release version under foundry's [external] section#136
thedavidmeister merged 1 commit into
mainfrom
2026-08-18-issue-133-external-package

Conversation

@thedavidmeister

Copy link
Copy Markdown
Contributor

Closes#133

foundry.toml opened with a bare [package]. foundry reads any root section it
does not reserve as a profile, so every forge invocation printed:

Warning: Found unknown config section in foundry.toml: [package]
This notation for profiles has been deprecated and may result in the profile not being registered in future versions.
Please use [profile.package] instead or run `forge config --fix`.

The section is now [external.package] and LibRainDeploySnapshot.deployTag
reads .external.package.version. forge config on this branch prints no such
warning. Same change, same section, as rain.sol.codegen
rainlanguage/rain.sol.codegen#143.

Verified at source, at this repo's pinned toolchain

The flake here resolves forge 1.7.2-nightly at 43923a4e, and at that SHA:

  • Config::is_standalone_section returns true for EXTERNAL_SECTION
    (crates/config/src/lib.rs:718-722). WarningsProvider::collect_warnings
    emits UnknownSection for exactly the root keys that predicate rejects
    (crates/config/src/providers/warnings.rs), and forge config --fix filters
    by the same predicate (crates/config/src/fix.rs:146). external is NOT in
    STANDALONE_SECTIONS, so nothing under it is merged into a profile either —
    which is why name/version under it cannot raise UnknownKey the way they
    would under [profile.package].
  • soldeer never reads the section. That SHA's Cargo.lock pins
    soldeer-core 0.10.1, whose crates/core/src/config.rs contains the string
    packagezero times. rainix-tag-release publishes with
    forge soldeer push "$SOLDEER_PACKAGE~$VERSION" — name and version off the
    command line, not out of the file.

The release path is unchanged, measured rather than assumed

This is a tag-released repo, so the one automated writer of that line is
rainix-tag-release's bump —
sed -i -E "0,/^version[[:space:]]*=.*/s//version = \"${VERSION}\"/" foundry.toml
followed by a grep -qxE that fails the release loudly if it matched nothing.
Run against both files with VERSION=0.1.6:

foundry.tomlsed resultgrep -qxE
ed91bfa (main)one line changed, version = "0.1.5" -> version = "0.1.6"match
this branchone line changed, version = "0.1.5" -> version = "0.1.6"match

It anchors on the first line beginning version with no section awareness, and
that line is still first and unindented. foundry.toml is also in
.soldeerignore, so the published package's bytes never contained it.

Ramification: what a consuming repo must declare

LibRainDeploySnapshot is published and deployTag(vm) reads the CONSUMING
repo's foundry.toml, so a repo that calls it must carry its release version at
[external.package].version. Consumers pin exact versions, so nothing moves for
anyone until they bump, and this repo's own version only advances on a sol-v*
tag — this PR publishes nothing. The library's @dev note now names that key
next to the fs_permissions entry it already required.

Adversarial mutation pass

Committed before mutating. Every run is the WHOLE suite with no filter, because
a filter is the trap this repo sets: LibAddressRegistryDeploy's address and
codehash pins fail under any change to compiler input, so a filter that includes
them reports KILLED for everything and measures nothing. They stay green in all
five runs below, which is what shows the suite discriminating rather than
collapsing.

#MutationSuite ranNon-RPC failuresKilled by
M0none (baseline)311 tests, 260 passed / 51 failed0
M1foundry.toml: [external.package] -> [package]311 tests, 251 / 609testReleaseVersionLivesUnderTheExternalSection + the 8 deployTag readers
M2reader path -> .package.version311 tests, 252 / 598testDeployTagUsesTheGuardedConversion + 7 freeze tests
M3reader path -> .external.package.name311 tests, 252 / 598the same 8, via UnreleasableVersion("rain-deploy")
M4keep the working read, append a SECOND bare [package]311 tests, 259 / 521testReleaseVersionLivesUnderTheExternalSection ONLY
M5foundry.toml: [external.package] -> [profile.package]311 tests, 251 / 609the same 9 as M1

5 killed, 0 survived. The 51 failures in every row are the unchanged
*_RPC_URL not found baseline.

M4 is what earns the new test. The read still resolves, the release path is
intact and every pre-existing test passes; the only thing that fails is
assertFalse(vm.keyExistsToml(config, ".package")). Without that half of the
assertion, a repo could grow the warning back with a green suite. M5 is the
mirror: [profile.package] silences the .package half and fails the
.external.package.version half, so both assertions are load-bearing and the
test pins external specifically rather than "not [package]".

Checks

  • nix develop -c forge config: the [package] warning is present on ed91bfa
    and absent on this branch; the only line left on stderr is the unrelated
    nightly-build notice, which ed91bfa prints too.
  • nix develop -c forge test: 260 passed / 51 failed / 311 total, against
    259 / 51 / 310 on ed91bfa. The +1 is the new test; no other count moves, and
    all 51 are *_RPC_URL not found.
  • nix develop -c forge fmt --check: exit 0.

QA

  • Discriminating tests: testReleaseVersionLivesUnderTheExternalSection in
    test/src/lib/LibRainDeploySnapshot.t.sol — fails on base, verified by
    running it against ed91bfa's foundry.toml as mutant M1 above
    ([external.package] -> [package], [FAIL: assertion failed]).
    testDeployTagUsesTheGuardedConversion and the seven freeze tests fail on
    base too once the reader moves (M2/M3). The test's subject is deployTag's
    source of truth, so it mirrors src/lib/LibRainDeploySnapshot.sol; it reads
    foundry.toml the way testSupportedNetworksAreFullyConfigured already reads
    it for [rpc_endpoints]/[etherscan] — config, not prose.
  • Mutations applied: foundry.toml:5[external.package] -> [package] ->
    testReleaseVersionLivesUnderTheExternalSection + 8 deployTag readers;
    foundry.toml gains a second bare [package] alongside the working read ->
    testReleaseVersionLivesUnderTheExternalSection alone;
    foundry.toml:5 -> [profile.package] -> the same 9;
    src/lib/LibRainDeploySnapshot.sol:101".external.package.version" ->
    ".package.version" -> testDeployTagUsesTheGuardedConversion + 7 freeze
    tests; the same line -> ".external.package.name" -> the same 8 via
    UnreleasableVersion("rain-deploy"). 5 applied, 5 killed, 0 survived; full
    table with per-run suite counts above.
  • Oracle: foundry's and soldeer's own source at the toolchain this repo pins —
    is_standalone_section/STANDALONE_SECTIONS and fix.rs at 43923a4e,
    soldeer-core 0.10.1crates/core/src/config.rs — plus rainix-tag-release's
    bump sed/grep run against the real file. Not the warning text, and not
    this repo's own code.
  • Category check: the issue asks for (a) [package] -> [external.package]
    with version left unindented and first, (b) a comment saying the section is
    another tool's metadata rather than foundry config, (c) prose naming
    [package].version fixed in the same pass, and (d) the version reader proven
    byte-identical before and after. Covered a, b, c, d. (d) is the
    rainix-tag-release bump rather than rainix-static soldeer-gate: this repo
    is tag-released, package-release.yaml calls rainix-tag-release.yaml, and
    soldeer-gate runs only in rainix-autopublish.yaml, which this repo never
    invokes. Both anchor identically on the first ^version[[:space:]]*= line.
    Beyond the issue: this repo has a reader the issue's precedent repo does not —
    LibRainDeploySnapshot.deployTag really parses the TOML — so the path moves
    with the section, which is the coordination the issue's closing note
    sequences.

foundry read the bare [package] as an unregistered profile and warned on
every invocation. [external.*] is the section it reserves for another
tool's config and ignores, so the release metadata moves there and the
reader follows it to .external.package.version.
@thedavidmeisterthedavidmeister self-assigned this Aug 18, 2026
@coderabbitai

Copy link
Copy Markdown

Warning

Review limit reached

@thedavidmeister, you've reached your PR review limit, so we couldn't start this review.

Next review available in:26 minutes

Limit details: You’ve used all 1 included review currently available under your plan.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 685b2c72-c25a-492f-8dbc-4be66999d445

📥 Commits

Reviewing files that changed from the base of the PR and between ed91bfa and 3fa8c17.

📒 Files selected for processing (6)
  • .github/workflows/package-release.yaml
  • CLAUDE.md
  • README.md
  • foundry.toml
  • src/lib/LibRainDeploySnapshot.sol
  • test/src/lib/LibRainDeploySnapshot.t.sol

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.

@thedavidmeister
thedavidmeister merged commit 74260ae into mainAug 18, 2026
4 checks passed
Sign up for freeto 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.

foundry.toml's bare [package] warns on every forge invocation, and forge's suggested fix makes it worse

2 participants

@thedavidmeister@claude