Skip to content

Commit 7e490b4

Browse files
author
Eric Stroczynski
authored
*: automate releases with goreleaser (#4034)
This commit adds tooling for automated releases in CI using goreleaser, agnostic of CI platform (albeit with some environment configuration). Any Github user with write capabilities to the SDK repo can start a release. .ci/gpg: GPG public key, encrypted private subkey (used for signing), and script to decrypt private subkey in CI website/scripts: scripts to update versions in release commits and branches at build time .goreleaser.yml: goreleaser config file *: script and Makefile updates to support automated releases docs: release and installation guide simplifications, related docs cleanup
1 parent 74f5a36 commit 7e490b4

File tree

22 files changed

+579
-534
lines changed

22 files changed

+579
-534
lines changed

.ci/gpg/create-keyring.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/bash
2+
3+
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
4+
5+
# Modified from https://blogs.itemis.com/en/secure-your-travis-ci-releases-part-2-signature-with-openpgp
6+
7+
function err_exit() {
8+
echo "ERROR: ${1:-"Unknown Error"} Exiting." 1>&2
9+
exit 1
10+
}
11+
12+
declare -r GPG_HOME="${DIR}/keyring"
13+
declare -r SECRING_AUTO="${GPG_HOME}/secring.auto"
14+
declare -r PUBRING_AUTO="${GPG_HOME}/pubring.auto"
15+
16+
mkdir -p "$GPG_HOME"
17+
cp "${DIR}"/*.auto* "${GPG_HOME}"
18+
19+
echo -e "\nDecrypting secret key..."
20+
{
21+
# $GPG_PASSWORD is taken from the script's env (injected by Travis CI).
22+
echo $GPG_PASSWORD | gpg --decrypt \
23+
--pinentry-mode loopback --batch \
24+
--passphrase-fd 0 \
25+
--output "${SECRING_AUTO}" \
26+
"${SECRING_AUTO}".gpg ; \
27+
} || { err_exit "Failed to decrypt secret key." ; }
28+
echo "Success!"
29+
30+
echo -e "\nImporting keys..."
31+
{ gpg --home "${GPG_HOME}" --import "${PUBRING_AUTO}" ; } || { err_exit "Could not import public key into gpg." ; }
32+
{ gpg --home "${GPG_HOME}" --import "${SECRING_AUTO}" ; } || { err_exit "Could not import secret key into gpg." ; }
33+
echo "Success!"

.ci/gpg/pubring.auto

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
-----BEGIN PGP PUBLIC KEY BLOCK-----
2+
3+
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
62+
dlF2O4uTr4frwKRl28eGEQ==
63+
=ebPb
64+
-----END PGP PUBLIC KEY BLOCK-----

.ci/gpg/secring.auto.gpg

4.3 KB
Binary file not shown.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
/tools/bin
88
/images/*/bin
99

10+
# CI GPG keyring
11+
/.ci/gpg/keyring
12+
1013
# Website
1114
website/public/
1215
website/resources/

.goreleaser.yml

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Global environment variables for builds.
2+
env:
3+
- CGO_ENABLED=0
4+
- GO111MODULE=on
5+
- GOPROXY=https://proxy.golang.org|direct
6+
- REPO=github.com/operator-framework/operator-sdk
7+
8+
# Hooks to run before any build is run.
9+
before:
10+
hooks:
11+
- go version | grep --quiet "go1\.15\.5" || echo "Go binary version must be 1.15.5"
12+
- go mod download
13+
14+
# Binary builds.
15+
builds:
16+
# operator-sdk build steps
17+
- id: operator-sdk
18+
main: ./cmd/operator-sdk
19+
binary: operator-sdk
20+
mod_timestamp: "{{ .CommitTimestamp }}"
21+
asmflags: &build-asmflags
22+
- all=-trimpath={{ .Env.PWD }}
23+
gcflags: &build-gcflags
24+
- all=-trimpath={{ .Env.PWD }}
25+
ldflags: &build-ldflags
26+
- -X {{ .Env.REPO }}/internal/version.Version={{ .Env.SIMPLE_VERSION }}
27+
- -X {{ .Env.REPO }}/internal/version.GitVersion={{ .Env.GIT_VERSION }}
28+
- -X {{ .Env.REPO }}/internal/version.GitCommit={{ .Env.GIT_COMMIT }}
29+
- -X {{ .Env.REPO }}/internal/version.KubernetesVersion={{ .Env.K8S_VERSION }}
30+
- -X {{ .Env.REPO }}/internal/version.ImageVersion={{ .Env.IMAGE_VERSION }}
31+
targets: &build-targets
32+
- darwin_amd64
33+
- linux_amd64
34+
- linux_arm64
35+
- linux_ppc64le
36+
- linux_s390x
37+
38+
# ansible-operator build steps
39+
- id: ansible-operator
40+
main: ./cmd/ansible-operator
41+
binary: ansible-operator
42+
mod_timestamp: "{{ .CommitTimestamp }}"
43+
asmflags: *build-asmflags
44+
gcflags: *build-gcflags
45+
ldflags: *build-ldflags
46+
targets: *build-targets
47+
48+
# helm-operator build steps
49+
- id: helm-operator
50+
main: ./cmd/helm-operator
51+
binary: helm-operator
52+
mod_timestamp: "{{ .CommitTimestamp }}"
53+
asmflags: *build-asmflags
54+
gcflags: *build-gcflags
55+
ldflags: *build-ldflags
56+
targets: *build-targets
57+
58+
# Use most recent tag and short commit for snapshot version.
59+
snapshot:
60+
name_template: "{{ .Env.GIT_VERSION }}"
61+
62+
# We don't use archives, so skip creating them.
63+
archives:
64+
- format: binary
65+
name_template: "{{ .Binary }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}"
66+
67+
checksum:
68+
name_template: "checksums.txt"
69+
70+
# Sign the checksum file with the CI GPG key.
71+
signs:
72+
- signature: "${artifact}.asc"
73+
artifacts: checksum
74+
# Use the CI signing subkey A20B5C7E decrypted into .ci/gpg/keyring to sign the release.
75+
args: ["--home", ".ci/gpg/keyring", "-u", "A20B5C7E", "--output", "${signature}", "--detach-sign", "${artifact}"]
76+
77+
# We use a custom changelog generator.
78+
changelog:
79+
80+
# TODO(estroz): configure homebrew publishing
81+
# brews:
82+
# - name: operator-sdk
83+
# ids:
84+
# - operator-sdk
85+
86+
# Uncomment for testing
87+
# release:
88+
# github:
89+
# owner: <your-github-namespace>
90+
# name: operator-sdk

.travis.yml

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ dist: xenial
33

44
language: go
55
go:
6-
- 1.15.x
6+
- 1.15.5
77
go_import_path: github.com/operator-framework/operator-sdk
88

99
cache:
@@ -47,12 +47,16 @@ x_base_steps:
4747
- docker
4848

4949
stages:
50-
- check
51-
- test
50+
- name: check
51+
if: type == pull_request
52+
- name: test
53+
if: type == pull_request
5254
- name: deploy
5355
if: type != pull_request AND ( tag IS present OR branch = master OR commit_message =~ /\[travis deploy\]/ )
5456
- name: deploy-manifest-multiarch
5557
if: type != pull_request AND ( tag IS present OR branch = master OR commit_message =~ /\[travis deploy\]/ )
58+
- name: release
59+
if: type != pull_request AND tag IS present
5660

5761
jobs:
5862
include:
@@ -151,3 +155,12 @@ jobs:
151155
name: push manifest lists
152156
<<: *manifest-deploy
153157
script: make -f release/Makefile image-push-multiarch
158+
159+
## Release jobs ##
160+
161+
- stage: release
162+
name: publish release
163+
before_install: git fetch origin --unshallow --tags
164+
install: sudo ln -sf $(command -v gpg2) $(dirname $(command -v gpg2))/gpg
165+
before_script: .ci/gpg/create-keyring.sh
166+
script: make release

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
**This file will no longer be updated. Instead, refer to generated `changelog/generated/<version>.md`**
2+
13
## v1.2.0
24

35
### Additions

Makefile

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ export GIT_COMMIT = $(shell git rev-parse HEAD)
1212
export K8S_VERSION = 1.18.8
1313

1414
# Build settings
15+
export TOOLS_DIR = tools/bin
16+
export SCRIPTS_DIR = tools/scripts
1517
REPO = $(shell go list -m)
1618
BUILD_DIR = build
17-
TOOLS_DIR = tools/bin
18-
SCRIPTS_DIR = tools/scripts
1919
GO_ASMFLAGS = -asmflags "all=-trimpath=$(shell dirname $(PWD))"
2020
GO_GCFLAGS = -gcflags "all=-trimpath=$(shell dirname $(PWD))"
2121
GO_BUILD_ARGS = \
@@ -73,7 +73,7 @@ build/scorecard-test build/scorecard-test-kuttl build/custom-scorecard-tests:
7373
build/operator-sdk build/ansible-operator build/helm-operator:
7474
go build $(GO_BUILD_ARGS) -o $(BUILD_DIR)/$(@F) ./cmd/$(@F)
7575

76-
##@ Dev images
76+
##@ Dev image build
7777

7878
# Convenience wrapper for building all remotely hosted images.
7979
.PHONY: image-build
@@ -90,6 +90,23 @@ image/%: build/%
9090
docker build -t $(BUILD_IMAGE_REPO)/$*:dev -f ./images/$*/Dockerfile ./images/$*
9191
rm -rf $(BUILD_DIR)
9292

93+
##@ Release
94+
95+
.PHONY: release
96+
release: ## Release target. See 'make -f release/Makefile help' for more information.
97+
$(MAKE) -f release/Makefile $@
98+
99+
.PHONY: prerelease
100+
prerelease: ## Write release commit changes. See 'make -f release/Makefile help' for more information.
101+
ifneq ($(RELEASE_VERSION),$(IMAGE_VERSION))
102+
$(error "IMAGE_VERSION "$(IMAGE_VERSION)" must be updated to match RELEASE_VERSION "$(RELEASE_VERSION)" prior to creating a release commit")
103+
endif
104+
$(MAKE) -f release/Makefile $@
105+
106+
.PHONY: tag
107+
tag: ## Tag a release commit. See 'make -f release/Makefile help' for more information.
108+
$(MAKE) -f release/Makefile $@
109+
93110
##@ Test
94111

95112
.PHONY: test-all
@@ -156,16 +173,6 @@ test-e2e-integration:: ## Run integration tests
156173
./hack/tests/integration.sh
157174
./hack/tests/subcommand-olm-install.sh
158175

159-
# TODO(estroz): remove changelog/release when goreleaser is added as release tool (they shouldn't be exposed as dev targets).
160-
161-
.PHONY: changelog
162-
changelog: ## Generate CHANGELOG.md and migration guide updates
163-
$(MAKE) -f release/Makefile changelog
164-
165-
.PHONY: release
166-
release: clean ## Release the Operator SDK
167-
$(MAKE) -f release/Makefile GO_BUILD_ARGS='$(GO_BUILD_ARGS)'
168-
169176
.DEFAULT_GOAL := help
170177
.PHONY: help
171178
help: ## Show this help screen.

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,39 @@ operators easier by providing:
2828
- Tools for scaffolding and code generation to bootstrap a new project fast
2929
- Extensions to cover common operator use cases
3030

31+
## Dependency and platform support
32+
33+
### Go version
34+
35+
Release binaries will be built with the Go compiler version specified in the Operator SDK's [prerequisites section][doc-readme-prereqs].
36+
37+
### Kubernetes versions
38+
39+
As the Operator SDK interacts directly with the Kubernetes API, certain API features are assumed to exist in the target cluster.
40+
The currently supported Kubernetes version will always be listed in the SDK [prerequisites section][doc-readme-prereqs].
41+
42+
### Platforms
43+
44+
The following matrix defines which architectures are supported for GNU Linux:
45+
46+
| | `amd64` | `arm64` | `ppc64le` | `s390x` |
47+
|-------------------------------|-----------------|-----------------|-----------------|-----------------|
48+
| `operator-sdk` |||||
49+
| `ansible-operator` |||||
50+
| `helm-operator` |||||
51+
| `scorecard-test` image |||||
52+
| `scorecard-test-kuttl` image |||| - |
53+
54+
The following matrix defines which architectures are supported for MacOS Darwin:
55+
56+
| | `amd64` |
57+
|-------------------------------|-----------------|
58+
| `operator-sdk` ||
59+
| `ansible-operator` ||
60+
| `helm-operator` ||
61+
62+
Support for the Windows platform is not on the roadmap at this time.
63+
3164
## License
3265

3366
Operator SDK is under Apache 2.0 license. See the [LICENSE][license_file] file for details.

hack/image/push-image-tags.sh

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ function push_image_tags() {
1616
push_image=$1; shift || push_image=$source_image
1717

1818
print_image_info $source_image
19-
print_git_tags
2019

2120
docker_login $push_image
2221

@@ -53,31 +52,4 @@ function print_image_info() {
5352
fi
5453
}
5554

56-
#
57-
# print_git_tags
58-
#
59-
# print_git_tags prints all tags present in the git repository.
60-
#
61-
function print_git_tags() {
62-
git_tags=$(git tag -l | sed 's|^| |')
63-
if [[ -n "$git_tags" ]]; then
64-
echo "Found git tags:"
65-
echo "$git_tags"
66-
echo ""
67-
fi
68-
}
69-
70-
71-
#
72-
# latest_git_version
73-
#
74-
# latest_git_version returns the highest semantic version
75-
# number found in the repository, with the form "vX.Y.Z".
76-
# Version numbers not matching the semver release format
77-
# are ignored.
78-
#
79-
function latest_git_version() {
80-
git tag -l | egrep "${semver_regex}" | sort -V | tail -1
81-
}
82-
8355
push_image_tags "$@"

0 commit comments

Comments
 (0)