Skip to main content
This guide covers the release flow, branching strategy, and migration processes for ENS contracts.

Release Flow Overview

ENS contracts follow a structured release process with multiple branches and environments:
  • Feature Branches - Development of new features
  • Staging Branch - Pre-production testing environment
  • Main Branch - Production-deployed code

Branch Strategy

Branch Hierarchy

Branch Rules

  • staging and main should start in sync
  • Only code intended for production can merge to staging
  • All code on staging and main should be deployed to testnet and mainnet respectively
  • Feature branches must be kept in sync with staging
  • Deployed code should always match source code in mainnet releases

Standard Release Flow

1

Create feature branch from staging

Start development from the staging branch:
git checkout staging
git pull origin staging
git checkout -b feature/my-new-feature
2

Make code updates

Implement your changes, ensuring comprehensive tests:
# Make your changes
# Write tests
bun run test
3

Sync with staging

Keep your feature branch up to date:
git checkout staging
git pull origin staging
git checkout feature/my-new-feature
git merge staging
4

Create Release Candidate

When ready for review, create a Release Candidate GitHub release:
# Tag format: v1.2.3-RC0
git tag v1.2.3-RC0
git push origin v1.2.3-RC0
This tagged commit is now subject to the bug bounty program.
5

Audit if necessary

Have the Release Candidate audited for security:
  • Engage security auditors
  • Review findings
  • Create new RC if changes needed: v1.2.3-RC1, v1.2.3-RC2, etc.
6

Deploy to testnet

Deploy the audited version to testnet:
bun hh --network sepolia deploy
Open a PR to merge deployment artifacts into the feature branch, then create a testnet release: v1.2.3-testnet
7

Review and merge to staging

After deployment PR is approved:
git checkout staging
git merge feature/my-new-feature
git push origin staging
You MUST merge the feature branch into staging after testnet deployment.
8

Iterate if needed

If further changes are required:
  • Make changes on existing feature branch (if in sync)
  • OR create new feature branch
  • Follow steps 1-7 again
9

Deploy to mainnet

Deploy from staging to Ethereum mainnet:
bun hh --network mainnet deploy
Create a production release from the commit with deployment artifacts: v1.2.3
10

Merge to main

Open a PR to merge into main:
# After review and approval
git checkout main
git merge staging
git push origin main

Cherry-picked Release Flow

For isolated changes that need to be released independently:
This approach should be used sparingly. Ideally, always release from staging.
1

Create branch from mainnet

git checkout main
git checkout -b hotfix/critical-fix
2

Cherry-pick from staging

git cherry-pick <commit-hash-from-staging>
3

Deploy to mainnet

bun hh --network mainnet deploy
Tag the commit with deployment artifacts and create a release.
4

Merge into main

git checkout main
git merge hotfix/critical-fix
git push origin main

Emergency Release Process

For critical security fixes or urgent issues:
1

Branch from main and fix

git checkout main
git checkout -b emergency/security-fix
# Make critical fixes
Optionally deploy to testnet, but can skip if urgent.
2

Deploy to mainnet

bun hh --network mainnet deploy
3

Merge back immediately

Merge changes into both main and staging immediately after deploy:
git checkout main
git merge emergency/security-fix
git push origin main

git checkout staging
git merge emergency/security-fix
git push origin staging
4

Create GitHub releases

If testnet deployment was skipped, deploy to testnet now and create appropriate releases.

Version Numbering

ENS contracts follow semantic versioning:

Version Format

  • Major.Minor.Patch (e.g., 1.6.2)
  • Release Candidates - v1.2.3-RC0, v1.2.3-RC1
  • Testnet Releases - v1.2.3-testnet
  • Production Releases - v1.2.3

When to Bump Versions

  • Major - Breaking changes, major new features
  • Minor - New features, non-breaking changes
  • Patch - Bug fixes, minor improvements

Migration Between Versions

Contract Upgrades

For contracts with upgrade mechanisms:
// Example: Setting upgrade contract for NameWrapper
await nameWrapper.setUpgradeContract(newWrapperAddress)

User-Initiated Migrations

Some migrations require users to take action:
  1. NameWrapper Upgrades - See Wrapper Upgrade Guide
  2. Resolver Updates - Users update their resolver addresses
  3. Controller Migrations - Switch to new registrar controllers

Deployment Artifacts Management

Archiving Old Deployments

Old deployment artifacts are archived:
# Check for unarchived deployments
bun run hh archive-scan
Archived deployments are stored in ./deployments/archive.

Deployment Version Bumping

When preparing new deployments:
  1. Bump the deploy script version number
  2. This ensures the script runs for each network
  3. Prevents accidental re-deployment of unchanged contracts

Testing Migrations

Fork Testing

Test migrations on a fork before production:
# Start Anvil fork
anvil --fork-url https://mainnet.infura.io/v3/YOUR_KEY

# Test migration
bun run test:deploy

Testnet Validation

Always validate migrations on testnet:
1

Deploy to testnet

bun hh --network sepolia deploy
2

Test migration functionality

TEST_REMOTE=1 bun run test:remote
3

Verify contract state

Check that migrated state is correct using block explorer or scripts.

Release Notes

Each release should include:
  • Summary of changes - What was added, changed, or fixed
  • Migration instructions - If user action is required
  • Contract addresses - New deployment addresses
  • Breaking changes - Any incompatible changes
  • Audit information - Link to audit reports if applicable

Release Note Template

## v1.2.3

### Summary
- Added new feature X
- Fixed bug in contract Y
- Updated dependency Z

### Migration
- Users must update their resolver to the new address
- No action required for .eth name owners

### Deployments
- Mainnet: 0x...
- Sepolia: 0x...

### Audit
- Audited by [Auditor Name]
- Report: [link]

Best Practices

Feature branches can be long-lived, so regularly sync with staging:
git checkout staging && git pull
git checkout feature/my-feature
git merge staging
Coordinate with team to minimize merge conflicts by working on different files when possible.
  • Run full test suite
  • Deploy to testnet
  • Test all migration paths
  • Verify with independent review
  • Update CHANGELOG
  • Write clear commit messages
  • Create comprehensive release notes
  • Update documentation

Deployment Guide

Learn about deployment procedures

Wrapper Upgrade

NameWrapper upgrade process

Audits

Security audit information

Testing

Testing before release

Build docs developers (and LLMs) love