If it's boring - automate it. Release notes are boring.

Whenever you ship a new release you probably need a release note, a report listing the new version number, fixed issues, new features…

Why write all that manually? By building up your traces and recording your trails as you work, you can pull all this information out of your backend automatically.

You’ve written your last release note. From here on out it’s release notes as code.

Test data as code

Management and maintenance of your test data is considered part of your Quality Assurance strategy. Your test data is versioned and stored as an artifact.

This implies that you separate your test data from the actual tests, which in turn comes with the benefit of easily running test suites with different, versioned data sets.

Test suites becomes self-contained, each with their own easy reproducible setup and tear-down steps, something that will later enable you to run your test suites independently of each other - maybe even selected on output from previous verification steps in your pipeline.

Your software is more than just a number

Versioning schemes are a powerful tool.

They give you a quick and accurate reference to when, where and by whom something was made, what it’s compatible with, etc.
It is the name of your release, the identifier of your component, the passport of your product.

Implement a well-defined versioning scheme for your components and releases.

Get your dependencies straight

All software has dependencies; You may be using third party technology or you have a lot of individually released microservices, frameworks or libraries in your system architecture.

Make sure there are no moving targets and don’t rely on someone else’s master, latest or stable release. Cache everything you need in your own registry.

Optimize your link processes to use cached dependencies when available, optimize your compile processes to feed the registry when new versions are created, so others can benefit from them.

Don't let infrastructure be the bottleneck

Both successful deployment and functional testing are often considered part of the definition of done.

When we´re building continuous delivery pipelines it’s because we want our developers to have access to, and to execute, the full definition of done.

Use simulators, emulators, containers and VMs to verify your definition of done and ensure stable releases. The closer to production your testing environment, the more confidence you can have in your changes.

Size matters - small is beautiful

Assignments should be prepared for working before they qualify as actual tasks. The goal of a task must be known to the person who is implementing it.

If a task is ambiguous it can not be estimated, and if it can not be estimated, it can not be prioritized.

If a task doesn’t have a clear definition of done, then it should be time-boxed.