- Recognize that a single "semver" version isn't enough, the client needs to separately semantically track all the different "contracts" it adheres to, such as:
- The internal DB format (ideally this stays 1.x!)
- The JSONRPC interface (decide what major/minor means here)
- The hardfork / network version
Ideally these versions would be easily inspectable via --version or --help and each one would have its own changelog in a release.
- Make sure client teams aren't overcommitting features to the next hardfork
- Make sure clients are more or less ready before choosing a hardfork date.
- Commit to releasing a feature-complete client weeks before the hardfork instead of days.
- Remember that for node providers and their customers testnets ARE production.
- Make it clear why a release was necessary and what are the advantages of upgrading to it.
- Make it clear when a point release contains security related updates, even if the exact nature can't be disclosed.
- Have some sort of deprecation policy/timeline and stick to it.
- Don't "kitch sink" hardfork releases. Save the big updates for after the hardfork instead of forcing users to adopt your changes on a set schedule.
- Feature flags / opt-in changes are ideal.
- Continuously (re)-sync to mainnet and run some nodes yourselves; fully test new releases before announcing them.