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
23 changes: 23 additions & 0 deletions .github/workflows/shellcheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: ShellCheck

on:
push:
branches: [main]
paths:
- 'scripts/*.sh'
- '.github/workflows/shellcheck.yml'
pull_request:
branches: [main]
paths:
- 'scripts/*.sh'
- '.github/workflows/shellcheck.yml'

jobs:
shellcheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ludeeus/action-shellcheck@master
with:
scandir: './scripts'
format: gcc
8 changes: 8 additions & 0 deletions scripts/check_abi_snapshot_hygiene.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ REQUIRED_ABIS=(
abis/compliance.json
)

# Check if abis/ directory exists
if [ ! -d "$REPO_ROOT/abis" ]; then
echo "ERROR: abis/ directory is missing or misconfigured" >&2
echo "This may indicate a bad checkout or missing repository structure." >&2
echo "Restore the directory or clone the repository properly." >&2
exit 1
fi

missing=0
for abi_file in "${REQUIRED_ABIS[@]}"; do
if [ ! -f "$REPO_ROOT/$abi_file" ]; then
Expand Down
90 changes: 90 additions & 0 deletions scripts/generate_release_notes.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/usr/bin/env bash
# generate_release_notes.sh — draft CHANGELOG.md entries from merged PR titles.
#
# Queries merged PRs since the last tag and groups them by conventional-commit prefix.
# Outputs a markdown section formatted for Keep a Changelog.
#
# Usage:
# ./scripts/generate_release_notes.sh
#
# Environment variables (optional):
# GITHUB_TOKEN — GitHub personal access token for higher rate limits
set -euo pipefail

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

# Get the last tag or default to a reasonable starting point
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD~50")

# Query merged PRs since last tag using gh CLI
echo "Querying merged PRs since $LAST_TAG..."
MERGED_PRS=$(gh pr list \
--search "merged:>$(git log -1 --format=%ci "$LAST_TAG" | cut -d' ' -f1)" \
--state merged \
--limit 100 \
--json title,number,mergedAt \
--jq '.[] | "\(.number): \(.title)"' 2>/dev/null || echo "")

if [ -z "$MERGED_PRS" ]; then
echo "No merged PRs found since $LAST_TAG"
exit 0
fi

# Group by conventional-commit prefix
echo ""
echo "## Unreleased"
echo ""

declare -A sections
declare -a order=("feat" "fix" "perf" "docs" "style" "refactor" "test" "chore")

while IFS=: read -r number title; do
number=$(echo "$number" | xargs)
title=$(echo "$title" | xargs)

# Extract conventional-commit prefix
prefix=$(echo "$title" | sed -n 's/^\([a-z]*\).*/\1/p' || echo "chore")

if [ -z "$prefix" ]; then
prefix="chore"
fi

sections[$prefix]="${sections[$prefix]:-}- $title (#$number)
"
done <<< "$MERGED_PRS"

# Output grouped sections
for prefix in "${order[@]}"; do
if [ -n "${sections[$prefix]:-}" ]; then
case "$prefix" in
feat)
echo "### Added"
;;
fix)
echo "### Fixed"
;;
perf)
echo "### Performance"
;;
docs)
echo "### Documentation"
;;
style)
echo "### Changed"
;;
refactor)
echo "### Changed"
;;
test)
echo "### Testing"
;;
chore)
echo "### Maintenance"
;;
esac
echo ""
echo "${sections[$prefix]}"
fi
done

echo "Generated release notes. Edit CHANGELOG.md and adjust as needed."
69 changes: 58 additions & 11 deletions scripts/verify.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
# the locally built artifacts. Exits non-zero and prints a clear diff if any
# mismatch is detected.
#
# Usage:
# ./verify.sh [--output {text|json}]
#
# Required environment variables:
# SOROBAN_RPC_URL — Soroban RPC endpoint
# INVOICE_CONTRACT_ID — deployed invoice contract ID (C…)
Expand All @@ -18,6 +21,27 @@ set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

# Parse command-line arguments
OUTPUT_FORMAT="text"
while [[ $# -gt 0 ]]; do
case "$1" in
--output)
OUTPUT_FORMAT="$2"
shift 2
;;
*)
echo "Unknown option: $1" >&2
exit 1
;;
esac
done

# Validate output format
if [[ ! "$OUTPUT_FORMAT" =~ ^(text|json)$ ]]; then
echo "ERROR: --output must be 'text' or 'json'" >&2
exit 1
fi

# ── ABI metadata sanity check ─────────────────────────────────────────────────
echo "Checking ABI metadata…"
test -f "$ROOT_DIR/abis/invoice.json" || { echo "ERROR: abis/invoice.json missing"; exit 1; }
Expand Down Expand Up @@ -47,6 +71,7 @@ CONTRACTS_DIR="${CONTRACTS_DIR:-$ROOT_DIR/../COMEBACKHERE-contracts/target/wasm3

FAIL=0
MISMATCHES=()
CHECKS=() # For JSON output: array of check results

verify_contract() {
local name="$1"
Expand Down Expand Up @@ -93,13 +118,19 @@ print(hashlib.sha256(wasm_bytes).hexdigest())
fi

if [[ "$local_hash" == "$deployed_hash" ]]; then
echo " ✓ $name: hash match ($local_hash)"
if [[ "$OUTPUT_FORMAT" == "text" ]]; then
echo " ✓ $name: hash match ($local_hash)"
fi
CHECKS+=("{\"contract\":\"$name\",\"status\":\"pass\",\"local_hash\":\"$local_hash\",\"deployed_hash\":\"$deployed_hash\"}")
else
echo " ✗ $name: HASH MISMATCH" >&2
echo " local: $local_hash" >&2
echo " deployed: $deployed_hash" >&2
if [[ "$OUTPUT_FORMAT" == "text" ]]; then
echo " ✗ $name: HASH MISMATCH" >&2
echo " local: $local_hash" >&2
echo " deployed: $deployed_hash" >&2
fi
FAIL=1
MISMATCHES+=("$name")
CHECKS+=("{\"contract\":\"$name\",\"status\":\"fail\",\"local_hash\":\"$local_hash\",\"deployed_hash\":\"$deployed_hash\"}")
fi
}

Expand All @@ -118,13 +149,29 @@ verify_contract "compliance" \
"$COMPLIANCE_CONTRACT_ID" \
"$CONTRACTS_DIR/comebackhere_compliance.wasm"

if [[ "$OUTPUT_FORMAT" == "json" ]]; then
# Output JSON result
echo "{"
echo " \"status\": \"$([ $FAIL -eq 0 ] && echo 'pass' || echo 'fail')\","
echo " \"checks\": ["
for i in "${!CHECKS[@]}"; do
echo " ${CHECKS[$i]}$([ $i -lt $((${#CHECKS[@]} - 1)) ] && echo ',' || echo '')"
done
echo " ]"
echo "}"
else
# Text output
if (( FAIL )); then
echo ""
echo "VERIFICATION FAILED — the following contracts have WASM hash mismatches:" >&2
printf ' - %s\n' "${MISMATCHES[@]}" >&2
echo "Ensure you are comparing the correct build artifacts to the correct deployment." >&2
else
echo ""
echo "All WASM hashes verified successfully."
fi
fi

if (( FAIL )); then
echo ""
echo "VERIFICATION FAILED — the following contracts have WASM hash mismatches:" >&2
printf ' - %s\n' "${MISMATCHES[@]}" >&2
echo "Ensure you are comparing the correct build artifacts to the correct deployment." >&2
exit 1
fi

echo ""
echo "All WASM hashes verified successfully."