Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d9add2a
Refactor reusable-build into a per-build structure.
elle-j May 29, 2026
7b8151a
Refactor differential-tests to use individual reusable builds.
elle-j May 29, 2026
9819663
Refactor hardhat workflow to use individual reusable build.
elle-j May 29, 2026
c52f97f
Refactor test-wasm to use individual reusable build.
elle-j May 29, 2026
2130579
Small refactor to alleviate testing of LLVM draft releases.
elle-j May 29, 2026
0444b3a
Gate `RELEASE_RESOLC_WASM_URI` behind `is_release` input.
elle-j Jun 1, 2026
5bf5860
Use treeless LLVM clone and require LLVM version detection.
elle-j Jun 1, 2026
59b28a8
Update build job names for easier GH UI navigation.
elle-j Jun 1, 2026
3328a8c
Skip unrelated workflows when tooling-projects change.
elle-j Jun 1, 2026
79b28e7
Run hardhat tests only after required test job succeeds.
elle-j Jun 1, 2026
f6d3de1
Skip some workflow runs for doc-only updates.
elle-j Jun 1, 2026
a91135f
Remove paths-ignore from required test job.
elle-j Jun 1, 2026
641b427
Skip some workflow runs for package.json updates.
elle-j Jun 1, 2026
3d12278
Skip some workflow runs for package.json updates.
elle-j Jun 2, 2026
7d5d996
Update revive-differential-tests ref.
elle-j Jun 2, 2026
8964c31
Merge branch 'main' into lj/speedup-ci
elle-j Jun 2, 2026
719afc5
Update e2e timeout-minutes.
elle-j Jun 2, 2026
026bfbd
Trigger workflow rerun.
elle-j Jun 2, 2026
18301db
Update revive-differential-tests ref.
elle-j Jun 2, 2026
a68b3c6
Upgrade actions using Node 20.
elle-j Jun 2, 2026
a0ede88
Revert version upgrade on action in test-llvm-builder.
elle-j Jun 2, 2026
558855e
Revert automatic double quote replacement in test-llvm-builder.
elle-j Jun 2, 2026
0c82252
Update node-version in test-wasm.
elle-j Jun 2, 2026
39885ec
Capture Playwright traces on test-wasm failures.
elle-j Jun 2, 2026
f48782f
Trigger workflow rerun.
elle-j Jun 2, 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
86 changes: 86 additions & 0 deletions .github/actions/build-resolc/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
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
run: |
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.

I'd prefer to use our Dockerfile. Currently a two stage build yielding an alpine image including solc, so maybe we want to split the Dockerfile up.

Or what would be even better, split this action up into build-resolc-native and build-resolc-musl. build-musl just tries to build the Dockerfile and sanity check by using the built image to build a contract. This would build the native and musl linux builds in parallel and also ensure the Dockerfile works on CI.

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.

Good idea on testing the Dockerfile! Regarding native vs musl linux, I think we should still build the musl here though, because that's the binary we distribute so we'd be more confident if that's the build we're using for differential tests etc.

I looked at ways we could refactor the Dockerfile such that it can still be used as it is today (no semantic change), or optionally skip e.g. the LLVM stage if a prebuilt is passed. This way the Dockerfile will always be used for building the linux musl build and can also use the published LLVM.

The full Dockerfile can be tested via a separate workflow (running in parallel). Since building LLVM will take a while, we could e.g. run that on pushes to main only.

(If we go with the Dockerfile refactor, it may be better to add it as a follow-up PR to keep that change more isolated, and keep the preexisting build logic for this PR.)

Copy link
Copy Markdown
Member

@xermicus xermicus Jun 3, 2026

Choose a reason for hiding this comment

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

Dumb question: Why do we build the linux release target here at all? We should just be using the musl build on linux anyways from here on.

(I'm not saying we don't build the MUSL here, but instead of an inlined script that builds the MUSL binary inside the container, just build the Dockerfile, which is the exact same thing)

I don't think the Dockerfile needs a change. I think either we should extract the binary from the image or if thats too cumbersome, copy out the binary via running the image as the inline script does currently. WDYT?

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.

We should just be using the musl build on linux anyways from here on.

We're already only building the musl build. The "Build (Native)" step has only been used for Windows and macOS.

I'm not saying we don't build the MUSL here, but instead of an inlined script that builds the MUSL binary inside the container, just build the Dockerfile

Yeah I definitely agree that we should just build the Dockerfile and use the binary that it creates, but if it's built as-is that'd mean this is also unnecessarily run:

RUN make install-llvm-builder
RUN revive-llvm --target-env musl build  --llvm-projects lld --llvm-projects clang

What I meant is we could pass the LLVM we get from the get-llvm action into the Dockerfile to skip those two RUN lines. Otherwise, running the Dockerfile as-is would add the LLVM building overhead.

And we can still have another workflow exercising the entire Dockerfile, including building of LLVM, that could be skipped on PRs.

Let me know if this makes sense or if I may be missing something obvious here.

Copy link
Copy Markdown
Member

@xermicus xermicus Jun 3, 2026

Choose a reason for hiding this comment

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

You're right, I fired way too quickly. It just looked to me like we build native too. Good call, this would add a lot of unnecessary overhead, I didn't consider it!

Yeah I like your idea. IIRC you can COPY --from=imagename, so should work across separate docker build invocations too. This would allow to factor it out into 2 separate nice and small Dockerfiles (e.g. Dockerfile.llvm, Dockerfile.resolc) and then for this purpose we just mount in the musl LLVM build obtained from the get-llvm action. Maybe add a docker phony target to the Makefile which runs the two docker build commands, this kinda serves as documentation / shortcut for people that just want to build a portable docker image.

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.

Sounds good, created an issue for it here to have a focused PR for it 👍

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 }}
109 changes: 52 additions & 57 deletions .github/actions/get-llvm/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,52 @@
# 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"
steps:
- 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
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}

Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/book.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading
Loading