2026-07-15 20:12:56 -03:00

530 lines
17 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: |
# Guest packages generate colliding output names, so document them
# separately below with isolated target directories.
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
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
integration-tests-prepare:
runs-on: ubuntu-24.04
timeout-minutes: 60
outputs:
integration-matrix: ${{ steps.publish-matrix.outputs.integration-matrix }}
auth-transfer-artifact-id: ${{ steps.publish-matrix.outputs.auth-transfer-artifact-id }}
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 integration test targets
run: |
target_dir="$RUNNER_TEMP/integration-test-targets"
mkdir -p "$target_dir"
cargo metadata \
--no-deps \
--format-version 1 > "$target_dir/metadata.json"
jq -r '
[.packages[]
| select(.name == "integration_tests")
| .targets[]
| select(.kind | index("test"))
| select(.name != "tps")
| .name]
| sort
| unique[]
' "$target_dir/metadata.json" > "$target_dir/discovered.targets"
if [[ ! -s "$target_dir/discovered.targets" ]]; then
echo "No non-tps integration test targets were discovered." >&2
exit 1
fi
target_count="$(wc -l < "$target_dir/discovered.targets")"
if (( target_count > 64 )); then
echo "More than 64 integration targets were discovered." >&2
exit 1
fi
{
echo "### Integration target archives"
echo
echo "| Target | Archive size |"
echo "| --- | ---: |"
} >> "$GITHUB_STEP_SUMMARY"
- name: Install Node.js for workflow artifact client
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24
- name: Install workflow artifact client
run: |
npm ci \
--prefix .github/scripts/artifact-client \
--ignore-scripts \
--omit=dev \
--no-audit \
--no-fund
- name: Build and upload integration test targets
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
ARTIFACT_CLIENT_SCRIPT: ${{ github.workspace }}/.github/scripts/artifact-client/upload.mjs
INTEGRATION_ARTIFACT_DIR: ${{ runner.temp }}/integration-test-targets
INTEGRATION_ARTIFACT_MANIFEST: ${{ runner.temp }}/integration-test-targets/uploaded.jsonl
INTEGRATION_TARGETS_FILE: ${{ runner.temp }}/integration-test-targets/discovered.targets
RISC0_DEV_MODE: "1"
with:
script: |
const { pathToFileURL } = await import("node:url")
const artifactClient = await import(
pathToFileURL(process.env.ARTIFACT_CLIENT_SCRIPT)
)
await artifactClient.buildAndUploadIntegrationTargets({ core, exec })
- name: Publish integration test matrix
id: publish-matrix
run: |
target_dir="$RUNNER_TEMP/integration-test-targets"
jq -r .target "$target_dir/uploaded.jsonl" \
| sort > "$target_dir/uploaded.targets"
if ! diff -u \
"$target_dir/discovered.targets" \
"$target_dir/uploaded.targets"; then
echo "Every discovered integration target must be uploaded exactly once." >&2
exit 1
fi
integration_matrix="$(jq -s -c '{include: .}' \
"$target_dir/uploaded.jsonl")"
auth_transfer_artifact_id="$(jq -r \
'select(.target == "auth_transfer") | .artifact_id' \
"$target_dir/uploaded.jsonl")"
if [[ ! "$auth_transfer_artifact_id" =~ ^[0-9]+$ ]]; then
echo "The auth_transfer artifact ID is missing or invalid." >&2
exit 1
fi
echo "integration-matrix=$integration_matrix" >> "$GITHUB_OUTPUT"
echo "auth-transfer-artifact-id=$auth_transfer_artifact_id" \
>> "$GITHUB_OUTPUT"
- name: Release artifact client and target metadata disk
if: always()
run: |
rm -rf .github/scripts/artifact-client/node_modules
rm -rf "$RUNNER_TEMP/integration-test-targets"
- 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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: risc0-runtime-3.0.5
path: ${{ runner.temp }}/risc0-runtime/r0vm
compression-level: 6
retention-days: 1
if-no-files-found: error
overwrite: true
- name: Release staged RISC Zero runtime disk
if: always()
run: rm -f "$RUNNER_TEMP/risc0-runtime/r0vm"
integration-tests:
needs:
- test-fixtures-tests
- integration-tests-prepare
runs-on: ubuntu-24.04
timeout-minutes: 90
strategy:
fail-fast: false
max-parallel: 30
matrix: ${{ fromJSON(needs.integration-tests-prepare.outputs.integration-matrix) }}
name: integration-tests (${{ matrix.target }})
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 archive
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
artifact-ids: ${{ matrix.artifact_id }}
path: ${{ runner.temp }}/integration-test-target
skip-decompress: true
- name: Run integration test target
env:
ARCHIVE_NAME: ${{ matrix.archive }}
RISC0_DEV_MODE: "1"
RUST_LOG: info
TARGET: ${{ matrix.target }}
run: |
if [[ ! "$TARGET" =~ ^[a-z0-9_]+$ ]]; then
echo "Invalid integration test target: $TARGET" >&2
exit 2
fi
expected_archive="integration-test-$TARGET.tar.zst"
if [[ "$ARCHIVE_NAME" != "$expected_archive" ]]; then
echo "Archive $ARCHIVE_NAME does not match target $TARGET." >&2
exit 2
fi
archive="$RUNNER_TEMP/integration-test-target/$ARCHIVE_NAME"
extract_dir="$RUNNER_TEMP/nextest-target"
echo "::group::Archive and disk usage before extraction"
du -h "$archive"
df -h "$RUNNER_TEMP"
echo "::endgroup::"
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"
echo "::group::Disk usage after extraction"
du -sh "$extract_dir"
df -h "$RUNNER_TEMP"
echo "::endgroup::"
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 target extraction." >&2
df -h "$RUNNER_TEMP" >&2
exit 1
fi
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" \
--show-progress none \
--success-output immediate \
--status-level all \
--final-status-level all \
--no-output-indent \
-E "binary(=$TARGET)"
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 auth_transfer integration test archive
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
artifact-ids: ${{ needs.integration-tests-prepare.outputs.auth-transfer-artifact-id }}
path: ${{ runner.temp }}/integration-test-target
skip-decompress: true
- name: Test valid proof
env:
RISC0_INFO: "1"
RUST_LOG: info,risc0_zkvm::host::client::prove::external=debug,risc0_zkvm::host::server::prove=debug,risc0_zkvm::host::recursion::prove=debug
run: |
archive="$RUNNER_TEMP/integration-test-target/integration-test-auth_transfer.tar.zst"
extract_dir="$RUNNER_TEMP/nextest-target"
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"
echo "Starting non-development RISC Zero succinct proof."
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" \
--no-capture \
--show-progress none \
-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"