diff --git a/.github/actions/build-resolc/action.yml b/.github/actions/build-resolc/action.yml new file mode 100644 index 00000000..35203b25 --- /dev/null +++ b/.github/actions/build-resolc/action.yml @@ -0,0 +1,88 @@ +name: Build resolc +description: Cache-aware resolc build for a single target. + +inputs: + target: + description: "Target triple (e.g., x86_64-unknown-linux-musl)" + required: true + build-type: + description: "'native' or 'musl'" + required: true + retention-days: + description: "Artifact retention in days" + required: false + default: "1" + +outputs: + url: + description: "Uploaded artifact URL" + value: ${{ steps.upload.outputs.artifact-url }} + sha: + description: "Uploaded artifact digest" + value: ${{ steps.upload.outputs.artifact-digest }} + +runs: + using: composite + steps: + - name: Check Build Cache + id: cache + uses: actions/cache@v5 + with: + # Use glob to match binaries with and without extensions. + path: resolc-${{ inputs.target }}* + key: build-${{ inputs.target }}-${{ github.sha }} + + - name: Set Up Rust Toolchain + if: ${{ steps.cache.outputs.cache-hit != 'true' }} + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + rustflags: "" + cache-key: ${{ inputs.target }} + + - name: Download LLVM + if: ${{ steps.cache.outputs.cache-hit != 'true' }} + uses: ./.github/actions/get-llvm + with: + target: ${{ inputs.target }} + + - name: Build (Native) + if: ${{ steps.cache.outputs.cache-hit != 'true' && inputs.build-type == 'native' }} + shell: bash + run: | + export LLVM_SYS_221_PREFIX=$PWD/llvm-${{ inputs.target }} + make install-bin + mv target/release/resolc resolc-${{ inputs.target }} || mv target/release/resolc.exe resolc-${{ inputs.target }}.exe + + - name: Build (MUSL) + if: ${{ steps.cache.outputs.cache-hit != 'true' && inputs.build-type == 'musl' }} + shell: bash + env: + RUST_MUSL_CROSS_IMAGE: messense/rust-musl-cross@sha256:2a8837c43bf12e246f1ebd05191de9ee27fcd22f9ca81511ccd4cf75dc16d71c + run: | + docker run -v $PWD:/opt/revive $RUST_MUSL_CROSS_IMAGE /bin/bash -c " + cd /opt/revive + chown -R root:root . + apt update && apt upgrade -y && apt install -y pkg-config + export LLVM_SYS_221_PREFIX=/opt/revive/llvm-${{ inputs.target }} + make install-bin + mv target/${{ inputs.target }}/release/resolc resolc-${{ inputs.target }} + " + sudo chown -R $(id -u):$(id -g) . + + - name: Install Solc + uses: ./.github/actions/get-solc + + - name: Basic Sanity Check + shell: bash + run: | + result=$(./resolc-${{ inputs.target }} --bin crates/integration/contracts/flipper.sol) + echo $result + if [[ $result == *'50564d'* ]]; then exit 0; else exit 1; fi + + - name: Upload Artifact + id: upload + uses: actions/upload-artifact@v6 + with: + name: resolc-${{ inputs.target }} + path: resolc-${{ inputs.target }}* + retention-days: ${{ inputs.retention-days }} diff --git a/.github/actions/get-llvm/action.yml b/.github/actions/get-llvm/action.yml index 71604fa1..3eb02ed4 100644 --- a/.github/actions/get-llvm/action.yml +++ b/.github/actions/get-llvm/action.yml @@ -4,13 +4,12 @@ # target: x86_64-unknown-linux-gnu name: "Download LLVM" +description: "Downloads a prebuilt LLVM release for a specific target." + inputs: target: + description: "Target triple (e.g., x86_64-unknown-linux-musl)" required: true - version: - description: "LLVM release version (e.g., 'llvm-18.1.8'). If not specified, uses the latest published LLVM release. To test a specific draft release, use the full name (e.g. 'llvm-21.1.8-revive.0f80912')." - required: false - default: "" runs: using: "composite" @@ -18,29 +17,39 @@ runs: - name: detect llvm version from submodule id: detect-version shell: bash + env: + # To test a draft LLVM release across every CI workflow, set this to the full + # draft name (e.g. "llvm-21.1.8-revive.0f80912") and revert to "" before merging. + OVERRIDE_VERSION: "" run: | - if [ -z "${{ inputs.version }}" ]; then - # Get the full version from the LLVM submodule. - git submodule update --init --recursive - cd llvm - # Try to get the most recent tag (e.g., "llvmorg-18.1.8") - LLVM_TAG=$(git describe --tags --abbrev=0 2>/dev/null) - if [ -n "$LLVM_TAG" ]; then - echo "Detected LLVM version from submodule: $LLVM_TAG" - # Convert "llvmorg-x.y.z" to "llvm-x.y.z" - LLVM_VERSION=$(echo "$LLVM_TAG" | sed 's/^llvmorg-/llvm-/') - echo "Detected LLVM version from submodule: $LLVM_VERSION" - echo "version_prefix=$LLVM_VERSION" >> $GITHUB_OUTPUT - else - echo "Could not detect LLVM version from submodule, will use latest release" - echo "version_prefix=" >> $GITHUB_OUTPUT - fi - cd .. - else - echo "Using explicitly provided version: ${{ inputs.version }}" - echo "version_prefix=${{ inputs.version }}" >> $GITHUB_OUTPUT + set -euo pipefail + + if [ -n "${OVERRIDE_VERSION}" ]; then + echo "Using override version: ${OVERRIDE_VERSION}" + echo "version_prefix=${OVERRIDE_VERSION}" >> "$GITHUB_OUTPUT" + exit 0 + fi + + LLVM_SHA=$(git ls-tree HEAD llvm | awk '{print $3}') + echo "LLVM_SHA: $LLVM_SHA" + LLVM_URL=$(git config -f .gitmodules submodule.llvm.url) + echo "LLVM_URL: $LLVM_URL" + if [ -z "$LLVM_SHA" ] || [ -z "$LLVM_URL" ]; then + echo "::error::Could not resolve LLVM submodule SHA or URL from this repo." >&2 + exit 1 fi + # Do a treeless clone to avoid unnecessarily fetching source files. + git clone --filter=tree:0 --no-checkout "$LLVM_URL" llvm-tmp + # Try to get the most recent tag (e.g., "llvmorg-18.1.8"). + LLVM_TAG=$(git -C llvm-tmp describe --tags --abbrev=0 "$LLVM_SHA") + rm -rf llvm-tmp + + # Convert "llvmorg-x.y.z" to "llvm-x.y.z". + LLVM_VERSION=$(echo "$LLVM_TAG" | sed 's/^llvmorg-/llvm-/') + echo "Detected LLVM version from submodule pin: $LLVM_VERSION" + echo "version_prefix=$LLVM_VERSION" >> "$GITHUB_OUTPUT" + - name: find asset id: find uses: actions/github-script@v7 @@ -56,6 +65,11 @@ runs: let target = process.env.target let versionPrefix = process.env.version_prefix + if (!versionPrefix) { + core.setFailed("version_prefix env is missing"); + return; + } + // Fetch all releases from all pages core.info('Fetching releases from revive repository...'); let hasMorePages = true; @@ -88,43 +102,24 @@ runs: core.info(` - ${r.tag_name} (published: ${r.published_at})`); }); - // Find the appropriate LLVM release - let llvmRelease; - if (versionPrefix) { - // Search for latest release matching the version prefix - llvmRelease = llvmReleases.find(release => { - return release.tag_name.startsWith(versionPrefix); - }); - if (llvmRelease) { - core.info(`Selected LLVM release matching prefix '${versionPrefix}': ${llvmRelease.tag_name}`); - } - } else { - // Find latest LLVM release (first in sorted list) - llvmRelease = llvmReleases[0]; - if (llvmRelease) { - core.info(`Selected latest LLVM version: ${llvmRelease.tag_name}`); - } + // Find the latest LLVM release matching the version prefix. + const llvmRelease = llvmReleases.find(release => release.tag_name.startsWith(versionPrefix)); + if (!llvmRelease) { + core.setFailed(`No LLVM releases matching prefix '${versionPrefix}' found! Please check the version, or first release LLVM`); + return; } - if (llvmRelease) { - let asset = llvmRelease.assets.find(asset => { - return asset.name.includes(target); - }); - if (!asset) { - core.setFailed(`Artifact for '${target}' not found in release ${llvmRelease.tag_name} (${llvmRelease.html_url})`); - process.exit(); - } - // Use the API URL (rather than `browser_download_url`) so that - // the authorization header is respected for draft releases. - return asset.url; - } + core.info(`Selected LLVM release matching prefix '${versionPrefix}': ${llvmRelease.tag_name}`); - if (versionPrefix) { - core.setFailed(`No LLVM releases matching prefix '${versionPrefix}' found! Please check the version.`); - } else { - core.setFailed(`No LLVM releases found! Please release LLVM before running this workflow.`); + const asset = llvmRelease.assets.find(asset => asset.name.includes(target)); + if (!asset) { + core.setFailed(`Artifact for '${target}' not found in release ${llvmRelease.tag_name} (${llvmRelease.html_url})`); + return; } - process.exit(); + + // Use the API URL (rather than `browser_download_url`) so that + // the authorization header is respected for draft releases. + return asset.url; - name: download shell: bash diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 4978652f..a3c490ff 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -29,7 +29,7 @@ jobs: pull-requests: write steps: - name: Checkout Commit Before Changes - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ inputs.ref_before }} @@ -158,7 +158,7 @@ jobs: - name: Upload Benchmark Results if: ${{ !inputs.pr_number }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: benchmark-report path: BENCHMARK_REPORT.md diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index ea2a2a4b..3240e5da 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -22,7 +22,7 @@ jobs: check-docs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: { fetch-depth: 0 } - name: Install and test the mdBook diff --git a/.github/workflows/differential-tests.yml b/.github/workflows/differential-tests.yml index f2183863..ebe7bc06 100644 --- a/.github/workflows/differential-tests.yml +++ b/.github/workflows/differential-tests.yml @@ -4,35 +4,68 @@ on: workflow_call: env: + IS_PUSH_TO_MAIN: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} # The compiler modes to use for compilation by retester. MODES: "Y M0 S+, Y M3 S+, Y Mz S+" SOLC_VERSION: "0.8.35" jobs: - build: - uses: ./.github/workflows/reusable-build.yml + build-linux: + uses: ./.github/workflows/reusable-build-linux.yml with: - is_release: false retention_days: 1 + build-macos: + uses: ./.github/workflows/reusable-build-macos.yml + with: + retention_days: 1 + + build-windows: + uses: ./.github/workflows/reusable-build-windows.yml + with: + retention_days: 1 + + build-matrix: + runs-on: ubuntu-24.04 + outputs: + entries: ${{ steps.matrix.outputs.entries }} + steps: + - name: Build Matrix + id: matrix + run: | + entries='[ + { + "platform": "linux-x86_64", + "target": "x86_64-unknown-linux-musl", + "runner": "ubuntu-24.04" + }, + { + "platform": "macos-arm64", + "target": "universal-apple-darwin", + "runner": "macos-15" + }, + ${{ env.IS_PUSH_TO_MAIN == 'true' && '{ + "platform": "macos-x86_64", + "target": "universal-apple-darwin", + "runner": "macos-15-intel" + },' || '' }} + { + "platform": "windows-x86_64", + "target": "x86_64-pc-windows-msvc", + "runner": "windows-2022" + } + ]' + + echo "Matrix:" + jq . <<< "$entries" + echo "entries=$(jq -c . <<< "$entries")" >> "$GITHUB_OUTPUT" + compile-and-export-hashes-native: - needs: build + needs: [build-matrix, build-linux, build-macos, build-windows] strategy: fail-fast: false matrix: - include: - - platform: linux-x86_64 - target: x86_64-unknown-linux-musl - runner: ubuntu-24.04 - - platform: macos-arm64 - target: universal-apple-darwin - runner: macos-15 - - platform: macos-x86_64 - target: universal-apple-darwin - runner: macos-15-intel - - platform: windows-x86_64 - target: x86_64-pc-windows-msvc - runner: windows-2022 + include: ${{ fromJSON(needs.build-matrix.outputs.entries) }} runs-on: ${{ matrix.runner }} steps: # For some deeply nested contracts in `resolc-compiler-tests`, Windows @@ -42,13 +75,13 @@ jobs: run: git config --system core.longpaths true - name: Checkout revive - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: path: revive submodules: recursive - name: Download Binary - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: name: resolc-${{ matrix.target }} path: resolc-bin @@ -81,7 +114,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout revive - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: path: revive submodules: true @@ -90,14 +123,18 @@ jobs: uses: ./revive/revive-differential-tests/.github/actions/compare-bytecode-hashes with: revive-differential-tests-path: revive/revive-differential-tests - hash-artifact-names: "hashes-linux-x86_64, hashes-macos-arm64, hashes-macos-x86_64, hashes-windows-x86_64" + hash-artifact-names: >- + hashes-linux-x86_64, + hashes-macos-arm64, + ${{ env.IS_PUSH_TO_MAIN == 'true' && 'hashes-macos-x86_64,' || '' }} + hashes-windows-x86_64 modes: ${{ env.MODES }} upload-artifact-name: hash-comparison-result run-e2e-tests: - needs: build + needs: build-linux runs-on: parity-large - timeout-minutes: 75 + timeout-minutes: 60 env: # Commit SHA that produced the polkadot-sdk crate pinned in Cargo.toml, # obtained from the crate's .cargo_vcs_info.json via: @@ -107,13 +144,13 @@ jobs: RUSTFLAGS: "-Awarnings" steps: - name: Checkout revive - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: path: revive submodules: recursive - name: Download Binary - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: name: resolc-x86_64-unknown-linux-musl path: ./resolc-bin @@ -123,7 +160,7 @@ jobs: run: chmod +x ./resolc-bin/resolc-x86_64-unknown-linux-musl - name: Checkout Polkadot SDK - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: repository: paritytech/polkadot-sdk ref: ${{ env.POLKADOT_SDK_REF }} @@ -176,4 +213,5 @@ jobs: needs: [compare-hashes, run-e2e-tests] runs-on: ubuntu-24.04 steps: - - run: echo "All jobs finished" + - name: Finish + run: echo "All jobs finished" diff --git a/.github/workflows/generate_versions.yml b/.github/workflows/generate_versions.yml index 57a67793..f7d3c002 100644 --- a/.github/workflows/generate_versions.yml +++ b/.github/workflows/generate_versions.yml @@ -13,12 +13,12 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: path: tmp - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: repository: paritytech/resolc-bin path: resolc-bin diff --git a/.github/workflows/hardhat.yml b/.github/workflows/hardhat.yml index 44821f62..a5800038 100644 --- a/.github/workflows/hardhat.yml +++ b/.github/workflows/hardhat.yml @@ -11,14 +11,20 @@ env: CI_HARDHAT_PROJECT_ROOT: tooling-projects/hardhat/erc20 jobs: + build: + uses: ./.github/workflows/reusable-build-linux.yml + with: + retention_days: 1 + use-hardhat: + needs: build runs-on: ubuntu-24.04 steps: - name: Checkout revive - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Download resolc Binary - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: name: resolc-x86_64-unknown-linux-musl path: resolc-bin diff --git a/.github/workflows/release-llvm.yml b/.github/workflows/release-llvm.yml index 4d445313..db2e52ac 100644 --- a/.github/workflows/release-llvm.yml +++ b/.github/workflows/release-llvm.yml @@ -72,7 +72,7 @@ jobs: permissions: contents: write # for uploading assets to release steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml index 662459ec..8e904fa2 100644 --- a/.github/workflows/release-nightly.yml +++ b/.github/workflows/release-nightly.yml @@ -19,7 +19,7 @@ jobs: has_commits: ${{ steps.check_commits.outputs.has_commits }} steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 ref: "main" @@ -60,18 +60,18 @@ jobs: needs: [build, check_commits] steps: - name: Checkout revive - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: path: revive - name: Checkout resolc-bin - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: repository: paritytech/resolc-bin path: resolc-bin - name: Download Artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: merge-multiple: true path: bins diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8205ec7a..f28c84df 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,6 +7,11 @@ on: pull_request: branches: ["main"] types: [opened, synchronize, labeled, unlabeled] + paths-ignore: + - "**.md" + - "book/**" + - "docs/**" + - "tooling-projects/**" concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -25,7 +30,7 @@ jobs: outputs: RELEASE_NOTES: ${{ steps.versions.outputs.RELEASE_NOTES }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Check versions id: versions @@ -72,7 +77,7 @@ jobs: environment: tags steps: - name: Download Artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: merge-multiple: true @@ -124,10 +129,10 @@ jobs: runs-on: ubuntu-24.04 environment: tags steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Download Artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: merge-multiple: true @@ -146,7 +151,7 @@ jobs: - name: npm pack run: npm -w js/resolc pack - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v6 with: name: npm_package path: "parity-resolc-*.tgz" diff --git a/.github/workflows/reusable-build-linux.yml b/.github/workflows/reusable-build-linux.yml new file mode 100644 index 00000000..a6ee9930 --- /dev/null +++ b/.github/workflows/reusable-build-linux.yml @@ -0,0 +1,41 @@ +name: Reusable Build — Linux + +on: + workflow_call: + inputs: + retention_days: + description: "Artifact retention days" + required: false + type: number + default: 1 + outputs: + url: + value: ${{ jobs.build.outputs.url }} + sha: + value: ${{ jobs.build.outputs.sha }} + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + name: Build Linux + runs-on: ubuntu-24.04 + outputs: + url: ${{ steps.build.outputs.url }} + sha: ${{ steps.build.outputs.sha }} + concurrency: + # Use `reusable-build` and not `${{ github.workflow }}` here so that callers share the same concurrency group. + group: reusable-build-x86_64-unknown-linux-musl-${{ github.sha }} + cancel-in-progress: false + steps: + - name: Checkout revive + uses: actions/checkout@v6 + + - name: Build resolc + id: build + uses: ./.github/actions/build-resolc + with: + target: x86_64-unknown-linux-musl + build-type: musl + retention-days: ${{ inputs.retention_days }} diff --git a/.github/workflows/reusable-build-macos.yml b/.github/workflows/reusable-build-macos.yml new file mode 100644 index 00000000..435f6222 --- /dev/null +++ b/.github/workflows/reusable-build-macos.yml @@ -0,0 +1,110 @@ +name: Reusable Build — macOS + +on: + workflow_call: + inputs: + retention_days: + description: "Artifact retention days" + required: false + type: number + default: 1 + outputs: + aarch64-apple-darwin_url: + value: ${{ jobs.build.outputs.aarch64-apple-darwin_url }} + aarch64-apple-darwin_sha: + value: ${{ jobs.build.outputs.aarch64-apple-darwin_sha }} + x86_64-apple-darwin_url: + value: ${{ jobs.build.outputs.x86_64-apple-darwin_url }} + x86_64-apple-darwin_sha: + value: ${{ jobs.build.outputs.x86_64-apple-darwin_sha }} + universal-apple-darwin_url: + value: ${{ jobs.create-universal.outputs.url }} + universal-apple-darwin_sha: + value: ${{ jobs.create-universal.outputs.sha }} + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + name: Build macOS (${{ matrix.target }}) + # GH Actions matrix jobs don't support multiple outputs. + # Workaround from https://github.com/orgs/community/discussions/17245#discussioncomment-11222880 + outputs: + aarch64-apple-darwin_url: ${{ steps.set-output.outputs.aarch64-apple-darwin_url }} + aarch64-apple-darwin_sha: ${{ steps.set-output.outputs.aarch64-apple-darwin_sha }} + x86_64-apple-darwin_url: ${{ steps.set-output.outputs.x86_64-apple-darwin_url }} + x86_64-apple-darwin_sha: ${{ steps.set-output.outputs.x86_64-apple-darwin_sha }} + strategy: + fail-fast: false + matrix: + include: + - target: aarch64-apple-darwin + runner: macos-15 + - target: x86_64-apple-darwin + # `macos-15-intel` will be the last x86_64 `macos` image supported by GHA. + # It will be available until Aug. 2027 (see https://github.com/actions/runner-images/issues/13045). + runner: macos-15-intel + runs-on: ${{ matrix.runner }} + concurrency: + # Use `reusable-build` and not `${{ github.workflow }}` here so that callers share the same concurrency group. + group: reusable-build-${{ matrix.target }}-${{ github.sha }} + cancel-in-progress: false + steps: + - name: Checkout revive + uses: actions/checkout@v6 + + - name: Build resolc + id: build + uses: ./.github/actions/build-resolc + with: + target: ${{ matrix.target }} + build-type: native + retention-days: ${{ inputs.retention_days }} + + - name: Set Output Variables + id: set-output + shell: bash + run: | + echo "${{ matrix.target }}_url=${{ steps.build.outputs.url }}" >> "$GITHUB_OUTPUT" + echo "${{ matrix.target }}_sha=${{ steps.build.outputs.sha }}" >> "$GITHUB_OUTPUT" + + create-universal: + name: Build macOS (universal) + needs: build + runs-on: macos-15 + outputs: + url: ${{ steps.upload.outputs.artifact-url }} + sha: ${{ steps.upload.outputs.artifact-digest }} + concurrency: + # Use `reusable-build` and not `${{ github.workflow }}` here so that callers share the same concurrency group. + group: reusable-build-universal-apple-darwin-${{ github.sha }} + cancel-in-progress: false + steps: + - name: Check Build Cache + id: cache + uses: actions/cache@v5 + with: + path: resolc-universal-apple-darwin + key: build-universal-apple-darwin-${{ github.sha }} + + - name: Download macOS Artifacts + if: ${{ steps.cache.outputs.cache-hit != 'true' }} + uses: actions/download-artifact@v7 + with: + pattern: resolc-*-apple-darwin + merge-multiple: true + + - name: Create macOS Universal Binary + if: ${{ steps.cache.outputs.cache-hit != 'true' }} + run: | + lipo resolc-aarch64-apple-darwin resolc-x86_64-apple-darwin -create -output resolc-universal-apple-darwin + chmod +x resolc-universal-apple-darwin + + - name: Upload Universal Binary + id: upload + uses: actions/upload-artifact@v6 + with: + name: resolc-universal-apple-darwin + path: resolc-universal-apple-darwin + retention-days: ${{ inputs.retention_days }} diff --git a/.github/workflows/reusable-build-wasm.yml b/.github/workflows/reusable-build-wasm.yml new file mode 100644 index 00000000..b9a6b7e3 --- /dev/null +++ b/.github/workflows/reusable-build-wasm.yml @@ -0,0 +1,180 @@ +name: Reusable Build — Wasm + +on: + workflow_call: + inputs: + is_release: + description: "Whether this is a release build" + required: true + type: boolean + retention_days: + description: "Artifact retention days" + required: false + type: number + default: 1 + outputs: + resolc_web_js_url: + value: ${{ jobs.build.outputs.resolc_web_js_url }} + resolc_web_js_sha: + value: ${{ jobs.build.outputs.resolc_web_js_sha }} + +env: + CARGO_TERM_COLOR: always + EMSCRIPTEN_TARGET: wasm32-unknown-emscripten + HOST_TARGET: x86_64-unknown-linux-gnu + +jobs: + build: + name: Build Wasm + runs-on: ubuntu-24.04 + outputs: + resolc_web_js_url: ${{ steps.upload-web-js.outputs.artifact-url }} + resolc_web_js_sha: ${{ steps.upload-web-js.outputs.artifact-digest }} + concurrency: + # Use `reusable-build` and not `${{ github.workflow }}` here so that callers share the same concurrency group. + group: reusable-build-wasm32-unknown-emscripten-${{ github.sha }} + cancel-in-progress: false + steps: + - name: Checkout revive + uses: actions/checkout@v6 + + - name: Check Build Cache + id: cache + uses: actions/cache@v5 + with: + path: resolc-${{ env.EMSCRIPTEN_TARGET }} + key: build-${{ env.EMSCRIPTEN_TARGET }}-${{ github.sha }} + + - name: Set Up Rust Toolchain + if: ${{ steps.cache.outputs.cache-hit != 'true' }} + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + # Pin to 1.92.0 until LLVM Wasm libraries are rebuilt with -fwasm-exceptions + # See: https://github.com/paritytech/revive/pull/463 + toolchain: "1.92.0" + target: ${{ env.EMSCRIPTEN_TARGET }} + rustflags: "" + + - name: Download Host LLVM + if: ${{ steps.cache.outputs.cache-hit != 'true' }} + uses: ./.github/actions/get-llvm + with: + target: ${{ env.HOST_TARGET }} + + - name: Download Wasm LLVM + if: ${{ steps.cache.outputs.cache-hit != 'true' }} + uses: ./.github/actions/get-llvm + with: + target: ${{ env.EMSCRIPTEN_TARGET }} + + - name: Download EMSDK + if: ${{ steps.cache.outputs.cache-hit != 'true' }} + uses: ./.github/actions/get-emsdk + + - name: Build + if: ${{ steps.cache.outputs.cache-hit != 'true' }} + env: + # Consumed by js/emscripten/build.js. + RELEASE_RESOLC_WASM_URI: ${{ inputs.is_release && format('https://github.com/paritytech/revive/releases/download/{0}/resolc.wasm', github.ref_name) || '' }} + run: | + export LLVM_SYS_221_PREFIX=$PWD/llvm-${{ env.HOST_TARGET }} + export REVIVE_LLVM_TARGET_PREFIX=$PWD/llvm-${{ env.EMSCRIPTEN_TARGET }} + source emsdk/emsdk_env.sh + make install-wasm + chmod -x ./target/${{ env.EMSCRIPTEN_TARGET }}/release/resolc.wasm + + - name: Move Artifacts + if: ${{ steps.cache.outputs.cache-hit != 'true' }} + run: | + mkdir -p resolc-${{ env.EMSCRIPTEN_TARGET }} + mv ./target/${{ env.EMSCRIPTEN_TARGET }}/release/resolc.js ./resolc-${{ env.EMSCRIPTEN_TARGET }}/ + mv ./target/${{ env.EMSCRIPTEN_TARGET }}/release/resolc.wasm ./resolc-${{ env.EMSCRIPTEN_TARGET }}/ + mv ./target/${{ env.EMSCRIPTEN_TARGET }}/release/resolc_web.js ./resolc-${{ env.EMSCRIPTEN_TARGET }}/ + + - name: Set Up Node.js + uses: actions/setup-node@v6 + with: + node-version: "24" + + - name: Basic Sanity Check + run: | + mkdir -p solc + curl -sSLo solc/soljson.js https://github.com/argotorg/solidity/releases/download/v0.8.35/soljson.js + node -e " + // Make sure to require './solc/soljson' and not 'solc/soljson' in order to use + // the explicitly downloaded solc, rather than resolving an npm package potentially + // installed in prior workflow steps. + const soljson = require('./solc/soljson'); + const createRevive = require('./resolc-${{ env.EMSCRIPTEN_TARGET }}/resolc.js'); + + const compiler = createRevive(); + compiler.soljson = soljson; + + const standardJsonInput = + { + language: 'Solidity', + sources: { + 'MyContract.sol': { + content: 'pragma solidity ^0.8.0; contract MyContract { function greet() public pure returns (string memory) { return \'Hello\'; } }', + }, + }, + settings: { + optimizer: { enabled: false }, + outputSelection: { + '*': { + '*': ['evm.bytecode'] + } + } + } + }; + + compiler.writeToStdin(JSON.stringify(standardJsonInput)); + compiler.callMain(['--standard-json']); + + const stdout = compiler.readFromStdout(); + const stderr = compiler.readFromStderr(); + + if (stderr) { console.error(stderr); process.exit(1); } + + let out = JSON.parse(stdout); + let bytecode = out.contracts['MyContract.sol']['MyContract'].evm.bytecode.object + console.log(bytecode); + + if(!bytecode.startsWith('50564d')) { process.exit(1); } + " + + - name: Upload Bundle Artifact (Release) + if: ${{ inputs.is_release }} + uses: actions/upload-artifact@v6 + with: + name: resolc-${{ env.EMSCRIPTEN_TARGET }} + path: resolc-${{ env.EMSCRIPTEN_TARGET }}/* + retention-days: ${{ inputs.retention_days }} + + # There is no way to upload several files as several artifacts with a single upload-artifact step. + # It's needed to have resolc_web.js separately for nightly builds for resolc-bin repo. + # https://github.com/actions/upload-artifact/issues/331 + - name: Upload resolc.js (Nightly) + if: ${{ !inputs.is_release }} + uses: actions/upload-artifact@v6 + with: + name: resolc.js + path: resolc-${{ env.EMSCRIPTEN_TARGET }}/resolc.js + retention-days: ${{ inputs.retention_days }} + + - name: Upload resolc.wasm (Nightly) + if: ${{ !inputs.is_release }} + uses: actions/upload-artifact@v6 + with: + name: resolc.wasm + path: resolc-${{ env.EMSCRIPTEN_TARGET }}/resolc.wasm + retention-days: ${{ inputs.retention_days }} + + - name: Upload resolc_web.js (Nightly) + if: ${{ !inputs.is_release }} + id: upload-web-js + uses: actions/upload-artifact@v6 + with: + name: resolc_web.js + path: resolc-${{ env.EMSCRIPTEN_TARGET }}/resolc_web.js + retention-days: ${{ inputs.retention_days }} diff --git a/.github/workflows/reusable-build-windows.yml b/.github/workflows/reusable-build-windows.yml new file mode 100644 index 00000000..b6161625 --- /dev/null +++ b/.github/workflows/reusable-build-windows.yml @@ -0,0 +1,44 @@ +name: Reusable Build — Windows + +on: + workflow_call: + inputs: + retention_days: + description: "Artifact retention days" + required: false + type: number + default: 1 + outputs: + url: + value: ${{ jobs.build.outputs.url }} + sha: + value: ${{ jobs.build.outputs.sha }} + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + name: Build Windows + runs-on: windows-2022 + outputs: + url: ${{ steps.build.outputs.url }} + sha: ${{ steps.build.outputs.sha }} + concurrency: + # Use `reusable-build` and not `${{ github.workflow }}` here so that callers share the same concurrency group. + group: reusable-build-x86_64-pc-windows-msvc-${{ github.sha }} + cancel-in-progress: false + steps: + - name: Enable Long Paths + run: git config --system core.longpaths true + + - name: Checkout revive + uses: actions/checkout@v6 + + - name: Build resolc + id: build + uses: ./.github/actions/build-resolc + with: + target: x86_64-pc-windows-msvc + build-type: native + retention-days: ${{ inputs.retention_days }} diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml index a9acc336..6f5d9e67 100644 --- a/.github/workflows/reusable-build.yml +++ b/.github/workflows/reusable-build.yml @@ -14,374 +14,48 @@ on: default: 1 outputs: resolc-x86_64-unknown-linux-musl_url: - value: ${{ jobs.build.outputs.resolc-x86_64-unknown-linux-musl_url }} + value: ${{ jobs.build-linux.outputs.url }} resolc-x86_64-unknown-linux-musl_sha: - value: ${{ jobs.build.outputs.resolc-x86_64-unknown-linux-musl_sha }} + value: ${{ jobs.build-linux.outputs.sha }} resolc-aarch64-apple-darwin_url: - value: ${{ jobs.build.outputs.resolc-aarch64-apple-darwin_url }} + value: ${{ jobs.build-macos.outputs.aarch64-apple-darwin_url }} resolc-aarch64-apple-darwin_sha: - value: ${{ jobs.build.outputs.resolc-aarch64-apple-darwin_sha }} + value: ${{ jobs.build-macos.outputs.aarch64-apple-darwin_sha }} resolc-x86_64-apple-darwin_url: - value: ${{ jobs.build.outputs.resolc-x86_64-apple-darwin_url }} + value: ${{ jobs.build-macos.outputs.x86_64-apple-darwin_url }} resolc-x86_64-apple-darwin_sha: - value: ${{ jobs.build.outputs.resolc-x86_64-apple-darwin_sha }} + value: ${{ jobs.build-macos.outputs.x86_64-apple-darwin_sha }} resolc-universal-apple-darwin_url: - value: ${{ jobs.create-macos-universal.outputs.resolc-universal-apple-darwin_url }} + value: ${{ jobs.build-macos.outputs.universal-apple-darwin_url }} resolc-universal-apple-darwin_sha: - value: ${{ jobs.create-macos-universal.outputs.resolc-universal-apple-darwin_sha }} + value: ${{ jobs.build-macos.outputs.universal-apple-darwin_sha }} resolc-x86_64-pc-windows-msvc_url: - value: ${{ jobs.build.outputs.resolc-x86_64-pc-windows-msvc_url }} + value: ${{ jobs.build-windows.outputs.url }} resolc-x86_64-pc-windows-msvc_sha: - value: ${{ jobs.build.outputs.resolc-x86_64-pc-windows-msvc_sha }} + value: ${{ jobs.build-windows.outputs.sha }} resolc-web_js_url: value: ${{ jobs.build-wasm.outputs.resolc_web_js_url }} resolc-web_js_sha: value: ${{ jobs.build-wasm.outputs.resolc_web_js_sha }} -env: - CARGO_TERM_COLOR: always - RUST_MUSL_CROSS_IMAGE: messense/rust-musl-cross@sha256:2a8837c43bf12e246f1ebd05191de9ee27fcd22f9ca81511ccd4cf75dc16d71c - # An empty string is interpreted as the latest published release (default behavior). - # To test a specific draft release, use the full name (e.g. "llvm-21.1.8-revive.5789e11"). - LLVM_VERSION: "" - jobs: - build: - # github actions matrix jobs don't support multiple outputs - # ugly workaround from https://github.com/orgs/community/discussions/17245#discussioncomment-11222880 - outputs: - resolc-x86_64-unknown-linux-musl_url: ${{ steps.set-output.outputs.resolc-x86_64-unknown-linux-musl_url }} - resolc-x86_64-unknown-linux-musl_sha: ${{ steps.set-output.outputs.resolc-x86_64-unknown-linux-musl_sha }} - resolc-aarch64-apple-darwin_url: ${{ steps.set-output.outputs.resolc-aarch64-apple-darwin_url }} - resolc-aarch64-apple-darwin_sha: ${{ steps.set-output.outputs.resolc-aarch64-apple-darwin_sha }} - resolc-x86_64-apple-darwin_url: ${{ steps.set-output.outputs.resolc-x86_64-apple-darwin_url }} - resolc-x86_64-apple-darwin_sha: ${{ steps.set-output.outputs.resolc-x86_64-apple-darwin_sha }} - resolc-x86_64-pc-windows-msvc_url: ${{ steps.set-output.outputs.resolc-x86_64-pc-windows-msvc_url }} - resolc-x86_64-pc-windows-msvc_sha: ${{ steps.set-output.outputs.resolc-x86_64-pc-windows-msvc_sha }} - # Queue jobs for the same target and commit instead of running in parallel or cancelling - # the first job. This allows the second workflow to use cached builds from the first if - # it is triggered by the same commit. - # - # Example: Workflow A and Workflow B both call this workflow for the same commit: - # - # Time | Workflow A | Workflow B - # -----|---------------------------|--------------------------- - # T1 | Job starts, cache miss | - # T2 | Building... | Job queued (same group) - # T3 | Build done, cache saved | Job queued - # T4 | Job finishes | Job starts, cache hit - # T5 | | Skips build, job finishes - concurrency: - # Use `reusable-build` and not `${{ github.workflow }}` here so that callers share the same concurrency group. - group: reusable-build-${{ matrix.target }}-${{ github.sha }} - cancel-in-progress: false - strategy: - matrix: - target: - [ - x86_64-unknown-linux-musl, - aarch64-apple-darwin, - x86_64-apple-darwin, - x86_64-pc-windows-msvc, - ] - include: - - target: x86_64-unknown-linux-musl - type: musl - runner: ubuntu-24.04 - - target: aarch64-apple-darwin - type: native - runner: macos-15 - - target: x86_64-apple-darwin - type: native - # `macos-15-intel` will be the last x86_64 `macos` image supported by GHA. - # It will be available until Aug. 2027 (see https://github.com/actions/runner-images/issues/13045). - runner: macos-15-intel - - target: x86_64-pc-windows-msvc - type: native - runner: windows-2022 - runs-on: ${{ matrix.runner }} - steps: - - name: Enable long paths (Windows) - if: runner.os == 'Windows' - run: git config --system core.longpaths true - - uses: actions/checkout@v4 - - # Cache build artifacts by target and commit (restores if available, saves on cache miss). - - name: Check Build Cache - id: cache - uses: actions/cache@v5 - with: - # Use glob to match binaries with and without extensions. - path: resolc-${{ matrix.target }}* - key: build-${{ matrix.target }}-${{ github.sha }} - - - uses: actions-rust-lang/setup-rust-toolchain@v1 - if: ${{ steps.cache.outputs.cache-hit != 'true' }} - with: - rustflags: "" - cache-key: ${{ matrix.target }} - - - name: Download LLVM - if: ${{ steps.cache.outputs.cache-hit != 'true' }} - uses: ./.github/actions/get-llvm - with: - target: ${{ matrix.target }} - version: ${{ env.LLVM_VERSION }} + build-linux: + uses: ./.github/workflows/reusable-build-linux.yml + with: + retention_days: ${{ inputs.retention_days }} - - name: Build (Native) - if: ${{ steps.cache.outputs.cache-hit != 'true' && matrix.type == 'native' }} - shell: bash - run: | - export LLVM_SYS_221_PREFIX=$PWD/llvm-${{ matrix.target }} - make install-bin - mv target/release/resolc resolc-${{ matrix.target }} || mv target/release/resolc.exe resolc-${{ matrix.target }}.exe + build-macos: + uses: ./.github/workflows/reusable-build-macos.yml + with: + retention_days: ${{ inputs.retention_days }} - - name: Build (MUSL) - if: ${{ steps.cache.outputs.cache-hit != 'true' && matrix.type == 'musl' }} - run: | - docker run -v $PWD:/opt/revive $RUST_MUSL_CROSS_IMAGE /bin/bash -c " - cd /opt/revive - chown -R root:root . - apt update && apt upgrade -y && apt install -y pkg-config - export LLVM_SYS_221_PREFIX=/opt/revive/llvm-${{ matrix.target }} - make install-bin - mv target/${{ matrix.target }}/release/resolc resolc-${{ matrix.target }} - " - sudo chown -R $(id -u):$(id -g) . - - - name: Install Solc - uses: ./.github/actions/get-solc - - - name: Basic Sanity Check - shell: bash - run: | - result=$(./resolc-${{ matrix.target }} --bin crates/integration/contracts/flipper.sol) - echo $result - if [[ $result == *'50564d'* ]]; then exit 0; else exit 1; fi - - - uses: actions/upload-artifact@v4 - id: artifact-upload-step - with: - name: resolc-${{ matrix.target }} - path: resolc-${{ matrix.target }}* - retention-days: ${{ inputs.retention_days }} - - - name: Set output variables - if: ${{ !inputs.is_release }} - id: set-output - shell: bash - run: | - echo "resolc-${{ matrix.target }}_url=${{ steps.artifact-upload-step.outputs.artifact-url }}" >> "$GITHUB_OUTPUT" - echo "resolc-${{ matrix.target }}_sha=${{ steps.artifact-upload-step.outputs.artifact-digest }}" >> "$GITHUB_OUTPUT" - - create-macos-universal: - needs: build - runs-on: macos-15 - concurrency: - # Use `reusable-build` and not `${{ github.workflow }}` here so that callers share the same concurrency group. - group: reusable-build-universal-apple-darwin-${{ github.sha }} - cancel-in-progress: false - outputs: - resolc-universal-apple-darwin_url: ${{ steps.set-output.outputs.resolc-universal-apple-darwin_url }} - resolc-universal-apple-darwin_sha: ${{ steps.set-output.outputs.resolc-universal-apple-darwin_sha }} - steps: - - name: Check Build Cache - id: cache - uses: actions/cache@v5 - with: - path: resolc-universal-apple-darwin - key: build-universal-apple-darwin-${{ github.sha }} - - - name: Download macOS Artifacts - if: ${{ steps.cache.outputs.cache-hit != 'true' }} - uses: actions/download-artifact@v4 - with: - pattern: resolc-*-apple-darwin - merge-multiple: true - - - name: Create macOS Fat Binary - if: ${{ steps.cache.outputs.cache-hit != 'true' }} - run: | - lipo resolc-aarch64-apple-darwin resolc-x86_64-apple-darwin -create -output resolc-universal-apple-darwin - chmod +x resolc-universal-apple-darwin - - - name: Upload Universal Binary - uses: actions/upload-artifact@v4 - id: artifact-upload-step - with: - name: resolc-universal-apple-darwin - path: resolc-universal-apple-darwin - retention-days: ${{ inputs.retention_days }} - - - name: Set output variables - if: ${{ !inputs.is_release }} - id: set-output - run: | - echo "resolc-universal-apple-darwin_url=${{ steps.artifact-upload-step.outputs.artifact-url }}" >> "$GITHUB_OUTPUT" - echo "resolc-universal-apple-darwin_sha=${{ steps.artifact-upload-step.outputs.artifact-digest }}" >> "$GITHUB_OUTPUT" + build-windows: + uses: ./.github/workflows/reusable-build-windows.yml + with: + retention_days: ${{ inputs.retention_days }} build-wasm: - runs-on: ubuntu-24.04 - outputs: - resolc_web_js_url: ${{ steps.set-output.outputs.resolc_web_js_url }} - resolc_web_js_sha: ${{ steps.set-output.outputs.resolc_web_js_sha }} - # Queue jobs for the same target and commit instead of running in parallel or cancelling - # the first job. This allows the second workflow to use cached builds from the first if - # it is triggered by the same commit. - concurrency: - # Use `reusable-build` and not `${{ github.workflow }}` here so that callers share the same concurrency group. - group: reusable-build-wasm32-unknown-emscripten-${{ github.sha }} - cancel-in-progress: false - env: - RELEASE_RESOLC_WASM_URI: https://github.com/paritytech/revive/releases/download/${{ github.ref_name }}/resolc.wasm - steps: - - uses: actions/checkout@v4 - - # Cache build artifacts by commit (restores if available, saves on cache miss). - - name: Check Build Cache - id: cache - uses: actions/cache@v5 - with: - path: resolc-wasm32-unknown-emscripten - key: build-wasm32-unknown-emscripten-${{ github.sha }} - - # Pin to 1.92.0 until LLVM WASM libraries are rebuilt with -fwasm-exceptions - # See: https://github.com/paritytech/revive/issues/XXX - - uses: actions-rust-lang/setup-rust-toolchain@v1 - if: ${{ steps.cache.outputs.cache-hit != 'true' }} - with: - toolchain: "1.92.0" - target: wasm32-unknown-emscripten - rustflags: "" - - - name: Download Host LLVM - if: ${{ steps.cache.outputs.cache-hit != 'true' }} - uses: ./.github/actions/get-llvm - with: - target: x86_64-unknown-linux-gnu - version: ${{ env.LLVM_VERSION }} - - - name: Download Wasm LLVM - if: ${{ steps.cache.outputs.cache-hit != 'true' }} - uses: ./.github/actions/get-llvm - with: - target: wasm32-unknown-emscripten - version: ${{ env.LLVM_VERSION }} - - - name: Download EMSDK - if: ${{ steps.cache.outputs.cache-hit != 'true' }} - uses: ./.github/actions/get-emsdk - - - name: Build - if: ${{ steps.cache.outputs.cache-hit != 'true' }} - run: | - export LLVM_SYS_221_PREFIX=$PWD/llvm-x86_64-unknown-linux-gnu - export REVIVE_LLVM_TARGET_PREFIX=$PWD/llvm-wasm32-unknown-emscripten - source emsdk/emsdk_env.sh - make install-wasm - chmod -x ./target/wasm32-unknown-emscripten/release/resolc.wasm - - - name: Compress Artifact - if: ${{ steps.cache.outputs.cache-hit != 'true' }} - run: | - mkdir -p resolc-wasm32-unknown-emscripten - mv ./target/wasm32-unknown-emscripten/release/resolc.js ./resolc-wasm32-unknown-emscripten/ - mv ./target/wasm32-unknown-emscripten/release/resolc.wasm ./resolc-wasm32-unknown-emscripten/ - mv ./target/wasm32-unknown-emscripten/release/resolc_web.js ./resolc-wasm32-unknown-emscripten/ - - - name: Set Up Node.js - uses: actions/setup-node@v6 - with: - node-version: "24" - - - name: Basic Sanity Check - run: | - mkdir -p solc - curl -sSLo solc/soljson.js https://github.com/argotorg/solidity/releases/download/v0.8.35/soljson.js - node -e " - // Make sure to require './solc/soljson' and not 'solc/soljson' in order to use - // the explicitly downloaded solc, rather than resolving an npm package potentially - // installed in prior workflow steps. - const soljson = require('./solc/soljson'); - const createRevive = require('./resolc-wasm32-unknown-emscripten/resolc.js'); - - const compiler = createRevive(); - compiler.soljson = soljson; - - const standardJsonInput = - { - language: 'Solidity', - sources: { - 'MyContract.sol': { - content: 'pragma solidity ^0.8.0; contract MyContract { function greet() public pure returns (string memory) { return \'Hello\'; } }', - }, - }, - settings: { - optimizer: { enabled: false }, - outputSelection: { - '*': { - '*': ['evm.bytecode'] - } - } - } - }; - - compiler.writeToStdin(JSON.stringify(standardJsonInput)); - compiler.callMain(['--standard-json']); - - const stdout = compiler.readFromStdout(); - const stderr = compiler.readFromStderr(); - - if (stderr) { console.error(stderr); process.exit(1); } - - let out = JSON.parse(stdout); - let bytecode = out.contracts['MyContract.sol']['MyContract'].evm.bytecode.object - console.log(bytecode); - - if(!bytecode.startsWith('50564d')) { process.exit(1); } - " - - - name: Upload artifacts (Release) - if: ${{ inputs.is_release }} - uses: actions/upload-artifact@v4 - with: - name: resolc-wasm32-unknown-emscripten - path: resolc-wasm32-unknown-emscripten/* - retention-days: ${{ inputs.retention_days }} - - # There is no way to upload several files as several artifacts with a single upload-artifact step - # It's needed to have resolc_web.js separately for night builds for resolc-bin repo - # https://github.com/actions/upload-artifact/issues/331 - - name: Upload artifact resolc.js (Nightly) - if: ${{ !inputs.is_release }} - uses: actions/upload-artifact@v4 - with: - name: resolc.js - path: resolc-wasm32-unknown-emscripten/resolc.js - retention-days: ${{ inputs.retention_days }} - - - name: Upload artifacts resolc.wasm (Nightly) - if: ${{ !inputs.is_release }} - uses: actions/upload-artifact@v4 - with: - name: resolc.wasm - path: resolc-wasm32-unknown-emscripten/resolc.wasm - retention-days: ${{ inputs.retention_days }} - - - name: Upload artifacts resolc_web.js (Nightly) - if: ${{ !inputs.is_release }} - uses: actions/upload-artifact@v4 - id: artifact-upload-step - with: - name: resolc_web.js - path: resolc-wasm32-unknown-emscripten/resolc_web.js - retention-days: ${{ inputs.retention_days }} - - - name: Set output variables - if: ${{ !inputs.is_release }} - id: set-output - env: - TARGET: resolc_web_js - run: | - echo "${TARGET}_url=${{ steps.artifact-upload-step.outputs.artifact-url }}" >> "$GITHUB_OUTPUT" - echo "${TARGET}_sha=${{ steps.artifact-upload-step.outputs.artifact-digest }}" >> "$GITHUB_OUTPUT" + uses: ./.github/workflows/reusable-build-wasm.yml + with: + is_release: ${{ inputs.is_release }} + retention_days: ${{ inputs.retention_days }} diff --git a/.github/workflows/test-wasm.yml b/.github/workflows/test-wasm.yml index 5135a7d7..07311296 100644 --- a/.github/workflows/test-wasm.yml +++ b/.github/workflows/test-wasm.yml @@ -1,14 +1,20 @@ -name: Test Wasm Version +name: Test Wasm on: push: branches: ["main"] paths-ignore: - "**.md" + - "book/**" + - "docs/**" + - "tooling-projects/**" pull_request: branches: ["main"] types: [opened, synchronize] paths-ignore: - "**.md" + - "book/**" + - "docs/**" + - "tooling-projects/**" concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -20,52 +26,10 @@ env: jobs: build: - runs-on: ubuntu-24.04 - defaults: - run: - shell: bash - steps: - - uses: actions/checkout@v4 - # Pin to 1.92.0 until LLVM WASM libraries are rebuilt with -fwasm-exceptions - # See: https://github.com/paritytech/revive/issues/XXX - - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: "1.92.0" - target: wasm32-unknown-emscripten - # without this it will override our rust flags - rustflags: "" - - - name: Download Host LLVM - uses: ./.github/actions/get-llvm - with: - target: x86_64-unknown-linux-gnu - - - name: Download Wasm LLVM - uses: ./.github/actions/get-llvm - with: - target: wasm32-unknown-emscripten - - - name: Install emsdk - uses: ./.github/actions/get-emsdk - - - name: Set LLVM Environment Variables - run: | - echo "LLVM_SYS_221_PREFIX=$(pwd)/llvm-x86_64-unknown-linux-gnu" >> $GITHUB_ENV - echo "REVIVE_LLVM_TARGET_PREFIX=$(pwd)/llvm-wasm32-unknown-emscripten" >> $GITHUB_ENV - - - name: Build Revive - run: | - source emsdk/emsdk_env.sh - make install-wasm - - - uses: actions/upload-artifact@v4 - with: - name: revive-wasm - path: | - ${{ env.REVIVE_WASM_INSTALL_DIR }}/resolc.js - ${{ env.REVIVE_WASM_INSTALL_DIR }}/resolc.wasm - ${{ env.REVIVE_WASM_INSTALL_DIR }}/resolc_web.js - retention-days: 1 + uses: ./.github/workflows/reusable-build-wasm.yml + with: + is_release: false + retention_days: 1 test: needs: build @@ -74,15 +38,14 @@ jobs: os: ["ubuntu-24.04", "macos-15", "windows-2022"] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - name: Checkout revive + uses: actions/checkout@v6 - - name: Create Target Directory - run: mkdir -p ${{ env.REVIVE_WASM_INSTALL_DIR }} - - - name: Download Artifact - uses: actions/download-artifact@v4 + - name: Download Artifacts + uses: actions/download-artifact@v7 with: - name: revive-wasm + pattern: resolc*.{js,wasm} + merge-multiple: true path: ${{ env.REVIVE_WASM_INSTALL_DIR }} - name: Set Up Node.js @@ -103,8 +66,18 @@ jobs: echo "Running tests for ${{ matrix.os }}" npm run -w js/resolc test - - name: Run Playwright tests + - name: Run Playwright Tests run: | cd js/emscripten npx playwright install --with-deps npx playwright test + + - name: Upload Playwright Debug Artifacts + if: always() + uses: actions/upload-artifact@v6 + with: + name: playwright-debug-${{ matrix.os }} + path: | + js/emscripten/test-results.json + js/emscripten/test-results/ + retention-days: 2 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5a2533b3..2fe90ac5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,13 +2,9 @@ name: Test on: push: branches: ["main"] - paths-ignore: - - "**.md" pull_request: branches: ["main"] types: [opened, synchronize] - paths-ignore: - - "**.md" concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -21,7 +17,7 @@ jobs: test: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: # without this it will override our rust flags @@ -61,11 +57,69 @@ jobs: - name: Test docs run: make doc + # Used as a gate for subjobs that should run only if `test` succeeds + # and files relevant for the specific job have changed. + check-changes: + runs-on: ubuntu-24.04 + outputs: + should-run-differential-tests: ${{ steps.filter.outputs.should-run-differential-tests }} + should-run-hardhat-tests: ${{ steps.filter.outputs.should-run-hardhat-tests }} + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Diff Files + run: | + git diff --name-only \ + ${{ github.event.pull_request.base.sha || github.event.before }}...HEAD \ + > changed-files.txt + + - name: Check If Relevant Files Changed + id: filter + run: | + print_changed_files() { + local file_count + file_count=$(wc -l < changed-files.txt | tr -d ' ') + echo "Changed files ($file_count total):" + sed 's/^/ /' changed-files.txt + echo + } + + has_changes_other_than() { + local IFS='|' + local ignored="$*" + grep -qvE "$ignored" changed-files.txt && echo true || echo false + } + + print_changed_files + + echo "should-run-differential-tests=$(has_changes_other_than \ + '\.md$' \ + '^book/' \ + '^docs/' \ + '^js/' \ + '^package\.json$' \ + '^package-lock\.json$' \ + '^tooling-projects/' \ + )" | tee -a "$GITHUB_OUTPUT" + + echo "should-run-hardhat-tests=$(has_changes_other_than \ + '\.md$' \ + '^book/' \ + '^docs/' \ + '^js/' \ + '^package\.json$' \ + '^package-lock\.json$' \ + )" | tee -a "$GITHUB_OUTPUT" + run-differential-tests: - # Only run this if `test` successfully completes. - needs: test + needs: [test, check-changes] + if: ${{ needs.check-changes.outputs.should-run-differential-tests == 'true' }} uses: ./.github/workflows/differential-tests.yml run-hardhat-tests: - needs: run-differential-tests + needs: [test, check-changes] + if: ${{ needs.check-changes.outputs.should-run-hardhat-tests == 'true' }} uses: ./.github/workflows/hardhat.yml diff --git a/js/emscripten/playwright.config.js b/js/emscripten/playwright.config.js index 300d79f2..7c022f7c 100644 --- a/js/emscripten/playwright.config.js +++ b/js/emscripten/playwright.config.js @@ -14,16 +14,19 @@ module.exports = defineConfig({ /* Opt out of parallel tests on CI. */ workers: process.env.CI ? 1 : undefined, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ - reporter: "list", + reporter: [ + ["list"], + ["json", { outputFile: "test-results.json" }], + ], /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ use: { /* Base URL to use in actions like `await page.goto('/')`. */ baseURL: "http://127.0.0.1:8080", - /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ - trace: "on-first-retry", + /* Collect trace for any failed test attempt. See https://playwright.dev/docs/trace-viewer */ + trace: "retain-on-failure", }, - timeout: 480000, + timeout: 60000, /* Configure projects for major browsers */ projects: [ { diff --git a/revive-differential-tests b/revive-differential-tests index 0ff2c831..70e8a92f 160000 --- a/revive-differential-tests +++ b/revive-differential-tests @@ -1 +1 @@ -Subproject commit 0ff2c831112de6cd89c4a7926aa9e341643b079f +Subproject commit 70e8a92f95bb73b6b2aa244f1bba46e0501e34f1