Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
96f11a1
Add script for compiling and generating hashes.
elle-j Feb 2, 2026
ff7fd85
Add script for comparing generated hashes.
elle-j Feb 2, 2026
1a31d89
Add GHA workflow for verifying reproducible builds.
elle-j Feb 2, 2026
e5e020c
Trigger new test-builds workflow after tests succeed.
elle-j Feb 2, 2026
0bd1995
Handle multiple compiled contracts from the same file.
elle-j Feb 2, 2026
e9ea206
Normalize the file path added as part of the hash entry.
elle-j Feb 2, 2026
364dd23
Fix concurrency group deadlock and reuse builds.
elle-j Feb 2, 2026
4b2c99f
Fix npm resolving which solc to use in sanity check.
elle-j Feb 2, 2026
6759c9e
Fix Windows 'Filename too long' error.
elle-j Feb 3, 2026
d967c82
Allow passing one contracts directory.
elle-j Feb 3, 2026
4e73e59
Move repeated logic into function.
elle-j Feb 3, 2026
2df795d
Make chosen optimization levels configurable by caller.
elle-j Feb 3, 2026
2bbe953
Try fix Windows hanging and add debug output.
elle-j Feb 3, 2026
f381f4e
Temporarily remove timeout-minutes.
elle-j Feb 3, 2026
b6635a9
Fix early termination.
elle-j Feb 4, 2026
c9e683c
Fix artifact upload on Windows.
elle-j Feb 5, 2026
a6f7c35
Refactor into Node scripts for shared logic across platforms.
elle-j Feb 9, 2026
e539d9e
Add Wasm to workflow job.
elle-j Feb 9, 2026
812d18a
Compile in project units to allow resolving imports.
elle-j Feb 10, 2026
b5e60af
Update workflow name in concurrency group id.
elle-j Feb 11, 2026
7267f63
Resolve import resolution for Windows.
elle-j Feb 11, 2026
e803931
Minor output update.
elle-j Feb 11, 2026
a0d6e7b
Update workflow name in concurrency group id.
elle-j Feb 12, 2026
396570f
Update to named arguments for easier use and maintenance.
elle-j Feb 12, 2026
5695cb6
Fix missing backslash.
elle-j Feb 12, 2026
8f1ded6
Merge branch 'main' into lj/ci-retester
elle-j Mar 12, 2026
c9d4aa3
Replace revive scripts with actions from the differential tests repo.
elle-j Mar 12, 2026
0123ad9
Update revive-differential-tests ref.
elle-j Mar 12, 2026
27da4b1
Update matrix.
elle-j Mar 12, 2026
eba7b9e
Update revive-differential-tests ref.
elle-j Mar 12, 2026
d8d1c08
Update revive-differential-tests ref.
elle-j Mar 13, 2026
fc8221e
Update revive-differential-tests ref.
elle-j Mar 13, 2026
ed39df3
Update revive-differential-tests ref.
elle-j Mar 17, 2026
352aa56
Update revive-differential-tests ref.
elle-j Mar 18, 2026
c8e488b
Run differential E2E tests.
elle-j Mar 19, 2026
e4c811e
Merge branch 'main' into lj/ci-retester
elle-j Mar 19, 2026
fd5a1a3
Update revive-differential-tests ref.
elle-j Mar 19, 2026
193f360
Pass explicit solc version to E2E test run.
elle-j Mar 19, 2026
794a8b8
Update revive-differential-tests ref.
elle-j Mar 19, 2026
45e8004
Prevent differential tests from being canceled by sibling job failures.
elle-j Mar 19, 2026
5d2560d
Update revive-differential-tests ref.
elle-j Mar 19, 2026
5838412
Update Polkadot SDK ref.
elle-j Mar 25, 2026
6e7151d
Update revive-differential-tests ref.
elle-j Mar 26, 2026
285a940
Prevent differential tests from being canceled by sibling job failures.
elle-j Mar 26, 2026
5e00736
Update revive-differential-tests ref.
elle-j Mar 26, 2026
382bcab
Update revive-differential-tests ref.
elle-j Mar 30, 2026
72895f2
Use new LLVM draft release.
elle-j Mar 30, 2026
13ccf19
Add auth bearer to llvm donwload.
elle-j Mar 30, 2026
5ab5139
Try fetch draft release.
elle-j Mar 30, 2026
9bb537a
Add comments to action.
elle-j Mar 30, 2026
559c35a
Update revive-differential-tests ref.
elle-j Mar 30, 2026
b1ed29f
Use LLVM draft release with patch.
elle-j Apr 6, 2026
01ae964
Merge branch 'main' into lj/ci-retester
elle-j Apr 8, 2026
5093a99
Update revive-differential-tests ref.
elle-j Apr 8, 2026
a663d58
Run differential tests on parity-large.
elle-j Apr 8, 2026
d801f05
Try utilize forklift for Polkadot SDK.
elle-j Apr 8, 2026
784b9bb
Configure forklift.
elle-j Apr 8, 2026
1c38116
Add timeout-minutes to differential tests.
elle-j Apr 8, 2026
4d6c2ed
Update revive-differential-tests ref.
elle-j Apr 8, 2026
cfa1fb6
Add expectations files (expected failures) for differential tests.
elle-j Apr 9, 2026
d455b5f
Merge branch 'main' into lj/ci-retester
elle-j Apr 9, 2026
96f975e
Use new LLVM draft release.
elle-j Apr 9, 2026
a1d3e44
Merge branch 'main' into lj/ci-retester
elle-j Apr 9, 2026
51938f6
Use new published LLVM release.
elle-j Apr 9, 2026
6a363cc
Merge branch 'main' into lj/ci-retester
elle-j Apr 10, 2026
0e77060
Remove unnecessary platform from workflow matrix.
elle-j Apr 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/assets/revive-dev-node-polkavm-resolc.json
Copy link
Copy Markdown
Contributor Author

@elle-j elle-j Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the expectations file (expected test execution failures) generated by retester in this run.

Reason for the test execution failure of fixtures/solidity/simple/algorithm/cryptography/caesar_cypher.sol::2::Y M0 S-:

"Failed to execute all of the steps on the driver: Failure on step 0: Function call step Failed: Failed to handle function call assertions: Transaction status assertion failed - Expected true but got false. Revert reason: Some("ContractTrapped")"

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"fixtures/solidity/simple/algorithm/cryptography/caesar_cypher.sol::2::Y M0 S-": "Failed"
}
82 changes: 71 additions & 11 deletions .github/workflows/reusable-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ on:
env:
CARGO_TERM_COLOR: always
RUST_MUSL_CROSS_IMAGE: messense/rust-musl-cross@sha256:2a8837c43bf12e246f1ebd05191de9ee27fcd22f9ca81511ccd4cf75dc16d71c
# 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:
Expand All @@ -51,6 +54,23 @@ jobs:
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:
Expand Down Expand Up @@ -81,26 +101,39 @@ jobs:
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 }}

- name: Build (Native)
if: ${{ matrix.type == 'native' }}
if: ${{ steps.cache.outputs.cache-hit != 'true' && matrix.type == 'native' }}
shell: bash
run: |
export LLVM_SYS_211_PREFIX=$PWD/llvm-${{ matrix.target }}
make install-bin
mv target/release/resolc resolc-${{ matrix.target }} || mv target/release/resolc.exe resolc-${{ matrix.target }}.exe

- name: Build (MUSL)
if: ${{ matrix.type == '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
Expand Down Expand Up @@ -142,39 +175,70 @@ jobs:
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_211_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@v3
with:
Expand All @@ -185,8 +249,11 @@ jobs:
mkdir -p solc
curl -sSLo solc/soljson.js https://github.com/argotorg/solidity/releases/download/v0.8.34/soljson.js
node -e "
const soljson = require('solc/soljson');
const createRevive = require('./target/wasm32-unknown-emscripten/release/resolc.js');
// 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 jobs.
const soljson = require('./solc/soljson');
const createRevive = require('./resolc-wasm32-unknown-emscripten/resolc.js');

const compiler = createRevive();
compiler.soljson = soljson;
Expand Down Expand Up @@ -224,13 +291,6 @@ jobs:
if(!bytecode.startsWith('50564d')) { process.exit(1); }
"

- name: Compress Artifact
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: Upload artifacts (Release)
if: ${{ inputs.is_release }}
uses: actions/upload-artifact@v4
Expand Down
192 changes: 192 additions & 0 deletions .github/workflows/test-builds.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
name: Verify Reproducible Builds

on:
workflow_call:

env:
# The compiler modes to use for compilation by retester.
MODES: "Y M0 S+, Y M3 S+, Y Mz S+"
SOLC_VERSION: "0.8.33"

jobs:
build:
uses: ./.github/workflows/reusable-build.yml
with:
is_release: false
retention_days: 1

create-macos-universal:
needs: build
runs-on: macos-15
steps:
- name: Download MacOS artifacts
uses: actions/download-artifact@v4
with:
pattern: resolc-*-apple-darwin
merge-multiple: true

- name: Create MacOS Fat Binary
run: |
lipo resolc-aarch64-apple-darwin resolc-x86_64-apple-darwin -create -output resolc-universal-apple-darwin

- name: Upload Universal Binary
uses: actions/upload-artifact@v4
with:
name: resolc-universal-apple-darwin
path: resolc-universal-apple-darwin
retention-days: 1

compile-and-export-hashes-native:
needs: [build, create-macos-universal]
strategy:
fail-fast: false
matrix:
include:
- platform: linux
target: x86_64-unknown-linux-musl
runner: ubuntu-24.04
- platform: macos
target: universal-apple-darwin
runner: macos-15
- platform: windows
target: x86_64-pc-windows-msvc
runner: windows-2022
runs-on: ${{ matrix.runner }}
steps:
# For some deeply nested contracts in `resolc-compiler-tests`, Windows
# will generate a "Filename too long" error. This step enables long paths.
- name: Enable Git Long Paths (Windows)
if: ${{ runner.os == 'Windows' }}
run: git config --system core.longpaths true

- name: Checkout revive
uses: actions/checkout@v4
with:
path: revive
submodules: recursive

- name: Download Binary
uses: actions/download-artifact@v4
with:
name: resolc-${{ matrix.target }}
path: resolc-bin

- name: Make resolc Executable
shell: bash
run: chmod +x "resolc-bin/resolc-${{ matrix.target }}${{ runner.os == 'Windows' && '.exe' || '' }}"

- name: Compile Contracts
id: compile
uses: ./revive/revive-differential-tests/.github/actions/compile-contracts
with:
revive-differential-tests-path: revive/revive-differential-tests
resolc-path: resolc-bin/resolc-${{ matrix.target }}${{ runner.os == 'Windows' && '.exe' || '' }}
solc-version: ${{ env.SOLC_VERSION }}
modes: ${{ env.MODES }}
upload-artifact-name: compilation-report-${{ matrix.platform }}

- name: Export Bytecode Hashes
uses: ./revive/revive-differential-tests/.github/actions/export-bytecode-hashes
with:
revive-differential-tests-path: revive/revive-differential-tests
report-path: ${{ steps.compile.outputs.report-path }}
remove-prefix: ${{ steps.compile.outputs.contracts-source-prefix }}
platform-label: ${{ matrix.platform }}
upload-artifact-name: hashes-${{ matrix.platform }}

compare-hashes:
needs: compile-and-export-hashes-native
runs-on: ubuntu-24.04
steps:
- name: Checkout revive
uses: actions/checkout@v4
with:
path: revive
submodules: true

- name: Compare Bytecode Hashes
uses: ./revive/revive-differential-tests/.github/actions/compare-bytecode-hashes
with:
revive-differential-tests-path: revive/revive-differential-tests
hash-artifact-names: "hashes-linux, hashes-macos, hashes-windows"
modes: ${{ env.MODES }}
upload-artifact-name: hash-comparison-result

run-differential-tests:
needs: build
runs-on: parity-large
timeout-minutes: 75
env:
# TODO: Which Polkadot SDK commit do we want to use?
# The below one is as of March. 25, 2026.
POLKADOT_SDK_REF: "9d8a2fefd2414591c4a243460f3ffc5195a71deb"
Comment on lines +120 to +122
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a commit from Polkadot SDK main. Is there a particular tag we should use instead?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be aligned to what we have in Cargo.toml ? I.e. use the one that corresponds to 2507.4.0 ?

also, @xermicus, don't we need to also update this dependency ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we test against the exact same time everywhere

RUSTFLAGS: "-Awarnings"
steps:
- name: Checkout revive
uses: actions/checkout@v4
with:
path: revive
submodules: recursive

- name: Download Binary
uses: actions/download-artifact@v4
with:
name: resolc-x86_64-unknown-linux-musl
path: ./resolc-bin

- name: Make resolc Executable
shell: bash
run: chmod +x ./resolc-bin/resolc-x86_64-unknown-linux-musl

- name: Checkout Polkadot SDK
uses: actions/checkout@v4
with:
repository: paritytech/polkadot-sdk
ref: ${{ env.POLKADOT_SDK_REF }}
path: polkadot-sdk
submodules: recursive

- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential pkg-config libssl-dev protobuf-compiler llvm clang libclang-dev

- name: Install forklift
run: |
curl -fsSLo forklift https://github.com/paritytech/forklift/releases/download/0.15.0/forklift_0.15.0_linux_amd64
chmod +x forklift
sudo mv forklift /usr/local/bin/

- name: Configure forklift
run: |
mkdir -p .forklift
cp polkadot-sdk/.forklift/config.toml .forklift/config.toml

- name: Set Up Rust Toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: "1.90.0"
target: "wasm32-unknown-unknown"
components: "rust-src"
rustflags: ""

- name: Run Differential E2E Tests
uses: ./revive/revive-differential-tests/.github/actions/run-differential-tests
with:
revive-differential-tests-path: revive/revive-differential-tests
polkadot-sdk-path: ./polkadot-sdk
cargo-command: "forklift cargo"
platform: revive-dev-node-polkavm-resolc
resolc-path: ./resolc-bin/resolc-x86_64-unknown-linux-musl
solc-version: ${{ env.SOLC_VERSION }}
expectations-file-path: ./revive/.github/assets/revive-dev-node-polkavm-resolc.json

# Sentinel job that depends on the jobs we want to allow completing (instead of
# being canceled once the other job chains complete). Thus, run-differential-tests
# will always run even if compare-hashes finishes first, and vice versa.
wait-for-jobs:
if: ${{ always() }}
needs: [compare-hashes, run-differential-tests]
runs-on: ubuntu-24.04
steps:
- run: echo "All jobs finished"
5 changes: 5 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,8 @@ jobs:

- name: Test docs
run: make doc

test-builds:
# Only run this if `test` successfully completes.
needs: test
uses: ./.github/workflows/test-builds.yml
2 changes: 1 addition & 1 deletion revive-differential-tests
Loading