Skip to content

Conversation

@hudsonhrh
Copy link
Contributor

@hudsonhrh hudsonhrh commented Dec 4, 2025

Summary

Major improvements to Etherform CI/CD workflows including deployment profiles, GitHub Environments support, and robust contract verification.

Features

Deployment Profiles (deployment-foundry-profile)

  • Specify a Foundry profile for deployments while keeping CI tests on default profile
  • Useful when tests fail with high optimizer settings but production needs optimization
  • Profile applies to deployment, upgrade safety, verification, and flattening steps
  • Profile validation catches undefined profiles early with helpful error messages

GitHub Environments Support

  • Deploy jobs now use environment: from network config for per-network secrets
  • Restructured workflows with two-job pattern (read-config → deploy) to support environment resolution
  • Secrets (PRIVATE_KEY, RPC_URL) resolve from GitHub Environments based on "environment" field in deploy-networks.json

Robust Contract Verification

  • Optional verification: Skip if blockscout_url is omitted/empty in network config
  • Proper failure handling: Verification step fails when all retries are exhausted
  • Constructor args from broadcast: Extract actual constructor args from broadcast artifacts instead of guessing
  • Library-linked contracts: Works with contracts that use external libraries (fixes --guess-constructor-args failures)

Commits

Commit Description
3ad9cf8 Add all-in-one _foundry-cicd.yml reusable workflow
3c3048e Add deployment-foundry-profile input to all workflows
58ddecd Document deployment profiles in README
77f745e Make Blockscout verification optional
9d2381f Fix verification to actually fail when retries exhausted
7b38f11 Pass RPC_URL to verification (required for --guess-constructor-args)
b9a5466 Add GitHub Environments support for per-network secrets
f5b700a Use broadcast artifacts for constructor args in verification
e82dcdb Fix jq parse errors with robust arg handling

Usage

jobs:
  deploy:
    uses: BreadchainCoop/etherform/.github/workflows/_foundry-cicd.yml@main
    with:
      deployment-foundry-profile: 'production'
      deploy-on-pr: true
    secrets:
      PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
      RPC_URL: ${{ secrets.RPC_URL }}

Network config with environments:

{
  "testnets": [{
    "name": "sepolia",
    "blockscout_url": "https://eth-sepolia.blockscout.com",
    "environment": "testnet-sepolia"
  }],
  "mainnets": [{
    "name": "ethereum",
    "blockscout_url": "https://eth.blockscout.com",
    "environment": "production-ethereum"
  }]
}

closes #8, closes #7, closes #4

Tested with integration wit this repo https://github.com/PerpetualOrganizationArchitect/POP/actions/runs/19974105263/job/57286120003?pr=54
🤖 Generated with Claude Code

Add ability to specify a Foundry profile when integrating Etherform workflows.
The profile applies to deployment, upgrade safety, and verification steps,
while CI tests run with the default profile (optimizer off) to avoid test failures.

Profile validation catches undefined profiles early with helpful error messages.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
@hudsonhrh hudsonhrh force-pushed the foundry-profile-input branch from c5a35b6 to 3c3048e Compare December 4, 2025 19:35
hudsonhrh and others added 7 commits December 4, 2025 14:50
🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Verification is now skipped if blockscout_url is not set in network config.
This allows deploying to networks without Blockscout support.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Uses process substitution instead of pipe to properly track failures
across loop iterations. The step now exits with error code 1 when any
contract fails verification after 3 attempts.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The --guess-constructor-args flag requires an RPC URL to fetch
deployed bytecode and determine constructor arguments.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Restructure _deploy-testnet.yml into two jobs (read-config + deploy)
  so environment: can reference the config output
- Add read-testnet-config and read-mainnet-config jobs to _foundry-cicd.yml
- Deploy jobs now use environment: from network config for secret resolution
- Secrets (PRIVATE_KEY, RPC_URL) now resolve from GitHub Environments
  based on the "environment" field in deploy-networks.json

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Replace --guess-constructor-args with explicit constructor args
extracted from broadcast file. This fixes verification for contracts
that use external libraries.

Changes:
- Extract .arguments from broadcast transactions
- Get constructor signature from contract ABI via forge inspect
- Encode args with cast abi-encode
- Pass encoded args to forge verify-contract --constructor-args
- Remove --rpc-url (only needed for guessing)
- Gracefully handle contracts without constructor args

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Fix jq parse errors when processing constructor arguments:
- Use jq -e to safely check if arguments array exists
- Validate ABI JSON before parsing
- Use mapfile to properly handle args with special characters
- Pass args as bash array to preserve quoting for cast abi-encode

This fixes "Invalid numeric literal" errors when arguments
contain hex addresses.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@hudsonhrh hudsonhrh changed the title feat: add foundry-profile input to workflows feat: Etherform workflow improvements Dec 5, 2025
hudsonhrh and others added 2 commits December 6, 2025 00:27
Convert multiline contract-paths input to properly formatted YAML list for dorny/paths-filter. This fixes the error: "can not read a block mapping entry; a multiline key may not be an implicit key"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@RonTuretzky
Copy link
Contributor

@hudsonhrh can you demonstarte this working with a pr to the foundry-counter-upgradeable repo and include it in here?

Copy link
Contributor

@RonTuretzky RonTuretzky left a comment

Choose a reason for hiding this comment

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

please rebase off of #13


# Extract and verify each deployed contract with retry logic
jq -c '.transactions[] | select(.transactionType == "CREATE")' "$BROADCAST_FILE" | while read -r tx; do
# Use process substitution to avoid subshell issues with variable tracking
Copy link
Contributor

Choose a reason for hiding this comment

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

what is this change? why is it necessary?


echo "Verifying $CONTRACT_NAME at $CONTRACT_ADDR..."

# Build constructor args if present
Copy link
Contributor

Choose a reason for hiding this comment

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

is this info not in the run-latest json?

jobs:
deploy-testnet:
name: Deploy to Testnet
read-config:
Copy link
Contributor

Choose a reason for hiding this comment

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

are we decoupling this so that it can be re-used for testnet/mainnet?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Blockscout verification url bad format check Blockscout verification optional Accept different profiles

3 participants