mirror of
https://github.com/logos-co/scaffold.git
synced 2026-08-30 22:21:11 +00:00
170 lines
7.9 KiB
YAML
170 lines
7.9 KiB
YAML
name: Template E2E
|
|
|
|
# End-to-end guard for the scaffolded project templates (#93). The unit tests
|
|
# only exercise the render *mechanics* (placeholder substitution, manifest
|
|
# overlay). This job actually renders a project with `new`, builds the real,
|
|
# network-fetched lez/spel at the configured pins via `setup`, and asserts
|
|
# `doctor` reports zero FAIL — so a `DEFAULT_LEZ` / `DEFAULT_SPEL` bump (or a
|
|
# template change) that produces an unbuildable user project breaks CI.
|
|
#
|
|
# Heavy (full LEZ build + circuits download + risc0 guest build), so it is
|
|
# path-gated to the inputs that can actually break the rendered output, plus
|
|
# manual `workflow_dispatch`.
|
|
|
|
on:
|
|
pull_request:
|
|
paths:
|
|
- "src/constants.rs"
|
|
- "templates/**"
|
|
- "src/template/**"
|
|
# Manual trigger for testing the job itself / re-validating a pin on demand.
|
|
# Intentionally not path-triggered by edits to this workflow file: a
|
|
# CI-config-only change shouldn't kick off the full (~tens-of-minutes) LEZ
|
|
# build of itself.
|
|
workflow_dispatch:
|
|
|
|
# A newer push to the same PR supersedes an in-flight (expensive) run.
|
|
concurrency:
|
|
group: template-e2e-${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
render-and-build:
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
template: [default, lez-framework]
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
|
|
- name: Cache cargo artifacts
|
|
uses: Swatinem/rust-cache@v2
|
|
|
|
# The bootstrap cache holds the cloned lez/spel repos and their target/
|
|
# dirs (~/.cache/logos-scaffold) AND the extracted circuits release
|
|
# (~/.logos-blockchain-circuits, where the fetch step below puts it).
|
|
# Both must be cached, or the multi-MB circuits tarball re-downloads on
|
|
# every run. Keying on constants.rs means a pin or circuits-version bump
|
|
# invalidates it (rebuild from scratch) while same-pin re-runs stay warm.
|
|
- name: Cache scaffold bootstrap (repos + circuits)
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: |
|
|
~/.cache/logos-scaffold
|
|
~/.logos-blockchain-circuits
|
|
key: scaffold-bootstrap-${{ runner.os }}-${{ hashFiles('src/constants.rs') }}
|
|
|
|
- name: Build scaffold CLI
|
|
run: cargo build --release --bin logos-scaffold
|
|
|
|
# The LEZ standalone build chain (logos-blockchain-{pol,poc,poq,zksign})
|
|
# reads circuit keys at compile time. setup's preflight requires the
|
|
# release on disk, so fetch the version pinned in constants.rs and export
|
|
# LOGOS_BLOCKCHAIN_CIRCUITS for every subsequent step.
|
|
- name: Fetch logos-blockchain-circuits release
|
|
run: |
|
|
set -euo pipefail
|
|
ver="$(sed -n 's/.*DEFAULT_CIRCUITS_VERSION: &str = "\([^"]*\)".*/\1/p' src/constants.rs)"
|
|
if [ -z "$ver" ]; then echo "could not parse DEFAULT_CIRCUITS_VERSION"; exit 1; fi
|
|
dest="$HOME/.logos-blockchain-circuits"
|
|
if [ -f "$dest/pol/verification_key.json" ]; then
|
|
echo "circuits already cached at $dest"
|
|
else
|
|
url="https://github.com/logos-blockchain/logos-blockchain-circuits/releases/download/v${ver}/logos-blockchain-circuits-v${ver}-linux-x86_64.tar.gz"
|
|
echo "downloading $url"
|
|
mkdir -p "$dest"
|
|
curl -fL --retry 3 -o /tmp/circuits.tar.gz "$url"
|
|
tar -xzf /tmp/circuits.tar.gz -C "$dest" --strip-components=1
|
|
fi
|
|
echo "LOGOS_BLOCKCHAIN_CIRCUITS=$dest" >> "$GITHUB_ENV"
|
|
|
|
- name: Render project from template
|
|
run: |
|
|
set -euo pipefail
|
|
cd "$RUNNER_TEMP"
|
|
"$GITHUB_WORKSPACE/target/release/logos-scaffold" new e2e-app --template "${{ matrix.template }}"
|
|
|
|
- name: Setup (clone + build lez/spel at configured pins)
|
|
run: |
|
|
set -euo pipefail
|
|
cd "$RUNNER_TEMP/e2e-app"
|
|
"$GITHUB_WORKSPACE/target/release/logos-scaffold" setup
|
|
|
|
- name: doctor --json asserts zero FAIL
|
|
run: |
|
|
# -e up front so a failing `cd` (or any setup command) aborts the step
|
|
# instead of silently running doctor from the wrong directory.
|
|
set -euo pipefail
|
|
cd "$RUNNER_TEMP/e2e-app"
|
|
# doctor exits 0 with no FAIL, and non-zero when summary.fail > 0 — but
|
|
# it can also exit non-zero *before* emitting JSON (e.g. failing to
|
|
# load the project). So disable -e only around the call, capture rc,
|
|
# then validate the JSON rather than `|| true`-ing the whole step
|
|
# (which would lose the status and degrade into a generic jq error).
|
|
set +e
|
|
"$GITHUB_WORKSPACE/target/release/logos-scaffold" doctor --json > doctor.json
|
|
rc=$?
|
|
set -e
|
|
if ! jq -e . doctor.json >/dev/null 2>&1; then
|
|
echo "::error::doctor did not emit valid JSON (exit $rc)"
|
|
cat doctor.json || true
|
|
exit 1
|
|
fi
|
|
fail="$(jq '.summary.fail' doctor.json)"
|
|
echo "doctor summary: $(jq -c '.summary' doctor.json) (exit $rc)"
|
|
if [ "$fail" != "0" ]; then
|
|
echo "::error::doctor reported $fail FAIL check(s) for the '${{ matrix.template }}' template"
|
|
jq -r '.checks[] | select(.status == "fail") | "FAIL: \(.name) — \(.detail)"' doctor.json
|
|
exit 1
|
|
fi
|
|
# Zero FAIL but a non-zero exit means doctor failed for a reason other
|
|
# than FAIL checks — surface it rather than treating the run as green.
|
|
if [ "$rc" -ne 0 ]; then
|
|
echo "::error::doctor exited $rc with zero FAIL — unexpected"
|
|
exit 1
|
|
fi
|
|
|
|
# The rendered project ships a risc0 guest crate (methods/), whose build
|
|
# script cross-compiles to riscv32im-risc0-zkvm-elf and needs the Risc Zero
|
|
# Rust toolchain. Without it the `logos-scaffold build` step below panics
|
|
# with "Risc Zero Rust toolchain not found. Try running `rzup install rust`".
|
|
# rzup is risc0's toolchain manager; it registers a `risc0` rustup
|
|
# toolchain that risc0-build then discovers.
|
|
- name: Install Risc Zero toolchain
|
|
run: |
|
|
set -euo pipefail
|
|
# Download the official rzup installer to disk first rather than
|
|
# piping it straight into bash: a failed/partial fetch is caught
|
|
# before anything executes, and the script is on disk if a run needs
|
|
# debugging. -fsSL fails on an HTTP 4xx/5xx error page; --retry rides
|
|
# out flaky networking (matches the circuits-fetch curl above).
|
|
curl -fsSL --retry 3 --retry-delay 2 \
|
|
https://risczero.com/install -o "$RUNNER_TEMP/rzup-install.sh"
|
|
bash "$RUNNER_TEMP/rzup-install.sh"
|
|
echo "$HOME/.risc0/bin" >> "$GITHUB_PATH"
|
|
"$HOME/.risc0/bin/rzup" install rust
|
|
# Guest deps that compile C sources (e.g. `ring` in the lez-framework
|
|
# guest) additionally need risc0's C++ cross-toolchain. When it is
|
|
# missing, risc0-build points CC at a sentinel path
|
|
# (/no_risc0_cpp_toolchain_installed_run_rzup_install_cpp) and the
|
|
# guest build dies in cc-rs compiler detection.
|
|
"$HOME/.risc0/bin/rzup" install cpp
|
|
|
|
- name: Build rendered project workspace
|
|
# HOST_CC/HOST_CXX are intentionally NOT set here: scaffold pins them
|
|
# itself for every cargo invocation that can trigger the guest embed
|
|
# (`apply_host_cc_overrides` in src/process.rs — build, IDL, client
|
|
# gen), which is what keeps host-side compiles inside the guest graph
|
|
# (proc-macro deps: spel-framework-macros -> ... -> ring) off risc0's
|
|
# riscv cross-gcc. Leaving the env unset makes this E2E exercise that
|
|
# defaulting path instead of masking it.
|
|
run: |
|
|
set -euo pipefail
|
|
cd "$RUNNER_TEMP/e2e-app"
|
|
"$GITHUB_WORKSPACE/target/release/logos-scaffold" build
|