Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

ci: support Cairo1 recompile in CI #1877

Open
wants to merge 1 commit into
base: dori/add-cairo1-version-file-for-ci
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 55 additions & 5 deletions .github/workflows/compiled_cairo.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: CI
name: Verify Cairo File Dependencies

on:
push:
Expand All @@ -13,14 +13,45 @@ on:
- reopened
- synchronize
paths:
- 'crates/blockifier/feature_contracts/cairo0/**'
# A change in any feature contract, or any compiler version of any contract, should trigger
# this job.
- 'crates/blockifier/feature_contracts/**'
- 'crates/blockifier/tests/cairo1_compiler_tag.txt'
- 'crates/blockifier/tests/legacy_cairo1_compiler_tag.txt'
- 'crates/blockifier/tests/feature_contracts_compatibility_test.rs'
- 'crates/blockifier/tests/requirements.txt'

jobs:
verify_cairo_file_dependencies:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
# Checkout blockifier into a dedicated directory - technical requirement in order to be able to checkout `cairo` in a sibling directory.
- name: checkout blockifier into `blockifier` directory.
uses: actions/checkout@v4
with:
repository: 'starkware-libs/blockifier'
path: 'blockifier'

- name: Read Cairo1 Tag to compile contracts with from Blockifier.
id: read-tag
# GITHUB_ENV is a variable github allocates for dynamic stuff inside workflow like our usage, name not customizable.
run: echo "TAG=$(cat blockifier/crates/blockifier/tests/cairo1_compiler_tag.txt)" >> $GITHUB_ENV

- name: Read legacy Cairo1 Tag to compile the legacy contract with.
id: read-legacy-tag
# GITHUB_ENV is a variable github allocates for dynamic stuff inside workflow like our usage, name not customizable.
run: echo "LEGACY_TAG=$(cat blockifier/crates/blockifier/tests/legacy_cairo1_compiler_tag.txt)" >> $GITHUB_ENV

- name: checkout cairo1 repo in order to compile cairo1 contracts.
uses: actions/checkout@v4
with:
repository: 'starkware-libs/cairo'
fetch-tags: tags
ref: ${{ env.TAG }}
path: 'cairo'

- uses: actions-rs/toolchain@master
with:
components: rustfmt
toolchain: nightly-2024-01-12
Expand All @@ -30,5 +61,24 @@ jobs:
python-version: '3.9'
cache: 'pip'
- run:
pip install -r crates/blockifier/tests/requirements.txt;
cd blockifier &&
pip install -r crates/blockifier/tests/requirements.txt &&
cargo test verify_feature_contracts -- --include-ignored

- name: checkout legacy tag of cairo1 repo in order to compile the legacy contract.
uses: actions/checkout@v4
with:
repository: 'starkware-libs/cairo'
fetch-tags: tags
ref: ${{ env.LEGACY_TAG }}
path: 'cairo'

- name: Verify the legacy contract.
uses: actions-rs/toolchain@master
with:
components: rustfmt
toolchain: nightly-2024-01-12
- uses: Swatinem/rust-cache@v2
- run:
cd blockifier &&
LEGACY=1 cargo test verify_feature_contracts -- --include-ignored
1 change: 0 additions & 1 deletion crates/blockifier/src/test_utils/cairo_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ fn verify_cairo1_compiler_deps(git_tag_override: Option<String>) {
// Checkout the required version in the compiler repo.
run_and_verify_output(Command::new("git").args([
"-C",
// TODO(Dori, 1/6/2024): Handle CI case (repo path will be different).
cairo_repo_path.to_str().unwrap(),
"checkout",
&tag,
Expand Down
10 changes: 6 additions & 4 deletions crates/blockifier/src/test_utils/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ impl FeatureContract {
}
}

pub fn is_legacy(&self) -> bool {
matches!(self, Self::LegacyTestContract)
}

/// Unique integer representing each unique contract. Used to derive "class hash" and "address".
fn get_integer_base(self) -> u32 {
self.get_cairo_version_bit()
Expand Down Expand Up @@ -191,10 +195,8 @@ impl FeatureContract {
cairo0_compile(self.get_source_path(), extra_arg, false)
}
CairoVersion::Cairo1 => {
let tag_override = match self {
Self::LegacyTestContract => Some(LEGACY_CONTRACT_COMPILER_TAG.into()),
_ => None,
};
let tag_override =
if self.is_legacy() { Some(LEGACY_CONTRACT_COMPILER_TAG.into()) } else { None };
cairo1_compile(self.get_source_path(), tag_override)
}
}
Expand Down
56 changes: 30 additions & 26 deletions crates/blockifier/tests/feature_contracts_compatibility_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,23 @@ const FIX_COMMAND: &str = "FIX_FEATURE_TEST=1 cargo test -- --ignored";
// ```
// Then, run the FIX_COMMAND above.

// This test currently doesn't support Cairo1 contracts. To fix them you'll need to compile them one
// by one:
// 1. Clone the [cairo repo](https://github.com/starkware-libs/cairo).
// 2. Checkout the commit defined in [the root Cargo.toml](../../../../Cargo.toml).
// 3. From within the compiler repo root directory, run:
// ```
// PREFIX=~/workspace/blockifier/crates/blockifier/feature_contracts/cairo1
// CONTRACT_NAME=<contract_base_filename>
// cargo run --release --bin starknet-compile -- --single-file \
// $PREFIX/$CONTRACT_NAME.cairo \
// $PREFIX/compiled/$CONTRACT_NAME.sierra.json
// cargo run --release --bin starknet-sierra-compile \
// $PREFIX/compiled/$CONTRACT_NAME.sierra.json \
// $PREFIX/compiled/$CONTRACT_NAME.casm.json
// ```
// TODO(Gilad, 1/1/2024): New year's resolution: support Cairo1 in the test.
// To test Cairo1 feature contracts, first clone the Cairo repo and checkout the required tag.
// The repo should be located next to the blockifier repo:
// <WORKSPACE_DIR>/
// - blockifier/
// - cairo/
// Then, run the FIX_COMMAND above.

// Checks that:
// 1. `TEST_CONTRACTS` dir exists and contains only `.cairo` files and the subdirectory
// `COMPILED_CONTRACTS_SUBDIR`.
// 2. for each `X.cairo` file in `TEST_CONTRACTS` there exists an `X_compiled.json` file in
// `COMPILED_CONTRACTS_SUBDIR` which equals `starknet-compile-deprecated X.cairo --no_debug_info`.
fn verify_feature_contracts_compatibility(fix: bool, cairo_version: CairoVersion) {
for contract in FeatureContract::all_feature_contracts()
.filter(|contract| contract.cairo_version() == cairo_version)
{
fn verify_feature_contracts_compatibility(
fix: bool,
contracts_to_test: impl Iterator<Item = FeatureContract>,
) {
for contract in contracts_to_test {
// Compare output of cairo-file on file with existing compiled file.
let expected_compiled_output = contract.compile();
let existing_compiled_path = contract.get_compiled_path();
Expand Down Expand Up @@ -135,15 +126,28 @@ fn verify_feature_contracts_match_enum() {
assert_eq!(compiled_paths_from_enum, compiled_paths_on_filesystem);
}

fn is_env_var_set(env_var: &str) -> bool {
std::env::var(env_var).is_ok()
}

#[rstest]
#[ignore]
fn verify_feature_contracts(
#[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] cairo_version: CairoVersion,
) {
if std::env::var("CI").is_ok() && matches!(cairo_version, CairoVersion::Cairo1) {
// TODO(Dori, 1/6/2024): Support Cairo1 contracts in the CI and remove this `if` statement.
return;
}
let fix_features = std::env::var("FIX_FEATURE_TEST").is_ok();
verify_feature_contracts_compatibility(fix_features, cairo_version)
let fix_features = is_env_var_set("FIX_FEATURE_TEST");
let legacy_mode = is_env_var_set("LEGACY");
let ci_mode = is_env_var_set("CI");

let contracts_to_test = FeatureContract::all_feature_contracts().filter(|contract| {
// If called with LEGACY environment variable set, only test legacy contracts (from CI
// or not).
// If tested from the CI *without* the LEGACY environment variable set, test only
// non-legacy contracts of the respective cairo version.
// If not tested from CI, test all contracts of the requested cairo version.
contract.cairo_version() == cairo_version
&& (if legacy_mode { contract.is_legacy() } else { !ci_mode || !contract.is_legacy() })
});

verify_feature_contracts_compatibility(fix_features, contracts_to_test)
}
Loading