|
| 1 | +# TODO: Reusify and combine with the `check-lurk-compiles` action and/or make a reusable open-issue action |
| 2 | +# |
| 3 | +# This workflow runs autogenerated `solidity-verifier` compatibility tests on Arecibo PRs and notifies if compatibility is broken |
| 4 | +# The workflow is intended to be a required status check only to make sure the Rust test & basic job steps work |
| 5 | +# It is NOT intended to block breaking changes from merging, only to noisily surface them for review |
| 6 | +# |
| 7 | +# If the Rust template fails to generate the Solidity test or the job errors for another reason, the workflow fails immediately |
| 8 | +# If the Solidity test fails on `pull_request`, it writes a PR comment to ensure the author/reviewer are notified |
| 9 | +# If the Solidity test fails on `merge_group`, it opens an issue in `solidity-verifier` downstream that compatibility has been broken |
| 10 | +# `merge_group` failures should only happen intentionally when breaking changes need to be merged in Arecibo |
| 11 | +# |
| 12 | +# Implementation note: |
| 13 | +# `falnyr/replace-env-vars-action`, `micalevisk/last-issue-action` and `peter-evans/create-issue-from-file` replace |
| 14 | +# equivalent functionality in `JasonEtco/create-an-issue`. We can't use the latter because it doesn't allow creating |
| 15 | +# the issue in another repo. See https://github.com/JasonEtco/create-an-issue/issues/40 |
| 16 | +name: Test `solidity-verifier` compatibility |
| 17 | + |
| 18 | +on: |
| 19 | + merge_group: |
| 20 | + pull_request: |
| 21 | + types: [opened, synchronize, reopened, ready_for_review] |
| 22 | + branches: |
| 23 | + - dev |
| 24 | + - 'feat/**' |
| 25 | + - release-candidate |
| 26 | + |
| 27 | +concurrency: |
| 28 | + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} |
| 29 | + cancel-in-progress: true |
| 30 | + |
| 31 | +jobs: |
| 32 | + solidity-compat: |
| 33 | + runs-on: buildjet-16vcpu-ubuntu-2204 |
| 34 | + steps: |
| 35 | + - uses: actions/checkout@v4 |
| 36 | + with: |
| 37 | + repository: lurk-lab/ci-workflows |
| 38 | + - uses: ./.github/actions/ci-env |
| 39 | + - uses: actions/checkout@v4 |
| 40 | + - uses: dtolnay/rust-toolchain@stable |
| 41 | + - uses: taiki-e/install-action@nextest |
| 42 | + - uses: Swatinem/rust-cache@v2 |
| 43 | + - name: Run Solidity test generator |
| 44 | + run: | |
| 45 | + # Runs all tests with the `test_solidity_compatibility` prefix, e.g. `test_solidity_compatibility_ipa` |
| 46 | + cargo nextest run -E 'test(test_solidity_compatibility)' --release --run-ignored all --nocapture > test-output |
| 47 | + working-directory: ${{ github.workspace }} |
| 48 | + - name: Check out `solidity-verifier` for tests |
| 49 | + uses: actions/checkout@v4 |
| 50 | + with: |
| 51 | + repository: lurk-lab/solidity-verifier |
| 52 | + path: solidity-verifier |
| 53 | + submodules: recursive |
| 54 | + - name: Install Foundry |
| 55 | + uses: foundry-rs/foundry-toolchain@v1 |
| 56 | + with: |
| 57 | + version: nightly |
| 58 | + - name: Prep Solidity test files |
| 59 | + run: | |
| 60 | + # Get test names from output, extracting the final word after the final `_` in the test output |
| 61 | + # E.g. `test provider::tests::ipa_pc::test::test_solidity_compatibility_ipa ... ok` returns `ipa` |
| 62 | + # Expects all tests to live in the `provider` module, but can be changed/strengthened in future |
| 63 | + TEST_NAMES=$(grep 'test provider::*' test-output | awk -F'[_(.*?)\b...]' '{ print $(NF-3) }') |
| 64 | + echo "$TEST_NAMES" |
| 65 | +
|
| 66 | + # Print output of each test to `<test_name>.t.sol` file |
| 67 | + awk -v names="$TEST_NAMES" 'BEGIN { |
| 68 | + file_counter = 0 |
| 69 | + buffer = "" |
| 70 | + # Convert test names to array |
| 71 | + split(names, elements, " ") |
| 72 | + for (i in elements) { |
| 73 | + print "Element:", elements[i] |
| 74 | + } |
| 75 | + } |
| 76 | +
|
| 77 | + /running 1 test/ { |
| 78 | + between = 1 |
| 79 | + buffer = "" |
| 80 | + } |
| 81 | +
|
| 82 | + between { |
| 83 | + buffer = buffer $0 ORS |
| 84 | + } |
| 85 | +
|
| 86 | + /^test provider.*$/ { |
| 87 | + between = 0 |
| 88 | +
|
| 89 | + if (buffer != "") { |
| 90 | + ++file_counter |
| 91 | + print buffer > elements[file_counter]".t.sol" |
| 92 | + buffer = "" |
| 93 | + } |
| 94 | + }' test-output |
| 95 | +
|
| 96 | + # Clean up |
| 97 | + shopt -s nullglob |
| 98 | + for file in *.t.sol; do |
| 99 | + cat $file | sed '1d' | head -n -2 > tmp.file && mv tmp.file solidity-verifier/test/$file |
| 100 | + done |
| 101 | + shopt -u nullglob |
| 102 | + working-directory: ${{ github.workspace }} |
| 103 | + - name: Run Forge tests |
| 104 | + id: solidity-test |
| 105 | + run: forge test -vvv |
| 106 | + working-directory: ${{ github.workspace }}/solidity-verifier |
| 107 | + continue-on-error: true |
| 108 | + # Prepares env vars for use in a PR comment or issue in `solidity-verifier` |
| 109 | + - name: Set env vars |
| 110 | + if: steps.solidity-test.outcome != 'success' |
| 111 | + run: | |
| 112 | + if [[ "${{ github.event_name }}" == "pull_request" ]]; then |
| 113 | + COMMIT=$(echo ${{ github.event.pull_request.head.sha }} | cut -c -7) |
| 114 | + PR_NUMBER=${{ github.event.pull_request.number }} |
| 115 | + else |
| 116 | + COMMIT=$(echo ${{ github.event.merge_group.head_sha }} | cut -c -7) |
| 117 | + PR_NUMBER=$(echo ${{ github.event.merge_group.head_ref }} | sed -e 's/.*pr-\(.*\)-.*/\1/') |
| 118 | + fi |
| 119 | + GITHUB_URL=https://github.com/${{ github.repository }} |
| 120 | + WORKFLOW_URL=$GITHUB_URL/actions/runs/${{ github.run_id }} |
| 121 | + echo "WORKFLOW_FILE=$WORKFLOW_URL/workflow" | tee -a $GITHUB_ENV |
| 122 | + echo "WORKFLOW_URL=$WORKFLOW_URL" | tee -a $GITHUB_ENV |
| 123 | + echo "COMMIT_URL=$GITHUB_URL/commit/$COMMIT" | tee -a $GITHUB_ENV |
| 124 | + echo "PR_URL=$GITHUB_URL/pull/$PR_NUMBER" | tee -a $GITHUB_ENV |
| 125 | + echo "COMMIT=$COMMIT" | tee -a $GITHUB_ENV |
| 126 | + # Comment on PR when test fails on `pull_request` |
| 127 | + - name: Comment on failing run |
| 128 | + if: steps.solidity-test.outcome != 'success' && github.event_name == 'pull_request' |
| 129 | + uses: peter-evans/create-or-update-comment@v4 |
| 130 | + with: |
| 131 | + issue-number: ${{ github.event.pull_request.number }} |
| 132 | + body: | |
| 133 | + `solidity-verifier` compatibility test failed :x: |
| 134 | +
|
| 135 | + ${{ env.WORKFLOW_URL }} |
| 136 | + # Substitutes env vars for their values in `SOLIDITY_COMPAT_ISSUE.md` |
| 137 | + - uses: falnyr/replace-env-vars-action@master |
| 138 | + if: steps.solidity-test.outcome != 'success' && (github.event_name != 'pull_request' || github.event.action == 'enqueued') |
| 139 | + env: |
| 140 | + WORKFLOW_URL: ${{ env.WORKFLOW_URL }} |
| 141 | + WORKFLOW_FILE: ${{ env.WORKFLOW_FILE }} |
| 142 | + COMMIT: ${{ env.COMMIT }} |
| 143 | + COMMIT_URL: ${{ env.COMMIT_URL }} |
| 144 | + PR_URL: ${{ env.PR_URL }} |
| 145 | + with: |
| 146 | + filename: .github/SOLIDITY_COMPAT_ISSUE.md |
| 147 | + # Finds the last open issue matching given labels |
| 148 | + - name: Find the last open compatibility issue |
| 149 | + id: last-issue |
| 150 | + if: steps.solidity-test.outcome != 'success' && (github.event_name != 'pull_request' || github.event.action == 'enqueued') |
| 151 | + uses: micalevisk/last-issue-action@v2 |
| 152 | + with: |
| 153 | + repository: lurk-lab/solidity-verifier |
| 154 | + state: open |
| 155 | + # Find the last updated open issue that has these labels: |
| 156 | + labels: | |
| 157 | + compatibility |
| 158 | + debt |
| 159 | + automated issue |
| 160 | + # Update existing issue in `solidity-verifier` or create new one |
| 161 | + - uses: peter-evans/create-issue-from-file@v5 |
| 162 | + if: steps.solidity-test.outcome != 'success' && (github.event_name != 'pull_request' || github.event.action == 'enqueued') |
| 163 | + with: |
| 164 | + token: ${{ secrets.REPO_TOKEN }} |
| 165 | + repository: lurk-lab/solidity-verifier |
| 166 | + issue-number: ${{ steps.last-issue.outputs.issue-number }} |
| 167 | + title: ":rotating_light: Arecibo compatibility is broken" |
| 168 | + content-filepath: .github/SOLIDITY_COMPAT_ISSUE.md |
| 169 | + labels: | |
| 170 | + compatibility |
| 171 | + debt |
| 172 | + automated issue |
0 commit comments