Skip to content

Commit

Permalink
ci: support Cairo1 recompile in CI
Browse files Browse the repository at this point in the history
Signed-off-by: Dori Medini <dori@starkware.co>
  • Loading branch information
dorimedini-starkware committed May 7, 2024
1 parent 103ae1b commit 22d2764
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 34 deletions.
54 changes: 50 additions & 4 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 @@ -14,13 +14,40 @@ on:
- synchronize
paths:
- 'crates/blockifier/feature_contracts/cairo0/**'
- 'crates/blockifier/feature_contracts/cairo1/**'
- 'crates/blockifier/tests/feature_contracts_compatibility_test.rs'

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 +57,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
52 changes: 27 additions & 25 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 @@ -140,10 +131,21 @@ fn verify_feature_contracts_match_enum() {
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 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 std::env::var("LEGACY").is_ok() {
contract.is_legacy()
} else {
!std::env::var("CI").is_ok() || !contract.is_legacy()
})
});

verify_feature_contracts_compatibility(fix_features, contracts_to_test)
}

0 comments on commit 22d2764

Please sign in to comment.