diff --git a/.github/workflows/rust-tests.yml b/.github/workflows/rust-tests.yml index 453155307..cb52a7055 100644 --- a/.github/workflows/rust-tests.yml +++ b/.github/workflows/rust-tests.yml @@ -12,7 +12,185 @@ env: RUST_TOOLCHAIN: 1.70.0 jobs: + build-programs: + strategy: + matrix: + program-target: [ + compile-cairo, + compile-starknet, + compile-cairo-1-casm, + compile-cairo-1-sierra, + compile-cairo-2-casm, + compile-cairo-2-sierra, + ] + name: Build Cairo programs + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Fetch from cache + uses: actions/cache@v3 + id: cache-programs + with: + path: | + cairo_programs/**/*.casm + cairo_programs/**/*.sierra + cairo_programs/**/*.json + starknet_programs/**/*.casm + starknet_programs/**/*.sierra + starknet_programs/**/*.json + !starknet_programs/raw_contract_classes/* + key: ${{ matrix.program-target }}-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'starknet_programs/**/*.cairo') }} + restore-keys: ${{ matrix.program-target }}-cache- + + # This is not pretty, but we need `make` to see the compiled programs are + # actually newer than the sources, otherwise it will try to rebuild them + - name: Restore timestamps + uses: chetan/git-restore-mtime-action@v1 + + - name: Python3 Build + if: ${{ steps.cache-programs.outputs.cache-hit != 'true' }} + uses: actions/setup-python@v4 + with: + python-version: '3.9' + cache: 'pip' + + - name: Install deps + if: ${{ steps.cache-programs.outputs.cache-hit != 'true' }} + run: make deps + + - name: Build programs + if: ${{ steps.cache-programs.outputs.cache-hit != 'true' }} + run: make -j ${{ matrix.program-target }} + + # NOTE: used to reduce the amount of cache steps we need in later jobs + # TODO: remove this cache once the workflow finishes + merge-caches: + name: Merge Cairo programs cache + runs-on: ubuntu-22.04 + needs: build-programs + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Fetch from cache (compile-cairo) + uses: actions/cache/restore@v3 + id: cache-programs + with: + path: | + cairo_programs/**/*.casm + cairo_programs/**/*.sierra + cairo_programs/**/*.json + starknet_programs/**/*.casm + starknet_programs/**/*.sierra + starknet_programs/**/*.json + !starknet_programs/raw_contract_classes/* + key: compile-cairo-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'starknet_programs/**/*.cairo') }} + fail-on-cache-miss: true + + - name: Fetch from cache (compile-starknet) + uses: actions/cache/restore@v3 + with: + path: | + cairo_programs/**/*.casm + cairo_programs/**/*.sierra + cairo_programs/**/*.json + starknet_programs/**/*.casm + starknet_programs/**/*.sierra + starknet_programs/**/*.json + !starknet_programs/raw_contract_classes/* + key: compile-starknet-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'starknet_programs/**/*.cairo') }} + fail-on-cache-miss: true + + - name: Fetch from cache (compile-cairo-1-casm) + uses: actions/cache/restore@v3 + with: + path: | + cairo_programs/**/*.casm + cairo_programs/**/*.sierra + cairo_programs/**/*.json + starknet_programs/**/*.casm + starknet_programs/**/*.sierra + starknet_programs/**/*.json + !starknet_programs/raw_contract_classes/* + key: compile-cairo-1-casm-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'starknet_programs/**/*.cairo') }} + fail-on-cache-miss: true + + - name: Fetch from cache (compile-cairo-1-sierra) + uses: actions/cache/restore@v3 + with: + path: | + cairo_programs/**/*.casm + cairo_programs/**/*.sierra + cairo_programs/**/*.json + starknet_programs/**/*.casm + starknet_programs/**/*.sierra + starknet_programs/**/*.json + !starknet_programs/raw_contract_classes/* + key: compile-cairo-1-sierra-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'starknet_programs/**/*.cairo') }} + fail-on-cache-miss: true + + - name: Fetch from cache (compile-cairo-2-casm) + uses: actions/cache/restore@v3 + with: + path: | + cairo_programs/**/*.casm + cairo_programs/**/*.sierra + cairo_programs/**/*.json + starknet_programs/**/*.casm + starknet_programs/**/*.sierra + starknet_programs/**/*.json + !starknet_programs/raw_contract_classes/* + key: compile-cairo-2-casm-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'starknet_programs/**/*.cairo') }} + fail-on-cache-miss: true + + - name: Fetch from cache (compile-cairo-2-sierra) + uses: actions/cache/restore@v3 + with: + path: | + cairo_programs/**/*.casm + cairo_programs/**/*.sierra + cairo_programs/**/*.json + starknet_programs/**/*.casm + starknet_programs/**/*.sierra + starknet_programs/**/*.json + !starknet_programs/raw_contract_classes/* + key: compile-cairo-2-sierra-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'starknet_programs/**/*.cairo') }} + fail-on-cache-miss: true + + - name: Fetch from cache (compile-cairo-2-sierra) + uses: actions/cache/restore@v3 + with: + path: | + cairo_programs/**/*.casm + cairo_programs/**/*.sierra + cairo_programs/**/*.json + starknet_programs/**/*.casm + starknet_programs/**/*.sierra + starknet_programs/**/*.json + !starknet_programs/raw_contract_classes/* + key: compile-cairo-2-sierra-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'starknet_programs/**/*.cairo') }} + fail-on-cache-miss: true + + - name: Merge caches + uses: actions/cache/save@v3 + with: + path: | + cairo_programs/**/*.casm + cairo_programs/**/*.sierra + cairo_programs/**/*.json + starknet_programs/**/*.casm + starknet_programs/**/*.sierra + starknet_programs/**/*.json + !starknet_programs/raw_contract_classes/* + key: all-programs-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'starknet_programs/**/*.cairo') }} + build: + name: Build with release profile + needs: merge-caches runs-on: ubuntu-22.04 steps: - name: Install Rust @@ -25,15 +203,26 @@ jobs: cache-on-failure: true - name: Checkout uses: actions/checkout@v3 - - uses: actions/setup-python@v2 + - name: Fetch programs + uses: actions/cache/restore@v3 with: - python-version: '3.9' - - name: Deps - run: make deps + path: | + cairo_programs/**/*.casm + cairo_programs/**/*.sierra + cairo_programs/**/*.json + starknet_programs/**/*.casm + starknet_programs/**/*.sierra + starknet_programs/**/*.json + !starknet_programs/raw_contract_classes/* + key: all-programs-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'starknet_programs/**/*.cairo') }} + fail-on-cache-miss: true + - name: Build - run: make build + run: cargo build --release --workspace - format: + lint: + name: Lint with fmt and clippy + needs: merge-caches runs-on: ubuntu-22.04 steps: - name: Install Rust @@ -46,17 +235,32 @@ jobs: cache-on-failure: true - name: Checkout uses: actions/checkout@v3 - - uses: actions/setup-python@v2 + - name: Fetch programs + uses: actions/cache/restore@v3 with: - python-version: '3.9' - - name: Deps - run: make deps + path: | + cairo_programs/**/*.casm + cairo_programs/**/*.sierra + cairo_programs/**/*.json + starknet_programs/**/*.casm + starknet_programs/**/*.sierra + starknet_programs/**/*.json + !starknet_programs/raw_contract_classes/* + key: all-programs-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'starknet_programs/**/*.cairo') }} + fail-on-cache-miss: true + - name: Format run: cargo fmt --all -- --check - name: Run clippy - run: make clippy + run: cargo clippy --workspace --all-targets -- -D warnings - test: + tests: + strategy: + fail-fast: false + matrix: + target: [ test-cairo-1, test-cairo-2, test-doctests ] + name: Run tests + needs: merge-caches runs-on: ubuntu-22.04 steps: - name: Install Rust @@ -69,35 +273,88 @@ jobs: cache-on-failure: true - name: Checkout uses: actions/checkout@v3 - - uses: actions/setup-python@v2 + + - name: Fetch programs + uses: actions/cache/restore@v3 with: - python-version: '3.9' - - name: Deps - run: make deps - - name: Run tests - run: make test - - name: Run doctests - run: cargo test --workspace --doc + path: | + cairo_programs/**/*.casm + cairo_programs/**/*.sierra + cairo_programs/**/*.json + starknet_programs/**/*.casm + starknet_programs/**/*.sierra + starknet_programs/**/*.json + !starknet_programs/raw_contract_classes/* + key: all-programs-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'starknet_programs/**/*.cairo') }} + fail-on-cache-miss: true + + - name: Install testing tools + # TODO: remove `if` when nextest adds doctests support + if: ${{ matrix.target != 'test-doctests' }} + uses: taiki-e/install-action@v2 + with: + tool: cargo-nextest + + - name: Run tests (${{ matrix.target }}) + run: make ${{ matrix.target }} - # 28.06.2023: This job uses unmaintained actions-rs because dtolnay is giving linking errors with nightly coverage: + needs: merge-caches + name: Generate and upload coverage report runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@v3 - - uses: actions/setup-python@v2 - with: - python-version: '3.9' - - name: Deps - run: make deps - name: Install Rust - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@nightly with: - toolchain: nightly - override: true - components: rustfmt, clippy - - name: Coverage - run: make coverage + toolchain: ${{ env.RUST_TOOLCHAIN }} + + - name: Set nightly as default + run: rustup default nightly + + - name: Install testing tools + uses: taiki-e/install-action@v2 + with: + tool: cargo-nextest,cargo-llvm-cov + + - uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + + - name: Cache coverage report + id: restore-report + uses: actions/cache/restore@v3 + with: + path: lcov.info + key: coverage-cache-${{ github.sha }} + + - name: Fetch programs + if: steps.restore-report.outputs.cache-hit != 'true' + uses: actions/cache/restore@v3 + with: + path: | + cairo_programs/**/*.casm + cairo_programs/**/*.sierra + cairo_programs/**/*.json + starknet_programs/**/*.casm + starknet_programs/**/*.sierra + starknet_programs/**/*.json + !starknet_programs/raw_contract_classes/* + key: all-programs-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'starknet_programs/**/*.cairo') }} + fail-on-cache-miss: true + + - name: Generate coverage report + if: steps.restore-report.outputs.cache-hit != 'true' + run: make coverage-report + + - name: Save coverage report + if: steps.restore-report.outputs.cache-hit != 'true' + uses: actions/cache/save@v3 + with: + path: lcov.info + key: coverage-cache-${{ github.sha }} + - name: Upload coverage to codecov.io uses: codecov/codecov-action@v3 with: diff --git a/Makefile b/Makefile index 996c89486..12a9797fa 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ -.PHONY: build check clean clippy compile-cairo compile-starknet coverage deps test heaptrack check-python-version compile-abi +.PHONY: build check clean clippy compile-cairo compile-starknet compile-cairo-1-casm compile-cairo-1-sierra \ + compile-cairo-2-casm compile-cairo-2-sierra coverage deps test heaptrack check-python-version export PATH:=$(shell pyenv root)/shims:$(PATH) export PYENV_VERSION=3.9 @@ -32,13 +33,7 @@ STARKNET_SIERRA_COMPILE_CAIRO_2:=cairo2/bin/starknet-sierra-compile # deps-venv: - pip install \ - fastecdsa \ - typeguard==2.13.0 \ - openzeppelin-cairo-contracts==0.6.1 \ - maturin \ - cairo-lang==0.11 \ - "urllib3 <=1.26.15" + pip install -r requirements.txt compile-cairo: $(CAIRO_TARGETS) $(CAIRO_ABI_TARGETS) compile-starknet: $(STARKNET_TARGETS) $(STARKNET_ABI_TARGETS) @@ -72,6 +67,9 @@ $(CAIRO_1_CONTRACTS_TEST_DIR)/%.sierra: $(CAIRO_1_CONTRACTS_TEST_DIR)/%.cairo $(CAIRO_1_CONTRACTS_TEST_DIR)/%.casm: $(CAIRO_1_CONTRACTS_TEST_DIR)/%.sierra $(STARKNET_SIERRA_COMPILE_CAIRO_1) --allowed-libfuncs-list-name experimental_v0.1.0 --add-pythonic-hints $< $@ +compile-cairo-1-sierra: $(CAIRO_1_COMPILED_SIERRA_CONTRACTS) +compile-cairo-1-casm: $(CAIRO_1_COMPILED_CASM_CONTRACTS) + cairo-repo-1-dir = cairo1 cairo-repo-1-dir-macos = cairo1-macos @@ -105,6 +103,9 @@ $(CAIRO_2_CONTRACTS_TEST_DIR)/%.sierra: $(CAIRO_2_CONTRACTS_TEST_DIR)/%.cairo $(CAIRO_2_CONTRACTS_TEST_DIR)/%.casm: $(CAIRO_2_CONTRACTS_TEST_DIR)/%.sierra $(STARKNET_SIERRA_COMPILE_CAIRO_2) --add-pythonic-hints $< $@ +compile-cairo-2-sierra: $(CAIRO_2_COMPILED_SIERRA_CONTRACTS) +compile-cairo-2-casm: $(CAIRO_2_COMPILED_CASM_CONTRACTS) + cairo-repo-2-dir = cairo2 cairo-repo-2-dir-macos = cairo2-macos @@ -162,18 +163,29 @@ clean: -rm -rf cairo-2.0.0.tar -rm -rf cairo-1.1.1.tar -clippy: compile-cairo compile-starknet $(CAIRO_1_COMPILED_CASM_CONTRACTS) $(CAIRO_2_COMPILED_CASM_CONTRACTS) +clippy: compile-cairo compile-starknet compile-cairo-1-casm compile-cairo-2-casm cargo clippy --workspace --all-targets -- -D warnings -test: compile-cairo compile-starknet $(CAIRO_1_COMPILED_CASM_CONTRACTS) $(CAIRO_1_COMPILED_SIERRA_CONTRACTS) $(CAIRO_2_COMPILED_CASM_CONTRACTS) $(CAIRO_2_COMPILED_SIERRA_CONTRACTS) +test: compile-cairo compile-starknet compile-cairo-1-casm compile-cairo-1-sierra compile-cairo-2-casm compile-cairo-2-sierra echo "Cairo1 tests" - cargo test --workspace --all-targets --features=cairo_1_tests + $(MAKE) test-cairo-1 echo "Cairo2 tests" - cargo test --workspace --all-targets + $(MAKE) test-cairo-2 + +test-cairo-1: + cargo nextest run --workspace --all-targets --features=cairo_1_tests + +test-cairo-2: + cargo nextest run --workspace --all-targets + +test-doctests: + cargo test --workspace --doc + +coverage: compile-cairo compile-starknet compile-cairo-1-casm compile-cairo-2-casm + $(MAKE) coverage-report -coverage: compile-cairo compile-starknet compile-abi $(CAIRO_1_COMPILED_CASM_CONTRACTS) $(CAIRO_2_COMPILED_CASM_CONTRACTS) - cargo +nightly llvm-cov --ignore-filename-regex 'main.rs' --release - cargo +nightly llvm-cov report --lcov --ignore-filename-regex 'main.rs' --output-path lcov.info --release +coverage-report: + cargo +nightly llvm-cov nextest --lcov --ignore-filename-regex 'main.rs' --output-path lcov.info --release heaptrack: ./scripts/heaptrack.sh diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..887f4baa4 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +fastecdsa +cairo-lang==0.11 +openzeppelin-cairo-contracts==0.6.1