Ricardo Guilherme Schmidt b780882bb0
ci: reuse bounded integration artifacts
Build target-specific nextest archives once and reuse each extraction across four host workers. Pin prebuilt tools and RISC Zero components, reduce duplicate cache writes, and preserve coverage checks.
2026-07-15 17:34:23 -03:00

464 lines
14 KiB
YAML

name: General
on:
push:
branches:
- main
- dev
paths-ignore:
- "**.md"
- "!.github/workflows/*.yml"
pull_request:
paths-ignore:
- "**.md"
- "!.github/workflows/*.yml"
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env:
CARGO_INCREMENTAL: "0"
CARGO_PROFILE_TEST_DEBUG: "0"
NEXTEST_VERSION: "0.9.140"
jobs:
fmt-rs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Install nightly toolchain for rustfmt
run: rustup install nightly-2026-04-14 --profile minimal --component rustfmt
- name: Check Rust files are formatted
run: cargo +nightly-2026-04-14 fmt --check
fmt-toml:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Install taplo-cli
uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2
with:
tool: taplo-cli@0.10.0
fallback: none
- name: Check TOML files are formatted
run: taplo fmt --check
machete:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Install active toolchain
run: rustup install --profile minimal
- name: Install cargo-machete
uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2
with:
tool: cargo-machete@0.9.2
fallback: none
- name: Check for unused dependencies
run: cargo machete
deny:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Install cargo-deny
uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2
with:
tool: cargo-deny@0.20.2
fallback: none
- name: Check licenses and advisories
run: cargo deny check
lint:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: ./.github/actions/install-system-deps
- name: Install active toolchain
run: rustup install --profile minimal --component clippy
- name: Restore Rust cache
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
shared-key: ci-rust-cache
cache-bin: false
save-if: false
- name: Lint workspace
env:
RISC0_SKIP_BUILD: "1"
run: cargo clippy --workspace --all-targets --all-features -- -D warnings
- name: Lint programs
env:
RISC0_SKIP_BUILD: "1"
run: cargo clippy -p "*program" -- -D warnings
- name: Check rustdoc links
env:
RISC0_SKIP_BUILD: "1"
RUSTDOCFLAGS: -D warnings
run: |
cargo doc \
--workspace \
--all-features \
--no-deps \
--exclude test_program_guests \
--exclude test_methods_guests
for package in test_program_guests test_methods_guests; do
cargo doc \
-p "$package" \
--all-features \
--no-deps \
--target-dir "$RUNNER_TEMP/rustdoc-$package"
done
unit-tests:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: ./.github/actions/install-system-deps
- name: Install active toolchain
run: rustup install --profile minimal
- uses: ./.github/actions/install-risc0
- name: Restore Rust cache
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
shared-key: ci-rust-cache
cache-bin: false
save-if: false
- name: Install nextest
uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2
with:
tool: nextest@${{ env.NEXTEST_VERSION }}
fallback: none
- name: Run tests
env:
RISC0_DEV_MODE: "1"
RUST_LOG: info
run: cargo nextest run --workspace --exclude integration_tests --exclude test_fixtures --all-features --no-fail-fast
test-fixtures-tests:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: ./.github/actions/install-system-deps
- name: Install active toolchain
run: rustup install --profile minimal
- uses: ./.github/actions/install-risc0
with:
profile: runtime
save-cache: "true"
- name: Restore Rust cache
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
shared-key: ci-rust-cache
cache-bin: false
save-if: false
- name: Install nextest
uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2
with:
tool: nextest@${{ env.NEXTEST_VERSION }}
fallback: none
- name: Run test_fixtures tests
env:
RISC0_DEV_MODE: "1"
RUST_LOG: info
run: cargo nextest run -p test_fixtures --no-fail-fast
integration-tests-prepare:
runs-on: ubuntu-24.04
timeout-minutes: 60
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: ./.github/actions/install-system-deps
- name: Install active toolchain
run: rustup install --profile minimal
- uses: ./.github/actions/install-risc0
with:
save-cache: "true"
- name: Restore Rust cache
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
shared-key: ci-rust-cache
cache-bin: false
save-if: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev' }}
- name: Install nextest
uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2
with:
tool: nextest@${{ env.NEXTEST_VERSION }}
fallback: none
- name: Discover and validate integration test shards
run: |
shard_dir="$RUNNER_TEMP/integration-test-shards"
mkdir -p "$shard_dir"
cargo metadata \
--no-deps \
--format-version 1 > "$shard_dir/metadata.json"
jq -r '
[.packages[]
| select(.name == "integration_tests")
| .targets[]
| select(.kind | index("test"))
| select(.name != "tps")
| .name]
| sort
| unique[]
' "$shard_dir/metadata.json" > "$shard_dir/discovered.targets"
shard_targets=(
"indexer_ffi_state_consistency keys token indexer_block_batching indexer_test_run_ffi shared_accounts account"
"amm cross_zone_bridge pinata indexer_state_consistency_with_labels indexer_test_run vault program_deployment"
"indexer_ffi_state_consistency_with_labels ata auth_transfer indexer_stall indexer_ffi_block_batching private_pda block_size_limit cross_zone_state_machine"
"cross_zone_verified two_zone bridge indexer_state_consistency cross_zone_ping wallet_ffi config cross_zone_ingress_guard"
)
for shard in "${!shard_targets[@]}"; do
targets_file="$shard_dir/$shard.targets"
filter_file="$shard_dir/$shard.filter"
tr ' ' '\n' <<< "${shard_targets[$shard]}" > "$targets_file"
awk '
{ printf "%s%s", separator, "binary(=" $0 ")"; separator = " | " }
END { print "" }
' "$targets_file" > "$filter_file"
done
sort "$shard_dir"/[0-3].targets > "$shard_dir/assigned.targets"
if ! diff -u "$shard_dir/discovered.targets" "$shard_dir/assigned.targets"; then
echo "Every non-tps integration binary must belong to exactly one shard." >&2
exit 1
fi
{
echo "### Integration archive shards"
echo
echo "| Shard | Archive size | Binaries |"
echo "| ---: | ---: | ---: |"
} >> "$GITHUB_STEP_SUMMARY"
- uses: ./.github/actions/build-integration-shard
with:
shard: "0"
- uses: ./.github/actions/build-integration-shard
with:
shard: "1"
- uses: ./.github/actions/build-integration-shard
with:
shard: "2"
- uses: ./.github/actions/build-integration-shard
with:
shard: "3"
- name: Stage RISC Zero runtime
run: |
mkdir -p "$RUNNER_TEMP/risc0-runtime"
install -m 0755 "$(command -v r0vm)" "$RUNNER_TEMP/risc0-runtime/r0vm"
- name: Upload RISC Zero runtime
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: risc0-runtime-3.0.5
path: ${{ runner.temp }}/risc0-runtime/r0vm
compression-level: 6
retention-days: 1
if-no-files-found: error
integration-tests:
needs:
- test-fixtures-tests
- integration-tests-prepare
runs-on: ubuntu-24.04
timeout-minutes: 90
strategy:
fail-fast: false
max-parallel: 4
matrix:
shard: [0, 1, 2, 3]
name: integration-tests (shard ${{ matrix.shard }})
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: ./.github/actions/restore-risc0-runtime
- name: Install nextest
uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2
with:
tool: nextest@${{ env.NEXTEST_VERSION }}
fallback: none
- name: Download integration test shard
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: integration-tests-${{ matrix.shard }}
path: ${{ runner.temp }}/integration-test-shard
- name: Run integration test shard
env:
RISC0_DEV_MODE: "1"
RUST_LOG: info
run: |
archive="$RUNNER_TEMP/integration-test-shard/integration-tests-${{ matrix.shard }}.tar.zst"
targets="$RUNNER_TEMP/integration-test-shard/${{ matrix.shard }}.targets"
extract_dir="$RUNNER_TEMP/nextest-shard"
mkdir -p "$extract_dir"
cargo-nextest nextest list \
--archive-file "$archive" \
--extract-to "$extract_dir" \
--workspace-remap "$GITHUB_WORKSPACE" \
--list-type binaries-only \
--message-format json \
--no-pager > /dev/null
rm -f "$archive"
available_kib="$(df --output=avail -k "$RUNNER_TEMP" | tail -n 1 | tr -d ' ')"
minimum_free_kib=$((6 * 1024 * 1024))
if (( available_kib < minimum_free_kib )); then
echo "Less than 6 GiB remains after shard extraction." >&2
df -h "$RUNNER_TEMP" >&2
exit 1
fi
common_args=(
--cargo-metadata "$extract_dir/target/nextest/cargo-metadata.json"
--binaries-metadata "$extract_dir/target/nextest/binaries-metadata.json"
--target-dir-remap "$extract_dir/target"
--workspace-remap "$GITHUB_WORKSPACE"
--no-fail-fast
)
failed=0
while IFS= read -r binary; do
echo "::group::integration binary: $binary"
if ! cargo-nextest nextest run "${common_args[@]}" -E "binary(=$binary)"; then
failed=1
fi
echo "::endgroup::"
done < "$targets"
exit "$failed"
valid-proof-test:
needs: integration-tests-prepare
runs-on: ubuntu-24.04
timeout-minutes: 90
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: ./.github/actions/restore-risc0-runtime
- name: Install nextest
uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2
with:
tool: nextest@${{ env.NEXTEST_VERSION }}
fallback: none
- name: Download integration test shard
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: integration-tests-2
path: ${{ runner.temp }}/integration-test-shard
- name: Test valid proof
env:
RUST_LOG: info
run: |
archive="$RUNNER_TEMP/integration-test-shard/integration-tests-2.tar.zst"
extract_dir="$RUNNER_TEMP/nextest-shard"
mkdir -p "$extract_dir"
cargo-nextest nextest list \
--archive-file "$archive" \
--extract-to "$extract_dir" \
--workspace-remap "$GITHUB_WORKSPACE" \
--list-type binaries-only \
--message-format json \
--no-pager > /dev/null
rm -f "$archive"
cargo-nextest nextest run \
--cargo-metadata "$extract_dir/target/nextest/cargo-metadata.json" \
--binaries-metadata "$extract_dir/target/nextest/binaries-metadata.json" \
--target-dir-remap "$extract_dir/target" \
--workspace-remap "$GITHUB_WORKSPACE" \
-E 'binary(=auth_transfer) & test(=private::private_transfer_to_owned_account)'
artifacts:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Install active toolchain
run: rustup install --profile minimal
- uses: ./.github/actions/install-risc0
with:
profile: build
- name: Restore Rust cache
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
shared-key: ci-rust-cache
cache-bin: false
save-if: false
- name: Install just
uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2
with:
tool: just@1.56.0
fallback: none
- name: Build artifacts
run: just build-artifacts
- name: Check if artifacts match repository
run: |
if ! git diff --exit-code artifacts/; then
echo "❌ Artifacts in the repository are out of date!"
echo "Please run 'just build-artifacts' and commit the changes."
exit 1
fi
echo "✅ Artifacts are up to date"