diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8b0a6dc --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,60 @@ +name: Run unit tests + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + merge_group: + workflow_dispatch: + +jobs: + unit-tests: + name: Unit Tests + runs-on: buildjet-16vcpu-ubuntu-2204 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.8 + + - name: Check formatting + run: | + forge fmt --check + + - name: Regenerate Contracts + run: | + python src/blocks/poseidon/poseidon-contract-gen.py src/blocks/poseidon/neptune-constants-U24-pallas.json PoseidonU24Pallas > src/blocks/poseidon/PoseidonNeptuneU24pallas.sol + python src/blocks/poseidon/poseidon-contract-gen.py src/blocks/poseidon/neptune-constants-U24-vesta.json PoseidonU24Vesta > src/blocks/poseidon/PoseidonNeptuneU24vesta.sol + + - name: Run forge fmt on re-generated contracts + run: | + forge fmt + + - name: Check discrepancies + run: | + if [[ `git status --porcelain` ]]; then + echo "There are discrepancies between the repository and the source. Please ensure the contracts are up to date." + exit 1 + fi + + - name: Run Forge build + run: | + forge --version + forge build + + - name: Run Forge tests + run: | + forge test -vvv + + - name: Get sizes of compiled contracts + run: | + forge --version + forge build --sizes || true diff --git a/.github/workflows/end2end.yml b/.github/workflows/end2end.yml new file mode 100644 index 0000000..99dc709 --- /dev/null +++ b/.github/workflows/end2end.yml @@ -0,0 +1,73 @@ +# Run integration tests when a maintainer comments `!test` on a PR to feature branch +# Fails when base branch is `main`, as it doesn't support e2e tests +name: End to end integration tests + +on: + issue_comment: + types: [created] + +env: + ANVIL_PRIVATE_KEY: ${{secrets.ANVIL_PRIVATE_KEY}} + ANVIL_URL: ${{secrets.ANVIL_RPC_URL}} + +jobs: + integration-tests-e2e: + name: E2E verification + runs-on: buildjet-16vcpu-ubuntu-2204 + if: + github.event.issue.pull_request + && github.event.issue.state == 'open' + && contains(github.event.comment.body, '!test') + && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') + steps: + - uses: xt0rted/pull-request-comment-branch@v2 + id: comment-branch + + - name: Exit if base branch is `main` + if: ${{ steps.comment-branch.outputs.base_ref == 'main' }} + run: | + echo "Cannot run end2end integration tests on PR targeting `main`" + exit 1 + continue-on-error: false + + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Checkout PR branch + run: gh pr checkout $PR_NUMBER + env: + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ github.event.issue.number }} + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.8 + + - name: Deploy main contract + run: | + echo "CONTRACT_ADDRESS=$(forge script script/Deployment.s.sol:NovaVerifierDeployer --fork-url $ANVIL_URL --private-key $ANVIL_PRIVATE_KEY --broadcast --non-interactive | sed -n 's/.*Contract Address: //p' | tail -1)" >> $GITHUB_OUTPUT + id: deployment + + - name: Load proof and public parameters + run: | + python loader.py pp-verifier-key.json pp-compressed-snark.json ${{steps.deployment.outputs.CONTRACT_ADDRESS}} $ANVIL_URL $ANVIL_PRIVATE_KEY + + - name: Check proof verification status + run: | + [[ $(cast call ${{steps.deployment.outputs.CONTRACT_ADDRESS}} "verify(uint32,uint256[],uint256[],bool)(bool)" "3" "[1]" "[0]" "true" --private-key $ANVIL_PRIVATE_KEY --rpc-url $ANVIL_URL) == true ]] && exit 0 || exit 1 + + - name: Comment on successful run + uses: peter-evans/create-or-update-comment@v3 + with: + issue-number: ${{ github.event.issue.number }} + body: | + End-to-end `!test` action succeeded! :rocket: + + https://github.com/lurk-lab/solidity-verifier/actions/runs/${{ github.run_id }} \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 20e18e0..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,94 +0,0 @@ -name: test - -on: [workflow_dispatch, push, pull_request] - -env: - ANVIL_PRIVATE_KEY: ${{secrets.ANVIL_PRIVATE_KEY}} - ANVIL_URL: ${{secrets.ANVIL_RPC_URL}} - - -jobs: - integration-tests-e2e: - needs: [unit-tests] - strategy: - fail-fast: true - - name: E2E verification - runs-on: [self-hosted] - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: 3.8 - - - name: Deploy main contract - run: | - echo "CONTRACT_ADDRESS=$(forge script script/Deployment.s.sol:NovaVerifierDeployer --fork-url $ANVIL_URL --private-key $ANVIL_PRIVATE_KEY --broadcast --non-interactive | sed -n 's/.*Contract Address: //p' | tail -1)" >> $GITHUB_OUTPUT - id: deployment - - - name: Load proof and public parameters - run: | - python loader.py pp-verifier-key.json pp-compressed-snark.json ${{steps.deployment.outputs.CONTRACT_ADDRESS}} $ANVIL_URL $ANVIL_PRIVATE_KEY - - - name: Check proof verification status - run: | - [[ $(cast call ${{steps.deployment.outputs.CONTRACT_ADDRESS}} "verify(uint32,uint256[],uint256[],bool)(bool)" "3" "[1]" "[0]" "true" --private-key $ANVIL_PRIVATE_KEY --rpc-url $ANVIL_URL) == true ]] && exit 0 || exit 1 - - unit-tests: - strategy: - fail-fast: true - - name: Unit Tests - runs-on: [self-hosted] - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: 3.8 - - - name: Check formatting - run: | - forge fmt --check - - - name: Regenerate Contracts - run: | - python src/blocks/poseidon/poseidon-contract-gen.py neptune-constants-U24-pallas.json PoseidonU24Pallas > src/blocks/poseidon/PoseidonNeptuneU24pallas.sol - python src/blocks/poseidon/poseidon-contract-gen.py neptune-constants-U24-vesta.json PoseidonU24Vesta > src/blocks/poseidon/PoseidonNeptuneU24vesta.sol - - - name: Run forge fmt on re-generated contracts - run: | - forge fmt - - - name: Check discrepancies - run: | - if [[ `git status --porcelain` ]]; then - echo "There are discrepancies between the repository and the source. Please ensure the contracts are up to date." - exit 1 - fi - - - name: Run Forge build - run: | - forge --version - forge build - - - name: Run Forge tests - run: | - forge test -vvv - - - name: Get sizes of compiled contracts - run: | - forge --version - forge build --sizes || true