Skip to content

Commit 4072e48

Browse files
zerosnacksfigtracerAmpmablrpepyakin
authored
chore(release): v1.7.1 (#14640)
* fix(cheatcodes): fix solc 0.8.35 error keyword warning (#14509) fix(cheatcodes): avoid solc error keyword warning (cherry picked from commit f0bd9bb) * chore: bump compiler version to 0.8.35 for tests (#14524) * bump compiler version for tests * fix CI: update gas snapshots and bump svm-rs to 0.5.25 Amp-Thread-ID: https://ampcode.com/threads/T-019dddbd-7f28-72cc-965b-d5a23ecb37ce Co-authored-by: Amp <amp@ampcode.com> * make fmt Amp-Thread-ID: https://ampcode.com/threads/T-019dddbd-7f28-72cc-965b-d5a23ecb37ce Co-authored-by: Amp <amp@ampcode.com> * fix: add blockTimestamp to LegacyTransactionResult for testRpcTransactionByHash DRPC now returns a blockTimestamp field, which shifts ABI decoding offsets and breaks the test. Amp-Thread-ID: https://ampcode.com/threads/T-019dddbd-7f28-72cc-965b-d5a23ecb37ce Co-authored-by: Amp <amp@ampcode.com> --------- Co-authored-by: Amp <amp@ampcode.com> (cherry picked from commit 470d048) * fix(ci): use `PATH_USD` fallback fee token in Mail templates (#14546) (cherry picked from commit e8d0d89) * fix(forge): ignore ETH_RPC_URL for test forking (#14555) Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Co-authored-by: Mablr <59505383+mablr@users.noreply.github.com> (cherry picked from commit 6c9bbea) * fix(cli): fix jsonwebtoken panic (#14562) `cast` panicked with this message coming from jsonwebtoken: ``` Call CryptoProvider::install_default() before this point to select a provider manually, or make sure exactly one of the 'rust_crypto' and 'aws_lc_rs' features is enabled. See the documentation of the CryptoProvider type for more information. ``` This seemingly was introduced with the bump of jsonwebtoken to 10. Now it requires you to pick one backend used by default controlled by the compile time cargo features or call `CryptoProvider::install_default()` at the beginning. I realized that probably it would be better to just select the feature and I picked `aws_lc_rs` as it seems to be increasingly a default and we already are using the C toolchain. Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> (cherry picked from commit 6e40f56) * ci: sign release archives, docker images, and publish SBOMs (#14563) - release.yml: emit per-archive sha256 + SPDX SBOM (Syft), cosign keyless sign-blob of the archive, and use actions/attest@v4 for both build provenance and SBOM attestations. Upload all artifacts to the draft release. - docker-publish.yml: enable BuildKit SBOM, capture the build digest, cosign keyless sign each pushed tag, and publish a Sigstore-signed SLSA provenance attestation via actions/attest with push-to-registry. - SECURITY.md: document how external users verify archives and the docker image (gh attestation, cosign, plain sha256, buildx imagetools). - README.md: link to the new verification section. (cherry picked from commit 3e7f0ed) * fix(ci): increase permissions for the enhanced attestation writing (#14584) * increase permissions for artifact writing * apply write permissions to release-docker (cherry picked from commit 1fd6466) * fix(forge): encode Tempo creates as AA calls (#14585) (cherry picked from commit 8b44ae6) * fix(cli): fix release version strings for immutable tags, bump to 1.7.1 (#14496) * Fix release version metadata for immutable tags Amp-Thread-ID: https://ampcode.com/threads/T-019dd617-b29f-7409-8523-9858a1504f17 Co-authored-by: Amp <amp@ampcode.com> * Derive nightly release suffix from commit SHA Amp-Thread-ID: https://ampcode.com/threads/T-019dd617-b29f-7409-8523-9858a1504f17 Co-authored-by: Amp <amp@ampcode.com> * Apply suggestion from @zerosnacks * Apply suggestion from @zerosnacks * Apply suggestion from @zerosnacks * bump to v1.7.1 * avoid appending whole sha hash, not necessary, handle version cmp correctly. after v1.7.1 release we need to bump to v1.7.2 for nightlies following it to compare correctly * Make foundryVersionCmp tolerate new version format and add tests - Strip both pre-release ('-nightly', '-dev') and build metadata ('+<sha>.<ts>.<profile>') from SEMVER_VERSION before comparison so the cheatcode keeps working for tagged releases (which have no '-' separator). - Extract strip_semver_metadata helper and add Rust unit tests covering all SEMVER_VERSION shapes, version_cmp ordering, and parse_version rejection of pre-release/build/garbage input. - Extend the Solidity test suite for vm.getFoundryVersion()/foundryVersionCmp/foundryVersionAtLeast: validate MAJOR.MINOR.PATCH parseability, build profile value, cmp/atLeast invariant, and error paths for invalid user-supplied versions. Amp-Thread-ID: https://ampcode.com/threads/T-019dd971-fcb7-7149-9680-f0134130844c Co-authored-by: Amp <amp@ampcode.com> * fix(test): drop view from solidity tests using assert helpers and fix fmt - assertTrue/assertEq aren't view, so testGetFoundryVersionBuildProfile and testFoundryVersionCmpAndAtLeastAreConsistent can't be view either. - Collapse the buildType assertion onto one line to satisfy forge fmt. Amp-Thread-ID: https://ampcode.com/threads/T-019dd971-fcb7-7149-9680-f0134130844c Co-authored-by: Amp <amp@ampcode.com> * test(version): assert build profile is non-empty instead of debug|release The dist profile (used for distributed release binaries) is also valid; just require non-empty so any future profile works. Amp-Thread-ID: https://ampcode.com/threads/T-019dd971-fcb7-7149-9680-f0134130844c Co-authored-by: Amp <amp@ampcode.com> * Normalize nightly-<sha> to nightly in release_version Ensures tarball and Docker nightly artifacts produce the same version string. The commit identifier is already included in the SemVer build metadata (after `+`), so collapsing `nightly-<sha>` to `nightly` avoids duplicating the SHA in the pre-release tag. Co-authored-by: Amp <amp@ampcode.com> Amp-Thread-ID: https://ampcode.com/threads/T-019df79e-d4c9-707c-85eb-2efbf59160b3 --------- Co-authored-by: Centaur AI <ai@centaur.local> Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Co-authored-by: zerosnacks <zerosnacks@protonmail.com> (cherry picked from commit a70d4aa) * fix(evm): query `state_snapshot.storage` in `ForkDbStateSnapshot::storage_ref` (#14007) * fix(evm): query `state_snapshot.storage` in `ForkDbStateSnapshot::storage_ref` * test(evm): cover `ForkDbStateSnapshot::storage_ref` snapshot lookup (cherry picked from commit fa5429a) * fix(cast): consistent `--json` output for `keychain` subcommands (#14590) - `keychain rl`: wrap remaining limit in `{"remaining":"..."}` object instead of emitting a bare JSON string - `keychain policy add-call`: emit `{"status":"already_present","target":"..."}` when the rule already exists, instead of plain text - `send_keychain_tx`: wrap sponsor hash in `{"sponsor_hash":"0x..."}` object when --tempo.print-sponsor-hash is used with --json Add CLI tests covering the rl and sponsor-hash JSON output shapes. (cherry picked from commit 7916719) * fix(cheatcodes): transfer value for payable mock calls (#14547) * test: updated tests * fix: execute value transfer * test: improve * imp: review item * test: vm.prank test * imp: moved mocked-call handling after prank application --------- Co-authored-by: Mablr <59505383+mablr@users.noreply.github.com> (cherry picked from commit f2e09d2) * fix(forge): `--fuzz-seed` parameter is not effective in `forge coverage` (#14610) fix --fuzz-seed not effective in forge coverage (cherry picked from commit bd9cf55) * fix(cheatcodes): enforce `expectRevert` reverter address for CREATE frames (#14615) * fix(cheatcodes): enforce `expectRevert` reverter address for CREATE frames The reverter address argument to `vm.expectRevert` was silently ignored when the innermost reverting frame was a CREATE (top-level or nested), because create_end never populated `expected_revert.reverted_by`. Mirror call_end's logic in create_end: when the outcome reverts and a reverter address is expected, record outcome.address (revm guarantees this is Some(would-be address) whenever the constructor executed). Adds positive regression tests for top-level and nested-CREATE reverts, and a negative regression test asserting wrong-reverter now fails. Co-authored-by: Amp <amp@ampcode.com> * improve coverage * add Derek's suggested test cases * fix: forge fmt for ExpectRevert.t.sol Amp-Thread-ID: https://ampcode.com/threads/T-019dfdc5-5414-70b6-9f49-cb5797a37a29 Co-authored-by: Amp <amp@ampcode.com> --------- Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> (cherry picked from commit 85cd75c) * fix(cheatcodes): preserve reverts with `expectEmit` (#14619) * test: added regression test * fix: re-order revert handling * refactor: simplify * lint: fmt * polish: tighten comment, extend test with revert reason and custom error Amp-Thread-ID: https://ampcode.com/threads/T-019dfd96-7a03-7249-8c10-af20ee2729f5 Co-authored-by: Amp <amp@ampcode.com> --------- Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Co-authored-by: Amp <amp@ampcode.com> (cherry picked from commit 2e8ae6c) * fix(evm): preserve `CREATE` address on revert in isolation mode (#14637) (cherry picked from commit 9584c6c) * chore(clippy): fix for_kv_map and useless_borrows_in_formatting (#14554) * chore(clippy): fix for_kv_map and useless_borrows_in_formatting Amp-Thread-ID: https://ampcode.com/threads/T-019df0f9-62e7-74b8-bd5e-da2acce678fb Co-authored-by: Amp <amp@ampcode.com> * chore(clippy): drop redundant borrows in cheatcodes assert formatters Amp-Thread-ID: https://ampcode.com/threads/T-019df0f9-62e7-74b8-bd5e-da2acce678fb Co-authored-by: Amp <amp@ampcode.com> --------- Co-authored-by: Amp <amp@ampcode.com> (cherry picked from commit 84d3873) * fix(ext): bump forge-std commit in external integration tests (#14504) bump forge commit (cherry picked from commit 024820c) * chore(tests): bump forge-std version (#14510) chore: bump forge-std version used for tests Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> (cherry picked from commit 5766929) * fix(config): suppress spurious unknown-key warning for `network` (#14534) * fix(config): suppress spurious unknown-key warning for `network` The `network` field in `NetworkConfigs` had `skip_serializing_if = "Option::is_none"`, so it was missing from the serialized default `Config`. The warnings provider builds its allowed-keys set from that serialized default, so a valid `network = "tempo"` entry in foundry.toml triggered: Warning: Found unknown `network` config for profile `default` defined in foundry.toml. Replace `skip_serializing_if` with `#[serde(default)]` so `network` appears (as null) in the default config and is recognized as a known profile key. TOML output is unchanged (None is omitted by toml-rs); only the JSON snapshot in `test_default_config` needed updating. Amp-Thread-ID: https://ampcode.com/threads/T-019ddec8-2f04-7255-b8bf-70c1ce2a996d Co-authored-by: Amp <amp@ampcode.com> * test(config): add regression tests for network/tempo unknown-key warnings Cover both the new `network = "tempo"` form and the legacy `tempo = true` alias to ensure neither triggers UnknownKey warnings. Amp-Thread-ID: https://ampcode.com/threads/T-019ddec8-2f04-7255-b8bf-70c1ce2a996d Co-authored-by: Amp <amp@ampcode.com> * fix(config): canonicalize network field on serialization Previously, with `network = "tempo"` set, `forge config` would emit both: network = "tempo" tempo = false which is misleading — the legacy boolean alias contradicts the resolved network. Conversely, with `tempo = true` (legacy), the output omitted `network` entirely, hiding the actual resolved network. Make `NetworkConfigs` use a custom `Serialize` impl that: - Always emits the *resolved* network as the canonical `network = "..."` field. - Never emits the legacy `tempo` / `optimism` boolean aliases (they are still accepted as deserialize-only aliases for backward compatibility). - Continues to emit `celo` and `bypass_prevrandao` as before. This ensures consistent output regardless of input form: network = "tempo" (canonical) → network = "tempo" tempo = true (legacy) → network = "tempo" optimism = true (legacy) → network = "optimism" Both legacy keys are added to `BACKWARD_COMPATIBLE_KEYS` in the warnings provider so they don't trigger unknown-key warnings on input. Test snapshots updated accordingly. Amp-Thread-ID: https://ampcode.com/threads/T-019ddec8-2f04-7255-b8bf-70c1ce2a996d Co-authored-by: Amp <amp@ampcode.com> * style: cargo fmt Amp-Thread-ID: https://ampcode.com/threads/T-019ddec8-2f04-7255-b8bf-70c1ce2a996d Co-authored-by: Amp <amp@ampcode.com> --------- Co-authored-by: Amp <amp@ampcode.com> (cherry picked from commit 95bf101) * feat(forge): use network = "tempo" and add rpc_endpoints in tempo template (#14528) * feat(forge): use network = "tempo" and add rpc_endpoints in tempo template Amp-Thread-ID: https://ampcode.com/threads/T-019dddff-1855-752f-b136-bd0465462ac8 Co-authored-by: Amp <amp@ampcode.com> * feat(forge): add eth_rpc_url = "tempo" to tempo template Amp-Thread-ID: https://ampcode.com/threads/T-019dddff-1855-752f-b136-bd0465462ac8 Co-authored-by: Amp <amp@ampcode.com> * style: cargo fmt Amp-Thread-ID: https://ampcode.com/threads/T-019dddff-1855-752f-b136-bd0465462ac8 Co-authored-by: Amp <amp@ampcode.com> * fix: drop eth_rpc_url from tempo template (would silently fork all tests) Amp-Thread-ID: https://ampcode.com/threads/T-019dddff-1855-752f-b136-bd0465462ac8 Co-authored-by: Amp <amp@ampcode.com> * refactor: build tempo template foundry.toml in a single toml serialize Amp-Thread-ID: https://ampcode.com/threads/T-019dddff-1855-752f-b136-bd0465462ac8 Co-authored-by: Amp <amp@ampcode.com> --------- Co-authored-by: Amp <amp@ampcode.com> (cherry picked from commit 323bceb) * ci(tempo): align ci-tempo workflow with master, drop fork-schedule test step Backport of CI Tempo workflow updates (#14501, #14537, #14556) so the v1.7.1 release branch matches master: - Devnet checks run on PR and push (re-enabled) - Devnet wallet tests run on PR and push - Testnet/mainnet checks moved to nightly schedule only - Nightly failure issue creation The 'Check Tempo fork schedule compatibility' step is intentionally omitted: the underlying tempo::tests::test_fork_schedule_parses_configured_rpcs test was added in #14485 (Tempo deps bump) which is not part of v1.7.1. Amp-Thread-ID: https://ampcode.com/threads/T-019e01cd-cea5-72e8-8338-5f0594e06335 Co-authored-by: Amp <amp@ampcode.com> --------- Co-authored-by: figtracer <me@figtracer.com> Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: Mablr <59505383+mablr@users.noreply.github.com> Co-authored-by: Sergei Shulepov <s.pepyakin@gmail.com> Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> Co-authored-by: Derek Cofausper <256792747+decofe@users.noreply.github.com> Co-authored-by: Centaur AI <ai@centaur.local> Co-authored-by: zerosnacks <zerosnacks@protonmail.com> Co-authored-by: Nikki <gutonosa@protonmail.com> Co-authored-by: srdtrk <59252793+srdtrk@users.noreply.github.com> Co-authored-by: lazymio <mio@lazym.io> Co-authored-by: stevencartavia <112043913+stevencartavia@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent f83bad9 commit 4072e48

62 files changed

Lines changed: 1348 additions & 472 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
title: "bug: tempo nightly workflow failed"
3+
labels: P-high, T-bug
4+
---
5+
6+
The nightly Tempo workflow (mainnet and testnet checks) has failed. This indicates a regression in Foundry's Tempo support or an issue with the Tempo mainnet/testnet endpoints.
7+
8+
Check the [tempo nightly workflow page]({{ env.WORKFLOW_URL }}) for details.
9+
10+
This issue was raised by the workflow at `.github/workflows/ci-tempo.yml`.

.github/workflows/ci-tempo.yml

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ on:
66
push:
77
branches: [master]
88
pull_request:
9+
schedule:
10+
- cron: "0 2 * * *" # Run daily at 2 AM UTC (offset from other nightlies)
911
workflow_dispatch:
1012
inputs:
1113
network:
@@ -59,36 +61,28 @@ jobs:
5961
cargo build --profile dev --locked -p forge -p cast -p anvil -p chisel
6062
echo "${{ github.workspace }}/target/debug" >> "$GITHUB_PATH"
6163
62-
# TODO: re-enable once devnet is up and stable
63-
# - name: Run Tempo check on devnet
64-
# if: |
65-
# github.event_name == 'pull_request' ||
66-
# github.event.inputs.network == 'devnet' ||
67-
# github.event.inputs.network == 'all'
68-
# env:
69-
# ETH_RPC_URL: ${{ secrets.TEMPO_DEVNET_RPC_URL }}
70-
# SCRIPTS: ${{ github.event.inputs.scripts || 'both' }}
71-
# run: |
72-
# if [ "$SCRIPTS" = "check" ] || [ "$SCRIPTS" = "both" ]; then
73-
# ./.github/scripts/tempo-check.sh
74-
# fi
75-
# if [ "$SCRIPTS" = "deploy" ] || [ "$SCRIPTS" = "both" ]; then
76-
# ./.github/scripts/tempo-deploy.sh
77-
# fi
78-
79-
# TODO: re-enable once devnet is up and stable
80-
# - name: Run Tempo wallet tests on devnet
81-
# if: |
82-
# github.event_name == 'pull_request' ||
83-
# github.event.inputs.network == 'devnet' ||
84-
# github.event.inputs.network == 'all'
85-
# env:
86-
# ETH_RPC_URL: ${{ secrets.TEMPO_DEVNET_RPC_URL }}
87-
# run: ./.github/scripts/tempo-wallet.sh
64+
- name: Run Tempo check on mainnet
65+
if: |
66+
github.event_name == 'schedule' ||
67+
github.event.inputs.network == 'mainnet' ||
68+
github.event.inputs.network == 'all'
69+
env:
70+
ETH_RPC_URL: ${{ secrets.TEMPO_MAINNET_RPC_URL }}
71+
TEMPO_FEE_TOKEN: "0x20c0000000000000000000000000000000000000"
72+
VERIFIER_URL: ${{ secrets.VERIFIER_URL }}
73+
PRIVATE_KEY: ${{ secrets.THROW_AWAY_MAINNET_PKEY }}
74+
SCRIPTS: ${{ github.event.inputs.scripts || 'both' }}
75+
run: |
76+
if [ "$SCRIPTS" = "check" ] || [ "$SCRIPTS" = "both" ]; then
77+
./.github/scripts/tempo-check.sh
78+
fi
79+
if [ "$SCRIPTS" = "deploy" ] || [ "$SCRIPTS" = "both" ]; then
80+
./.github/scripts/tempo-deploy.sh
81+
fi
8882
8983
- name: Run Tempo check on testnet
9084
if: |
91-
github.event_name == 'pull_request' ||
85+
github.event_name == 'schedule' ||
9286
github.event.inputs.network == 'testnet' ||
9387
github.event.inputs.network == 'all'
9488
env:
@@ -103,15 +97,14 @@ jobs:
10397
./.github/scripts/tempo-deploy.sh
10498
fi
10599
106-
- name: Run Tempo check on mainnet
100+
- name: Run Tempo check on devnet
107101
if: |
108-
github.event.inputs.network == 'mainnet' ||
102+
github.event_name == 'push' ||
103+
github.event_name == 'pull_request' ||
104+
github.event.inputs.network == 'devnet' ||
109105
github.event.inputs.network == 'all'
110106
env:
111-
ETH_RPC_URL: ${{ secrets.TEMPO_MAINNET_RPC_URL }}
112-
TEMPO_FEE_TOKEN: "0x20c0000000000000000000000000000000000000"
113-
VERIFIER_URL: ${{ secrets.VERIFIER_URL }}
114-
PRIVATE_KEY: ${{ secrets.THROW_AWAY_MAINNET_PKEY }}
107+
ETH_RPC_URL: ${{ secrets.TEMPO_DEVNET_RPC_URL }}
115108
SCRIPTS: ${{ github.event.inputs.scripts || 'both' }}
116109
run: |
117110
if [ "$SCRIPTS" = "check" ] || [ "$SCRIPTS" = "both" ]; then
@@ -120,3 +113,35 @@ jobs:
120113
if [ "$SCRIPTS" = "deploy" ] || [ "$SCRIPTS" = "both" ]; then
121114
./.github/scripts/tempo-deploy.sh
122115
fi
116+
117+
- name: Run Tempo wallet tests on devnet
118+
if: |
119+
github.event_name == 'push' ||
120+
github.event_name == 'pull_request' ||
121+
github.event.inputs.network == 'devnet' ||
122+
github.event.inputs.network == 'all'
123+
env:
124+
ETH_RPC_URL: ${{ secrets.TEMPO_DEVNET_RPC_URL }}
125+
run: ./.github/scripts/tempo-wallet.sh
126+
127+
# If the nightly run fails, this will create an issue to signal so.
128+
issue:
129+
name: Open an issue
130+
runs-on: ubuntu-latest
131+
needs: [tempo-check]
132+
if: failure() && github.event_name == 'schedule'
133+
permissions:
134+
contents: read
135+
issues: write
136+
steps:
137+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
138+
with:
139+
persist-credentials: false
140+
- uses: JasonEtco/create-an-issue@1b14a70e4d8dc185e5cc76d3bec9eab20257b2c5 # v2.9.2
141+
env:
142+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
143+
WORKFLOW_URL: |
144+
${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
145+
with:
146+
update_existing: true
147+
filename: .github/TEMPO_NIGHTLY_FAILURE_TEMPLATE.md

.github/workflows/docker-publish.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ jobs:
3232
name: build and push
3333
runs-on: depot-ubuntu-latest
3434
permissions:
35+
attestations: write
36+
artifact-metadata: write
3537
contents: read
3638
id-token: write
3739
packages: write
@@ -92,6 +94,7 @@ jobs:
9294
uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1.7.1
9395

9496
- name: Build and push Foundry image
97+
id: build
9598
uses: depot/build-push-action@5f3b3c2e5a00f0093de47f657aeaefcedff27d18 # v1.17.0
9699
with:
97100
build-args: |
@@ -106,3 +109,30 @@ jobs:
106109
platforms: linux/amd64,linux/arm64
107110
push: true
108111
no-cache: true
112+
sbom: true
113+
provenance: mode=max
114+
115+
- name: Install cosign
116+
uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1
117+
118+
- name: Sign image with cosign (keyless)
119+
env:
120+
DOCKER_TAGS: ${{ steps.docker_tagging.outputs.docker_tags }}
121+
DIGEST: ${{ steps.build.outputs.digest }}
122+
shell: bash
123+
run: |
124+
set -euo pipefail
125+
IFS=',' read -r -a tags <<< "$DOCKER_TAGS"
126+
for tag in "${tags[@]}"; do
127+
# Strip any tag suffix and pin to immutable digest, then sign.
128+
ref="${tag%%:*}@${DIGEST}"
129+
printf 'Signing %s\n' "$ref"
130+
cosign sign --yes "$ref"
131+
done
132+
133+
- name: Image build provenance attestation
134+
uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0
135+
with:
136+
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
137+
subject-digest: ${{ steps.build.outputs.digest }}
138+
push-to-registry: true

.github/workflows/release.yml

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ jobs:
7171
7272
- name: Build changelog
7373
id: build_changelog
74-
uses: mikepenz/release-changelog-builder-action@bcae7115752d4ed746ff92feb666574428a79415 # v6.2
74+
uses: mikepenz/release-changelog-builder-action@bcae7115752d4ed746ff92feb666574428a79415 # v6.2.1
7575
with:
7676
configuration: "./.github/changelog.json"
7777
fromTag: ${{ steps.release_info.outputs.from_tag || '' }}
@@ -117,6 +117,8 @@ jobs:
117117
needs: prepare
118118
uses: ./.github/workflows/docker-publish.yml
119119
permissions:
120+
attestations: write
121+
artifact-metadata: write
120122
contents: read
121123
id-token: write
122124
packages: write
@@ -129,9 +131,10 @@ jobs:
129131
# way, GitHub's immutable-releases setting seals the release at publish.
130132
release:
131133
permissions:
132-
id-token: write
133-
contents: write
134134
attestations: write
135+
artifact-metadata: write
136+
contents: write
137+
id-token: write
135138
name: release ${{ matrix.target }} (${{ matrix.runner }})
136139
runs-on: ${{ matrix.runner }}
137140
timeout-minutes: 240
@@ -264,6 +267,38 @@ jobs:
264267
printf "file_name=%s\n" "foundry_${VERSION_NAME}_${PLATFORM_NAME}_${ARCH}.zip" >> "$GITHUB_OUTPUT"
265268
fi
266269
printf "foundry_attestation=%s\n" "foundry_${VERSION_NAME}_${PLATFORM_NAME}_${ARCH}.attestation.txt" >> "$GITHUB_OUTPUT"
270+
printf "foundry_sbom=%s\n" "foundry_${VERSION_NAME}_${PLATFORM_NAME}_${ARCH}.spdx.json" >> "$GITHUB_OUTPUT"
271+
printf "foundry_checksum=%s\n" "foundry_${VERSION_NAME}_${PLATFORM_NAME}_${ARCH}.sha256" >> "$GITHUB_OUTPUT"
272+
printf "foundry_signature=%s\n" "foundry_${VERSION_NAME}_${PLATFORM_NAME}_${ARCH}.sigstore.json" >> "$GITHUB_OUTPUT"
273+
274+
- name: Generate archive checksum
275+
env:
276+
FILE_NAME: ${{ steps.artifacts.outputs.file_name }}
277+
FOUNDRY_CHECKSUM: ${{ steps.artifacts.outputs.foundry_checksum }}
278+
shell: bash
279+
run: |
280+
set -euo pipefail
281+
if command -v sha256sum >/dev/null 2>&1; then
282+
sha256sum "$FILE_NAME" > "$FOUNDRY_CHECKSUM"
283+
else
284+
shasum -a 256 "$FILE_NAME" > "$FOUNDRY_CHECKSUM"
285+
fi
286+
cat "$FOUNDRY_CHECKSUM"
287+
288+
- name: Install Syft
289+
uses: anchore/sbom-action/download-syft@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0
290+
291+
- name: Generate SBOM (SPDX)
292+
env:
293+
FOUNDRY_SBOM: ${{ steps.artifacts.outputs.foundry_sbom }}
294+
VERSION_NAME: ${{ (env.IS_NIGHTLY == 'true' && 'nightly') || needs.prepare.outputs.tag_name }}
295+
shell: bash
296+
run: |
297+
set -euo pipefail
298+
syft scan dir:. \
299+
--source-name foundry \
300+
--source-version "$VERSION_NAME" \
301+
-o spdx-json="$FOUNDRY_SBOM"
267302
268303
- name: Upload build artifacts
269304
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
@@ -292,15 +327,37 @@ jobs:
292327
tar -czvf "foundry_man_${VERSION_NAME}.tar.gz" forge.1.gz cast.1.gz anvil.1.gz chisel.1.gz
293328
printf 'foundry_man=%s\n' "foundry_man_${VERSION_NAME}.tar.gz" >> "$GITHUB_OUTPUT"
294329
295-
- name: Binaries attestation
330+
- name: Binaries and archive provenance attestation
296331
id: attestation
297-
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
332+
uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0
298333
with:
299334
subject-path: |
300335
${{ env.anvil_bin_path }}
301336
${{ env.cast_bin_path }}
302337
${{ env.chisel_bin_path }}
303338
${{ env.forge_bin_path }}
339+
${{ steps.artifacts.outputs.file_name }}
340+
341+
- name: Archive SBOM attestation
342+
uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0
343+
with:
344+
subject-path: ${{ steps.artifacts.outputs.file_name }}
345+
sbom-path: ${{ steps.artifacts.outputs.foundry_sbom }}
346+
347+
- name: Install cosign
348+
uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1
349+
350+
- name: Sign archive with cosign (keyless)
351+
env:
352+
FILE_NAME: ${{ steps.artifacts.outputs.file_name }}
353+
FOUNDRY_SIGNATURE: ${{ steps.artifacts.outputs.foundry_signature }}
354+
shell: bash
355+
run: |
356+
set -euo pipefail
357+
cosign sign-blob \
358+
--yes \
359+
--bundle "$FOUNDRY_SIGNATURE" \
360+
"$FILE_NAME"
304361
305362
- name: Record attestation URL
306363
env:
@@ -321,11 +378,20 @@ jobs:
321378
TAG_NAME: ${{ needs.prepare.outputs.tag_name }}
322379
FILE_NAME: ${{ steps.artifacts.outputs.file_name }}
323380
FOUNDRY_ATTESTATION: ${{ steps.artifacts.outputs.foundry_attestation }}
381+
FOUNDRY_SBOM: ${{ steps.artifacts.outputs.foundry_sbom }}
382+
FOUNDRY_CHECKSUM: ${{ steps.artifacts.outputs.foundry_checksum }}
383+
FOUNDRY_SIGNATURE: ${{ steps.artifacts.outputs.foundry_signature }}
324384
FOUNDRY_MAN: ${{ steps.man.outputs.foundry_man }}
325385
shell: bash
326386
run: |
327387
set -euo pipefail
328-
files=("$FILE_NAME" "$FOUNDRY_ATTESTATION")
388+
files=(
389+
"$FILE_NAME"
390+
"$FOUNDRY_ATTESTATION"
391+
"$FOUNDRY_SBOM"
392+
"$FOUNDRY_CHECKSUM"
393+
"$FOUNDRY_SIGNATURE"
394+
)
329395
if [[ -n "${FOUNDRY_MAN:-}" ]]; then
330396
files+=("$FOUNDRY_MAN")
331397
fi

0 commit comments

Comments
 (0)