Skip to content

Commit

Permalink
Merge branch 'main' into fix/comment-on-failure
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxMustermann2 committed Nov 27, 2024
2 parents 510626d + 93a0a13 commit fc7c643
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 87 deletions.
189 changes: 125 additions & 64 deletions .github/workflows/compare-layouts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,21 @@ jobs:
# The cache storage in the reusable foundry setup takes far too long.
# Do this job first to update the commit status and comment ASAP.
set-commit-status:
# Typically takes no more than 30s
timeout-minutes: 10
runs-on: ubuntu-latest
outputs:
number: ${{ steps.pr-context.outputs.number }}
steps:
# Log the workflow trigger details for debugging.
- name: Echo workflow trigger details
run: |
echo "Workflow run event: ${{ github.event.workflow_run.event }}"
echo "Workflow run conclusion: ${{ github.event.workflow_run.conclusion }}"
echo "Workflow run name: ${{ github.event.workflow_run.name }}"
echo "Workflow run URL: ${{ github.event.workflow_run.html_url }}"
echo "Commit SHA: ${{ github.event.workflow_run.head_commit.id }}"
echo "Workflow Run ID: ${{ github.event.workflow_run.id }}"
- name: Set commit status
# trigger is no matter what, because the status should be updated
if: always()
Expand Down Expand Up @@ -73,97 +84,146 @@ jobs:
message: ${{ steps.set-message.outputs.message }}

setup:
# A full job can be used as a reusable workflow but not a step.
# The caching of the binaries is necessary because we run the job to fetch
# the deployed layouts via a matrix strategy. This job is the parent of that job.
uses: ./.github/workflows/reusable-foundry-setup.yml
with:
# The below line does not accept environment variables,
# so it becomes the single source of truth for the version, within this workflow.
# Any `pinning` of the version should be done here and forge-ci.yml.
# Any `pinning` of the version should be done here and in forge-ci.yml.
foundry-version: nightly
# Skip the setup job if the parent job failed.
skip-install: ${{ github.event.workflow_run.conclusion != 'success' }}

# The actual job to compare the storage layouts.
compare-storage-layouts:
needs:
- setup
- set-commit-status
create-deployed-layouts-matrix:
runs-on: ubuntu-latest

env:
ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }}
ETHERSCAN_API_KEY: ${{ secrets.ETHERSCAN_API_KEY }}

outputs:
matrix: ${{ steps.generate-matrix.outputs.matrix }}
steps:
# Log the workflow trigger details for debugging.
- name: Echo workflow trigger details
run: |
echo "Workflow run event: ${{ github.event.workflow_run.event }}"
echo "Workflow run conclusion: ${{ github.event.workflow_run.conclusion }}"
echo "Workflow run name: ${{ github.event.workflow_run.name }}"
echo "Workflow run URL: ${{ github.event.workflow_run.html_url }}"
echo "Commit SHA: ${{ github.event.workflow_run.head_commit.id }}"
echo "Workflow Run ID: ${{ github.event.workflow_run.id }}"
# The repository needs to be available for script/deployedContracts.json
# and script/compareLayouts.js. We do not restore the build data because
# the compiled layouts are restored from the artifact and not rebuilt.
- name: Checkout the repository
if: ${{ github.event.workflow_run.conclusion == 'success' }}
- name: Echo a message to avoid "no action run" warning.
run: echo "Creating the matrix for deployed layouts."
- name: Checkout code
uses: actions/checkout@v4
# The toolchain is needed to run `cast storage`
- name: Restore cached Foundry toolchain
if: ${{ github.event.workflow_run.conclusion == 'success' }}
uses: actions/cache/restore@v3
with:
path: ${{ needs.setup.outputs.installation-dir }}
key: ${{ needs.setup.outputs.cache-key }}
- name: Add Foundry to PATH
if: ${{ github.event.workflow_run.conclusion == 'success' }}
run: echo "${{ needs.setup.outputs.installation-dir }}" >> "$GITHUB_PATH"
- name: Fetch the deployed layouts
- name: Generate matrix from deployedContracts.json
id: generate-matrix
if: ${{ github.event.workflow_run.conclusion == 'success' }}
run: |
set -e
data=$(cat script/deployedContracts.json)
bootstrap=$(echo "$data" | jq -r '.clientChain.bootstrapLogic // empty')
clientGateway=$(echo "$data" | jq -r '.clientChain.clientGatewayLogic // empty')
vault=$(echo "$data" | jq -r '.clientChain.vaultImplementation // empty')
rewardVault=$(echo "$data" | jq -r '.clientChain.rewardVaultImplementation // empty')
capsule=$(echo "$data" | jq -r '.clientChain.capsuleImplementation // empty')
pwd=$(pwd)
cd /tmp
# Create an array of contract names and addresses
declare -A contracts=(
["Bootstrap"]="$bootstrap"
["ClientChainGateway"]="$clientGateway"
["Vault"]="$vault"
["RewardVault"]="$rewardVault"
["ExoCapsule"]="$capsule"
)
# Iterate over the array and run `cast storage` for each contract
# Create the matrix as a JSON array
matrix=$(jq -n \
--arg bootstrap "$bootstrap" \
--arg clientGateway "$clientGateway" \
--arg vault "$vault" \
--arg rewardVault "$rewardVault" \
--arg capsule "$capsule" \
'[{name: "Bootstrap", address: $bootstrap},
{name: "ClientChainGateway", address: $clientGateway},
{name: "Vault", address: $vault},
{name: "RewardVault", address: $rewardVault},
{name: "ExoCapsule", address: $capsule}] | map(select(.address != ""))')
echo "Matrix: $matrix"
echo "matrix=$(echo $matrix | jq -c .)" >> "${GITHUB_OUTPUT}"
fetch-deployed-layouts:
timeout-minutes: 30
strategy:
matrix:
# if the parent workflow failed, the matrix will be empty. hence, no jobs will run.
contract: ${{ fromJSON(needs.create-deployed-layouts-matrix.outputs.matrix) }}
needs:
- setup
- create-deployed-layouts-matrix
runs-on: ubuntu-latest
steps:
- name: Restore cached Foundry toolchain
uses: actions/cache/restore@v3
with:
path: ${{ needs.setup.outputs.installation-dir }}
key: ${{ needs.setup.outputs.cache-key }}
- name: Add Foundry to PATH
run: echo "${{ needs.setup.outputs.installation-dir }}" >> "$GITHUB_PATH"
- name: Fetch the deployed layout
env:
ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }}
ETHERSCAN_API_KEY: ${{ secrets.ETHERSCAN_API_KEY }}
run: |
echo "Processing ${{ matrix.contract.name }} at address ${{ matrix.contract.address }}"
RPC_URL="https://eth-sepolia.g.alchemy.com/v2/$ALCHEMY_API_KEY"
for contract in "${!contracts[@]}"; do
address=${contracts[$contract]}
if [[ -n $address ]]; then
echo "Processing $contract at address $address"
cast storage --json "$address" --rpc-url "$RPC_URL" \
--etherscan-api-key "$ETHERSCAN_API_KEY" > "$contract.deployed.json"
mv "$contract.deployed.json" "$pwd"
else
echo "Skipping $contract as no address is provided"
fi
done
cd "$pwd"
# Restore the layouts from the previous job
- name: Restore the layout files from the artifact
cast storage --json "${{ matrix.contract.address }}" \
--rpc-url "$RPC_URL" \
--etherscan-api-key "$ETHERSCAN_API_KEY" > "${{ matrix.contract.name }}.deployed.json"
- name: Upload the deployed layout file as an artifact
uses: actions/upload-artifact@v4
with:
path: ${{ matrix.contract.name }}.deployed.json
name: deployed-layout-${{ matrix.contract.name }}-${{ github.event.workflow_run.head_commit.id }}

combine-deployed-layouts:
needs: fetch-deployed-layouts
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Echo a message
run: echo "Combining the deployed layouts."
- name: Download artifacts
if: ${{ github.event.workflow_run.conclusion == 'success' }}
uses: actions/download-artifact@v4
with:
path: combined
- name: Zip up the deployed layouts
if: ${{ github.event.workflow_run.conclusion == 'success' }}
run: zip -j deployed-layouts.zip combined/*/*.json
- name: Upload the deployed layout files as an artifact
if: ${{ github.event.workflow_run.conclusion == 'success' }}
uses: actions/upload-artifact@v4
with:
path: deployed-layouts.zip
name: deployed-layouts-${{ github.event.workflow_run.head_commit.id }}

# The actual job to compare the storage layouts.
compare-storage-layouts:
# Typically takes no more than 7 minutes
timeout-minutes: 30
needs:
- setup
- set-commit-status
- combine-deployed-layouts
runs-on: ubuntu-latest

steps:
# The repository needs to be available for script/deployedContracts.json
# and script/compareLayouts.js.
- name: Checkout the repository
if: ${{ github.event.workflow_run.conclusion == 'success' }}
uses: actions/checkout@v4
- name: Restore the compiled layout files from the artifact
if: ${{ github.event.workflow_run.conclusion == 'success' }}
uses: dawidd6/action-download-artifact@v6
with:
name: storage-layouts-${{ github.event.workflow_run.head_commit.id }}
name: compiled-layouts-${{ github.event.workflow_run.head_commit.id }}
run_id: ${{ github.event.workflow_run.id }}
- name: Extract the restored layouts
- name: Restore the deployed layout files from the artifact
if: ${{ github.event.workflow_run.conclusion == 'success' }}
uses: actions/download-artifact@v4
with:
name: deployed-layouts-${{ github.event.workflow_run.head_commit.id }}
path: ./
- name: Extract the restored compiled layouts
if: ${{ github.event.workflow_run.conclusion == 'success' }}
run: unzip compiled-layouts.zip
- name: Extract the restored deployed layouts
if: ${{ github.event.workflow_run.conclusion == 'success' }}
run: unzip storage-layouts.zip
run: unzip deployed-layouts.zip
- name: Set up Node.js
if: ${{ github.event.workflow_run.conclusion == 'success' }}
uses: actions/setup-node@v4
Expand Down Expand Up @@ -206,6 +266,7 @@ jobs:
-f description="$description" \
-f target_url="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
- name: Set message again
# Even though the job is different, specify a unique ID.
id: set-message-again
env:
WORKFLOW_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
Expand Down
78 changes: 59 additions & 19 deletions .github/workflows/forge-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ jobs:
build:
runs-on: ubuntu-latest
needs: setup
# Takes about 3 minutes
timeout-minutes: 15
outputs:
# The cache-key only contains the version name. It is only used so that the name does not
# need to be repeated everywhere; instead setting the `foundry-version` above suffices.
Expand Down Expand Up @@ -57,6 +59,8 @@ jobs:
test:
runs-on: ubuntu-latest
needs: build
# No more than a few minutes
timeout-minutes: 5
steps:
- name: Restore cached Foundry toolchain
uses: actions/cache/restore@v3
Expand Down Expand Up @@ -84,6 +88,8 @@ jobs:
format:
runs-on: ubuntu-latest
needs: build
# No more than a few minutes
timeout-minutes: 5
steps:
- name: Restore cached Foundry toolchain
uses: actions/cache/restore@v3
Expand All @@ -106,9 +112,11 @@ jobs:
- name: Check formatting
run: forge fmt --check

extract-storage-layouts:
extract-base-storage-layout-exocore-gateway:
runs-on: ubuntu-latest
needs: build
# A few minutes
timeout-minutes: 10
steps:
- name: Restore cached Foundry toolchain
uses: actions/cache/restore@v3
Expand All @@ -131,14 +139,30 @@ jobs:
# cache them.
run: |
forge inspect src/core/ExocoreGateway.sol:ExocoreGateway storage-layout > ExocoreGateway.base.json
- name: Copy base branch layout file
run: cp ExocoreGateway.base.json /tmp/
# Now we can generate the layout for the PR level.
- name: Checkout back to PR
uses: actions/checkout@v4
- name: Upload storage layout file as an artifact
uses: actions/upload-artifact@v4
with:
path: ExocoreGateway.base.json
name: compiled-layout-ExocoreGateway-base-${{ github.event.pull_request.base.sha || github.event.after || github.sha }}

extract-storage-layouts:
runs-on: ubuntu-latest
needs: build
strategy:
matrix:
contract: [Bootstrap, ClientChainGateway, RewardVault, Vault, ExocoreGateway, ExoCapsule]
# A few minutes
timeout-minutes: 10
steps:
- name: Restore cached Foundry toolchain
uses: actions/cache/restore@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
# Restoring these will help make `forge inspect` faster.
path: ${{ needs.build.outputs.installation-dir }}
key: ${{ needs.build.outputs.cache-key }}
- name: Add Foundry to PATH
run: echo "${{ needs.build.outputs.installation-dir }}" >> "$GITHUB_PATH"
- name: Checkout repository
uses: actions/checkout@v4
- name: Restore build artifacts
uses: actions/cache/restore@v3
with:
Expand All @@ -148,17 +172,33 @@ jobs:
./cache
./broadcast
key: build-${{ github.event.pull_request.head.sha || github.event.after || github.sha }}
- name: Generate storage layout files for the PR
- name: Generate storage layout file for ${{ matrix.contract }}
run: |
for file in Bootstrap ClientChainGateway RewardVault Vault ExocoreGateway ExoCapsule; do
forge inspect src/core/${file}.sol:${file} storage-layout > ${file}.compiled.json;
done
- name: Copy back base branch layout file
run: cp /tmp/ExocoreGateway.base.json ./ExocoreGateway.base.json
- name: Zip storage layout files
run: zip storage-layouts.zip ./*.compiled.json ./ExocoreGateway.base.json
- name: Upload storage layout files as an artifact
forge inspect src/core/${{ matrix.contract }}.sol:${{ matrix.contract }} storage-layout > ${{ matrix.contract }}.compiled.json;
- name: Upload storage layout file as an artifact
uses: actions/upload-artifact@v4
with:
path: ${{ matrix.contract }}.compiled.json
name: compiled-layout-${{ matrix.contract}}-${{ github.event.pull_request.head.sha || github.event.after || github.sha }}

combine-storage-layouts:
runs-on: ubuntu-latest
needs:
- extract-base-storage-layout-exocore-gateway
- extract-storage-layouts
# A few minutes
timeout-minutes: 10
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
# No name means all artifacts are downloaded within their respective subfolders
# inside the provided path.
with:
path: combined
- name: Zip up the compiled layouts
run: zip -j compiled-layouts.zip combined/*/*.json
- name: Upload the compiled layouts file as an artifact
uses: actions/upload-artifact@v4
with:
path: storage-layouts.zip
name: storage-layouts-${{ github.event.pull_request.head.sha || github.event.after || github.sha }}
path: compiled-layouts.zip
name: compiled-layouts-${{ github.event.pull_request.head.sha || github.event.after || github.sha }}
6 changes: 4 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ jobs:
lint:
strategy:
fail-fast: true
# No more than a few minutes
timeout-minutes: 5

runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: '22'
node-version: '18' # Latest LTS

- name: Clear npm cache
run: npm cache clean --force
Expand Down
Loading

0 comments on commit fc7c643

Please sign in to comment.