Project: Operator Framework (App Definition and Development / Application Definition & Image Build)
File: automating-releases.md

title: automating-releases authors: @estroz reviewers: @jmrodri @joelanford @theishah approvers: TBD creation-date: 2020-09-19 last-updated: 2020-10-01 status: implementable \[ \] Enhancement is `implementable` \[ \] Design details are appropriately documented from clear requirements \[ \] Test plan is defined \[ \] Graduation criteria for dev preview, tech preview, GA \ [RESOLVED] We currently build images for an architecture on machines of that architecture. This is not a requirement for Go binaries themselves, but might be for Ansible/Helm dependencies since they install binaries for particular architectures. What are these dependencies and can they be installed in a container during image build? This proposal encompasses all binaries/images currently built for an operator-sdk release. Once Ansible- and Helm-related code are split into their respective repos, will this release process follow? , or use goreleaser's ? This proposal outlines an automated release pipeline for the operator-sdk repository that includes both binary and image builds. The release tool will replace the existing combination of the release script `release.sh`, manual `git` steps, and manual release publishing with a one "click" solution. To users, no changes will occur since the release artifacts are not changing. To developers, the release process will become much simpler, hopefully to the point where a new contributor can run the release with little process knowledge. Releasing the operator-sdk repo currently requires several steps that are mostly manual, with some automation around building binaries for all architectures supported. Tools like can automate this process entirely by tagging code, and building and publishing binaries and images with one "click". Remove all manual steps from the release process Centralize release configuration One-click releasing Change the content or constituency of output release artifacts in any way Change the testing process in any way Change our CI provider As a contributor I want to run the release in as few operations as possible. This feature will enable new contributors to release the repo easily, instead of relying on a long onboarding document and the expertise of a few contributors. As a contributor I want to easily improve the release configuration whenever necessary, which includes adding new release architectures. Configuration should be documented, comprehensible, and centralized. The release tool satisfies the above goals and user stories: Release from semver code tags Encapsulates most release process complexity in one command Builds Applies to `operator-sdk`, `ansible-operator`, and `helm-operator` Publishes GitHub releases Centralized configuration and a well-documented `goreleaser` configuration is CI-agnostic, so if we choose to switch CI systems in the future we can bring our configuration with us verbatim. Additionally it supports generating release notes from a ; we currently use a custom changelog generator which we can continue using. These new release steps delegate releasing completely to CI infrastructure. Commit to master: Regenerated `CHANGELOG.md` Removed fragments in `changelog/` New migration guide `website/content/en/docs/upgrading-sdk-version/vX.Y.Z.md` Updated version in `website/content/en/docs/installation/install-operator-sdk.md` `git tag

&& git push --tags` CI runs tests on tag CI runs `make release TAG=<tag>` Currently the `make release` only builds binaries; this new rule will set up and run `goreleaser` to: Build multi-arch binaries and images Publish a Github release with binaries and signed SHA256 hashes for each binary We'll need to create a PGP key for CI Push images to the remote registry. Building `operator-sdk`, `ansible-operator`, and `helm-operator` binaries is straightforward because they can be cross-compiled locally under their own task. These binaries will be published as they are now. `goreleaser` does not yet have support for multi-arch image builds. Instead, the release config will have a post-build hook for each task in `builds` that runs an image build script leveraging , a Docker plugin that can build an image for each arch of a multi-arch manifest list in one command. `buildx` should be available in almost every CI environment by default as it is built into the `docker` CLI and server v19.03+. This removes the need for our CI to create and push manifest lists from images built on machines of the target arch. Currently our Dockerfiles require binaries be built externally with a specific name. We should instead be encapsulating the full image build process in a multi-stage build, in which our Dockerfiles are set up such that they first build the desired binary in a builder image (`golang:alpine`) then copy that binary into the final image (`ubi8/ubi-minimal:latest`). All `goreleaser` requires to publish a release is a with the `repo` privilege, and a quay.io push-enabled token (Travis CI already has one). Contributors need to learn a new configuration format. Luckily the goreleaser is straightforward and has great documentation. Release tool development is controlled by another organization, which can lead to undesirable bugs/changes. This is a manageable risk because the project is open source, to which we can contribute. is experimental and may not be easy to set up in CI. Create a goreleaser configuration that creates the exact same release artifacts the current process does. Push configuration to a test repository. Run a . Ensure: Tag is present remotely. Release notes/binaries are published as expected. Images are pullable and run on the desired architectures. Once test plan has been executed and passed, the goreleaser configuration can be pushed to the operator-sdk repo and unused release scripts/code removed. N/A N/A N/A N/A N/A The `goreleaser` binary will be updated whenever a new release containing a bug fix we want is available. Current release and . See . Combining native Github actions like . Still requires glue code and multiple actions have different configs that are not documented as well. A traditional build system like . While this could work, it is quite heavy-handed for what we need and would likely involve writing glue code. None, this can continue using our current CI infrastructure.