Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
181 changes: 181 additions & 0 deletions .github/workflows/gas.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
name: Gas Budget Regression

# ---------------------------------------------------------------------------
# Triggers
# ---------------------------------------------------------------------------
on:
pull_request:
branches: [main, master, develop]
# Re-run when the override label is added/removed so the status updates
# without needing a new commit.
types: [opened, synchronize, reopened, labeled, unlabeled]
push:
branches: [main, master, develop]

# ---------------------------------------------------------------------------
# Permissions
# ---------------------------------------------------------------------------
permissions:
contents: read # checkout
pull-requests: write # post the PR comment

jobs:
gas-regression:
name: Gas budget regression (≤5% tolerance)
runs-on: ubuntu-latest

steps:
# -----------------------------------------------------------------------
# 1. Source
# -----------------------------------------------------------------------
- name: Checkout repository
uses: actions/checkout@v4

# -----------------------------------------------------------------------
# 2. Toolchain
# -----------------------------------------------------------------------
- name: Install Rust (stable)
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy

# -----------------------------------------------------------------------
# 3. Cache
# -----------------------------------------------------------------------
- name: Cache cargo registry and build artifacts
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-gas-${{ hashFiles('**/Cargo.lock', '**/Cargo.toml') }}
restore-keys: |
${{ runner.os }}-cargo-gas-
${{ runner.os }}-cargo-

# -----------------------------------------------------------------------
# 4. Dependencies
# -----------------------------------------------------------------------
- name: Install jq
run: sudo apt-get install -y jq

# -----------------------------------------------------------------------
# 5. Check for override label
# When a PR carries the "gas-override" label the regression gate is
# skipped and a notice is posted instead. The label MUST be removed
# before merging.
# -----------------------------------------------------------------------
- name: Check for gas-override label
id: override_check
env:
PR_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }}
run: |
if echo "$PR_LABELS" | jq -e 'map(select(. == "gas-override")) | length > 0' > /dev/null 2>&1; then
echo "override=true" >> "$GITHUB_OUTPUT"
else
echo "override=false" >> "$GITHUB_OUTPUT"
fi

# -----------------------------------------------------------------------
# 6. Override path — post notice and skip gate
# -----------------------------------------------------------------------
- name: Post override notice
if: steps.override_check.outputs.override == 'true' && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const body = [
"## ⚠️ Gas budget gate skipped",
"",
"This PR carries the **`gas-override`** label — the ≤5% regression check has been bypassed.",
"",
"> **Action required:** Remove the label before merging and ensure `contracts/.gas-baseline.json` is updated to reflect the new measurements.",
].join("\n");

await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});

- name: Skip regression (override active)
if: steps.override_check.outputs.override == 'true'
run: |
echo "gas-override label detected — skipping regression gate."
exit 0

# -----------------------------------------------------------------------
# 7. Build workspace (needed before tests emit measurements)
# -----------------------------------------------------------------------
- name: Build workspace
run: cargo build --workspace

# -----------------------------------------------------------------------
# 8. Run gas regression script
# -----------------------------------------------------------------------
- name: Run gas regression
id: regression
run: |
chmod +x scripts/gas-regression.sh
set +e
./scripts/gas-regression.sh --threshold 5
echo "exit_code=$?" >> "$GITHUB_OUTPUT"
set -e

# -----------------------------------------------------------------------
# 9. Post Markdown report as a PR comment
# -----------------------------------------------------------------------
- name: Post gas report to PR
if: github.event_name == 'pull_request' && always()
uses: actions/github-script@v7
with:
script: |
const fs = require("fs");
const reportPath = "target/gas-report.md";

let body;
try {
body = fs.readFileSync(reportPath, "utf8");
} catch {
body = "⚠️ Gas report was not generated (see workflow logs for details).";
}

// Prepend a header indicating pass/fail so reviewers see it instantly.
const exitCode = "${{ steps.regression.outputs.exit_code }}";
const status = exitCode === "0"
? "✅ All entrypoints within the 5% budget threshold."
: "❌ One or more entrypoints exceeded the 5% budget threshold. See table below.";

const comment = `${status}\n\n${body}`;

await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment,
});

# -----------------------------------------------------------------------
# 10. Upload report artifact (available in push context too)
# -----------------------------------------------------------------------
- name: Upload gas report
if: always()
uses: actions/upload-artifact@v4
with:
name: gas-regression-report
path: target/gas-report.md
if-no-files-found: warn

# -----------------------------------------------------------------------
# 11. Fail the job if regression was detected
# -----------------------------------------------------------------------
- name: Fail on regression
if: steps.regression.outputs.exit_code != '0'
run: |
echo "Gas budget regression detected. See the report above."
echo "To update the baseline intentionally, run:"
echo " ./scripts/gas-regression.sh --update-baseline"
echo "Then commit contracts/.gas-baseline.json."
exit 1
Loading
Loading