This document outlines essential procedures for repository maintenance, including PR management, branching strategies, and release processes that maintainers should follow to ensure code quality and stability.
Code reviewers are responsible for ensuring that PRs meet the following criteria before merging:
- Properly labeled according to our labeling conventions
- Well-formatted code adhering to our style guidelines
- Comprehensive test coverage including unit and integration tests
- Documentation updates where appropriate
- Security considerations addressed and potential vulnerabilities mitigated
For first-time external contributors, a maintainer must:
- Review the PR with additional scrutiny
- Verify the contributor has signed the CLA (Contributor License Agreement)
- Manually approve CI workflows to run
- Provide detailed feedback to help onboard the contributor
-
main
(default):- The canonical branch where all approved code changes are merged
- Must remain stable and suitable for internal/external testing
- All CI workflows must pass before and after every commit
- Security audits are performed against specific commits on this branch
-
release-dev/xxx
:- Used for large features requiring multiple commits that introduce breaking changes
- Examples:
release-dev/slashing-v1
,release-dev/rewards-v2
- Branch from
main
for isolated development - Must be regularly rebased against
main
to reduce merge conflicts - Merged back into
main
as a single logical unit when complete - No security audits are performed directly on these branches
We employ different merge strategies based on PR type:
Regular PRs include bug fixes, small features, or incremental updates where each PR represents an atomic change.
Merge Strategy: Always use Squash and Merge
- Combines all commits into a single, atomic unit
- Maintains a clean, linear history on the target branch
- Preserves PR number in commit message for traceability
- Example:
PR #123 -> [squash] -> main
When merging a complete release-dev
branch into main
after a major feature is completed.
Merge Strategy: Always use Merge Commit (no squash)
- Preserves the complete commit history of the feature branch
- Creates a merge commit that serves as a feature completion marker
- Simplifies cherry-picking specific changes for hotfixes
- Example:
release-dev/feature -> [merge commit] -> main
- Branch Hygiene: Delete branches after merging to avoid clutter
- CI Validation: Never merge code that fails CI checks
- Documentation: Update documentation alongside code changes
- Breaking Changes: Clearly document any breaking changes in PR descriptions
Before diving into maintenance details, it's important to understand our environment network structure.
Environment | Environment Network | Definition and Practices |
---|---|---|
mainnet | mainnet-ethereum | - Production environment on Ethereum mainnet - Single canonical mainnet instance in foreseeable future - External facing with highest security requirements |
testnet | testnet-holesky testnet-sepolia testnet-hoodi |
- Test environments on Ethereum testnets (holesky, sepolia, etc.) - Multiple testnet environments may exist simultaneously - External facing, long-lived environments for both internal and external developers - Used for integration testing, AVS onboarding, and community engagement |
preprod | preprod-holesky preprod-sepolia preprod-hoodi |
- Pre-production environments on Ethereum testnets - Multiple preprod environments may exist simultaneously - Internal facing for development team use - Used for feature verification before promoting to testnet - Provides safe environment for testing breaking changes |
For more details on our testing infrastructure strategy, see our blog post: The Future of EigenLayer Testing: New & Improved Testnets & Tooling Coming Soon
This section defines release tag semver where <semver>
= <major>.<minor>.<patch>
E.g.
- v1.1.0
- v1.1.1
<semver>
should follow best practices of semver definition
In observing semver, we define the following;
- A major upgrade
- An ideologically breaking upgrade, which may require re-learning parts of the system.
- “Upgrade Required” — Major upgrades are assumed to break all tooling, integrations, and downstream consumers unless otherwise stated.
- Major upgrades are announced ahead of time via blog posts, the ELIP process, and onchain via the Eigen timelock.
- example: slashing, which changes most of our codebase
- A minor upgrade
- A conceptually breaking upgrade, which require adapting break changes and APIs, upgrading tools, CLIs, or integrations with EigenLayer.
- “Upgrade carefully” — Minor upgrades are assumed not to break any tooling, CLIs, or interactions with EigenLayer unless otherwise stated in release notes.
- A patch upgrade
- A “silent” upgrade, which addresses a bug or inconsistency in the system, but does not change any interfaces.
- i.e. fixes reveal the need for a rounding fix in a contract. Notably abi and tooling remains stable across patches.
- “Upgrade suggested” — Patch upgrades may come with upgrades to tooling, CLIs, or other Eigen infrastructure. You are encouraged to read the patch notes and upgrade.
- A “silent” upgrade, which addresses a bug or inconsistency in the system, but does not change any interfaces.
All releases will be cut from main
the base branch, to ensure global consistency, clean legibility, and high code quality with no env-network specific code
Each env_network deployment will pick one release above.
During release, release manager can cherry pick to exclude certain commits, especially in case of a non-sequential feature deployment
In smart contracts, there is a common scenario for non sequential feature deployment due to Ethereum hardforks, whose time we cannot control.
E.g. say we have features A, B, and Ethereum hardfork X, where B is an upgrade to adapt to X. The deployment sequence for testnet is A, B, X. While that of mainnet has to be B, X, A, because 1/ we don’t control the time of X, 2/ B must happen before X, and 3/ A is not ready for mainnet yet which can’t be deployed before B
Concrete example just happened is A = slashing V1, B = prooftra, X = pectra
So our release branch and model must be flexible enough to solve it via cherry picking
- a release would upgrade versions for all code, even though there's no change to a file from last release
- a deployment would adopt a release as a whole, so all contracts would upgrade to that release, instead of "some file on release v1.3 and some on release v1.4"
- there's no phrasing of, for example, "all non-EigenPod contracts be on
v1.3.0
and EigenPods contract onv1.4.0
" - they would all be on v1.4.0, just the non-eigenpod contract are not changed at all from v1.3.0 - as implementation detail, we can skip upgrade the contracts that have not changed, but the codebase and releases are on new release version
- there's no phrasing of, for example, "all non-EigenPod contracts be on
- all changes have to be deployed to testnet first, before mainnet. No skipping from preprod to mainnet directly
Once release are created, corresponding release branches will live forever for future reference and NEVER be deleted.
Together with “Fork-based PR” defined in CONTRIBUTING.md, it means there are only 3 categories of branches in the repository:
main
: live forever, never delete- release-dev branches
release-dev/*
e: long living branch for a period of time but will be deleted once their commits are merged back tomain
- release branches
vx.y.z
: live forever, never delete after a release is officially create
Each release in testnet and mainnet must have corresponding release note, changelog, and announcement blog
- Changelog
- lives in the repo
/CHANGELOG
dir - exact commit history diff from last release
- See examples in Kubernetes https://github.com/kubernetes/kubernetes/tree/master/CHANGELOG
- lives in the repo
- Release note:
- lives in the repo as part of release description under “Releases”
- high level summary of key changes users need to be aware of
- See template below
- Owner: release manager and PM
- Release announcement blog
- published to blog.eigenlayer.xyz
- an announcement with polished language to introduce the release to users. It will include content in both release notes and changelog
- See examples in Golang https://tip.golang.org/doc/go1.24
- Owner: release manager and PM
Release Note must follow template:
<release-version>
🚀 New Features – Highlight major new functionality.
- ...
- ...
⛔ Breaking Changes – Call out backward-incompatible changes.
- ...
- ...
📌 Deprecations – Mention features that are being phased out.
- ...
- ...
🛠️ Security Fixes – Specify patched vulnerabilities.
- ...
- ...
🔧 Improvements – Enhancements to existing features.
- ...
- ...
🐛 Bug Fixes – List resolved issues.
- ...
- ...
When writing release notes and changelog entries, follow these best practices to ensure clarity, usefulness, and professionalism.
Required Best Practices
- Be Clear and Concise – Use simple, direct language. Avoid jargon unless necessary.
- Categorize Changes – Use standard sectioned template above.
- Provide Context – Briefly explain why the change was made, not just what changed.
- Use a Consistent Format – Follow a structured template for every release.
- Include Relevant Links – Link to issue trackers, PRs, or documentation for more details.
- Highlight User Impact – Mention how the update affects users and any required actions.
- Keep It Versioned – Use semantic versioning (e.g.,
v2.3.1
) and list versions in descending order. - Avoid Internal-Only Details – Don't include internal project discussions that aren’t relevant to users.
- Maintain a Single Source of Truth – Store changelogs in a
CHANGELOG.md
file or an equivalent documentation system.
We introduce a new critical role called release manager (RM)
Each release should have a primary RM and a secondary RM. RM is on rotating base, not necessarily always be the tech lead of the project, so we can amortize the cost and onboard all developers with same standards
Primary Release Manager is responsible for
- Managing the release-dev branch during development phase
- create it from
main
and eventually merge back tomain
- constantly rebasing to
main
to resolve conflict early, without required efforts from other developers working on the release-dev branch - holding high bar for quality:
- code quality
- PR templating
- test quality (e.g. no flaky or failed tests, keep test runtime under control)
- create it from
- Manage release branches and deployment
- create and manage corresponding release branches
Vx.y.z
- author and publish release notes and changelog
- author and publish release blog with PM and marketing team
- lead communication with marketing and BD team to inform stakerholders for preparation
- lead deployment to env network
- create and manage corresponding release branches
- Mentoring and knowledge sharing
- mentor and train secondary release manager, who will be the primary manager for next release
By following these maintenance procedures, we ensure a stable, secure, and well-documented codebase that meets the high standards required for EigenLayer's infrastructure.