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
10 changes: 6 additions & 4 deletions .github/scripts/check-diff-changeset.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#!/bin/bash
# Analyzes a diff between two directories and validates changeset requirements
# Usage: check-diff-changeset.sh <analysis-type> <base-dir> <head-dir>
# Usage: check-diff-changeset.sh <analysis-type> <base-dir> <head-dir> <base-ref>
# analysis-type: bytecode | storage
# base-ref: git ref to compare changesets against (e.g., commit SHA)
#
# For bytecode: any change requires patch+
# For storage: additions require minor+, removals require major
Expand All @@ -11,9 +12,10 @@ set -euo pipefail
ANALYSIS_TYPE=${1:-}
BASE_DIR=${2:-}
HEAD_DIR=${3:-}
BASE_REF=${4:-}

if [ -z "$ANALYSIS_TYPE" ] || [ -z "$BASE_DIR" ] || [ -z "$HEAD_DIR" ]; then
echo "Usage: check-diff-changeset.sh <bytecode|storage> <base-dir> <head-dir>"
if [ -z "$ANALYSIS_TYPE" ] || [ -z "$BASE_DIR" ] || [ -z "$HEAD_DIR" ] || [ -z "$BASE_REF" ]; then
echo "Usage: check-diff-changeset.sh <bytecode|storage> <base-dir> <head-dir> <base-ref>"
exit 1
fi

Expand Down Expand Up @@ -91,7 +93,7 @@ echo "$CHANGE_DESC detected."
echo ""

# Check for adequate changeset
if "$SCRIPT_DIR/check-solidity-changeset.sh" "$REQUIRED_LEVEL"; then
if "$SCRIPT_DIR/check-solidity-changeset.sh" "$REQUIRED_LEVEL" "$BASE_REF"; then
echo ""
echo "$CHANGE_DESC are permitted with the existing changeset."
exit 0
Expand Down
51 changes: 37 additions & 14 deletions .github/scripts/check-solidity-changeset.sh
Original file line number Diff line number Diff line change
@@ -1,36 +1,59 @@
#!/bin/bash
# Checks if @hyperlane-xyz/core has a changeset at or above the required level
# Usage: check-solidity-changeset.sh <required-level>
# Usage: check-solidity-changeset.sh <required-level> <base-ref>
# Levels: patch < minor < major
# Exit 0 if adequate changeset exists, exit 1 otherwise
#
# Note: This parses .changeset/*.md files directly instead of using the changeset CLI
# because the CLI requires git history (merge-base) which fails in shallow clones.
# See: https://github.com/changesets/changesets/issues/700
#
# Only changesets added since base-ref are checked, ensuring we validate
# changesets introduced by the current PR, not pre-existing ones.

set -euo pipefail

REQUIRED_LEVEL=${1:-}
BASE_REF=${2:-}
PACKAGE="@hyperlane-xyz/core"

if [ -z "$REQUIRED_LEVEL" ]; then
echo "Usage: check-solidity-changeset.sh <patch|minor|major>"
if [ -z "$REQUIRED_LEVEL" ] || [ -z "$BASE_REF" ]; then
echo "Usage: check-solidity-changeset.sh <patch|minor|major> <base-ref>"
exit 1
fi

# Get changeset status as JSON
# Note: changeset status --output requires a path relative to repo root
STATUS_FILE=".changeset-status-$$.json"
trap "rm -f $STATUS_FILE" EXIT
# changeset status exits non-zero when there are pending changesets, so ignore exit code
pnpm changeset status --output "$STATUS_FILE" 2>/dev/null || true

# Extract bump type for the package (only if it has explicit changesets, not transitive)
FOUND_LEVEL=$(jq -r --arg pkg "$PACKAGE" '.releases[] | select(.name == $pkg and (.changesets | length > 0)) | .type' "$STATUS_FILE")

# Map levels to numbers
# Map levels to numbers for comparison
level_to_num() {
case "$1" in
patch) echo 1 ;; minor) echo 2 ;; major) echo 3 ;; *) echo 0 ;;
esac
}

# Get only newly added changeset files compared to base, then cat their contents
NEW_CHANGESETS=$(git diff --name-only --diff-filter=A "$BASE_REF" -- '.changeset/*.md' 2>/dev/null || true)
if [ -z "$NEW_CHANGESETS" ]; then
echo "No new changesets found in this PR."
echo "Run 'pnpm changeset' and select '$PACKAGE' with a '$REQUIRED_LEVEL' (or higher) bump."
exit 1
fi

# Read content of new changeset files
CHANGESET_CONTENT=$(echo "$NEW_CHANGESETS" | xargs cat 2>/dev/null || true)

# Search for the package and extract bump level
# Format in changeset files: '@hyperlane-xyz/core': minor
FOUND_LEVEL=""
if echo "$CHANGESET_CONTENT" | grep -q "$PACKAGE"; then
# Found the package, extract the level (major > minor > patch)
if echo "$CHANGESET_CONTENT" | grep "$PACKAGE" | grep -q "major"; then
FOUND_LEVEL="major"
elif echo "$CHANGESET_CONTENT" | grep "$PACKAGE" | grep -q "minor"; then
FOUND_LEVEL="minor"
elif echo "$CHANGESET_CONTENT" | grep "$PACKAGE" | grep -q "patch"; then
FOUND_LEVEL="patch"
fi
fi

REQUIRED_NUM=$(level_to_num "$REQUIRED_LEVEL")
FOUND_NUM=$(level_to_num "$FOUND_LEVEL")

Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/bytecode-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,6 @@ jobs:

# Compare outputs
- name: Compare outputs
run: .github/scripts/check-diff-changeset.sh bytecode solidity/base-bytecode solidity/HEAD-bytecode
env:
BASE_REF: ${{ github.event.inputs.base || github.event.pull_request.base.sha }}
run: .github/scripts/check-diff-changeset.sh bytecode solidity/base-bytecode solidity/HEAD-bytecode "$BASE_REF"
6 changes: 4 additions & 2 deletions .github/workflows/interface-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ jobs:

# Compare outputs and check for appropriate changeset
- name: Compare outputs
env:
BASE_REF: ${{ github.event.inputs.base || github.event.pull_request.base.sha }}
run: |
set +e
pnpm -C solidity interface test-interface base-interface HEAD-interface
Expand All @@ -76,7 +78,7 @@ jobs:
elif [ "$EXIT_CODE" -eq 1 ]; then
# Removals detected - require major changeset
echo ""
if .github/scripts/check-solidity-changeset.sh major; then
if .github/scripts/check-solidity-changeset.sh major "$BASE_REF"; then
echo ""
echo "Interface removals are permitted with the existing changeset."
exit 0
Expand All @@ -88,7 +90,7 @@ jobs:
elif [ "$EXIT_CODE" -eq 2 ]; then
# Additions only - require minor changeset
echo ""
if .github/scripts/check-solidity-changeset.sh minor; then
if .github/scripts/check-solidity-changeset.sh minor "$BASE_REF"; then
echo ""
echo "Interface additions are permitted with the existing changeset."
exit 0
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/storage-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,6 @@ jobs:

# Compare outputs
- name: Compare outputs
run: .github/scripts/check-diff-changeset.sh storage solidity/base-storage solidity/HEAD-storage
env:
BASE_REF: ${{ github.event.inputs.base || github.event.pull_request.base.sha }}
run: .github/scripts/check-diff-changeset.sh storage solidity/base-storage solidity/HEAD-storage "$BASE_REF"
1 change: 1 addition & 0 deletions solidity/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ ignored_warnings_from = ['lib', 'test', 'contracts/test']
verbosity = 4
# disable metadata for bytecode comparison
cbor_metadata = false
bytecode_hash = "none"

[rpc_endpoints]
mainnet = "${RPC_URL_MAINNET}"
Expand Down
Loading