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-is-release-${{ inputs.is_release }}-${{ github.sha }} cancel-in-progress: false queue: max 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 }}-is-release-${{ inputs.is_release }}-${{ 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. # For nightly Wasm releases, this URI is currently broken (see https://github.com/paritytech/revive/issues/542). 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.36/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 }}