Skip to content

Commit

Permalink
Automate GitHub release creation
Browse files Browse the repository at this point in the history
  • Loading branch information
sbueringer committed Jul 20, 2023
1 parent 9f4726b commit a6c98a3
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 47 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: release

on:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10

permissions:
contents: write # Allow to create a release.

jobs:
build:
name: create draft release
runs-on: ubuntu-latest
steps:
- name: Set env
run: echo "RELEASE_TAG=${GITHUB_REF:10}" >> $GITHUB_ENV
- name: checkout code
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # tag=v3.5.3
with:
fetch-depth: 0
- name: Calculate go version
run: echo "go_version=$(make go-version)" >> $GITHUB_ENV
- name: Set up Go
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # tag=v4.0.1
with:
go-version: ${{ env.go_version }}
- name: generate release artifacts
run: |
make release-manifests VERSION=${RELEASE_TAG}
- name: generate release notes
run: |
make release-notes
- name: Release
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # tag=v1
with:
draft: true
files: out/*
body_path: _releasenotes/${{ env.RELEASE_TAG }}.md
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ vendor/
# Ignore the temporary .gopath directory
.gopath/

# ignore generated yaml in out/
out/
# release artifacts
out
_releasenotes

# Ignore the kubeconfig file generated by clusterctl
/kubeconfig
Expand Down
20 changes: 18 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,17 @@ WEBHOOK_ROOT ?= $(MANIFEST_ROOT)/webhook
RBAC_ROOT ?= $(MANIFEST_ROOT)/rbac
SKIP_RESOURCE_CLEANUP ?= false
USE_EXISTING_CLUSTER ?= false

## latest git tag for the commit, e.g., v0.3.10
RELEASE_TAG ?= $(shell git describe --abbrev=0 2>/dev/null)
ifneq (,$(findstring -,$(RELEASE_TAG)))
PRE_RELEASE=true
endif
# the previous release tag, e.g., v0.3.9, excluding pre-release tags
PREVIOUS_TAG ?= $(shell git tag -l | grep -E "^v[0-9]+\.[0-9]+\.[0-9]+$$" | sort -V | grep -B1 $(RELEASE_TAG) | head -n 1 2>/dev/null)
RELEASE_DIR := out
RELEASE_NOTES_DIR := _releasenotes

BUILD_DIR := .build
OVERRIDES_DIR := $(HOME)/.cluster-api/overrides/infrastructure-vsphere/$(VERSION)

Expand Down Expand Up @@ -367,6 +377,8 @@ generate-flavors: $(FLAVOR_DIR)
$(RELEASE_DIR):
@mkdir -p $(RELEASE_DIR)

$(RELEASE_NOTES_DIR):
mkdir -p $(RELEASE_NOTES_DIR)/

$(BUILD_DIR):
@mkdir -p $(BUILD_DIR)
Expand Down Expand Up @@ -410,8 +422,12 @@ manifests: $(STAGE)-version-check $(STAGE)-flavors $(MANIFEST_DIR) $(BUILD_DIR)
"$(KUSTOMIZE)" build $(BUILD_DIR)/config/supervisor > $(MANIFEST_DIR)/infrastructure-components-supervisor.yaml

.PHONY: generate-release-notes
generate-release-notes: $(TOOLING_BINARIES)
"$(RELEASE_NOTES)" --project kubernetes-sigs/cluster-api-provider-vsphere --branch $(release_branch) --from $(previous_release_tag_or_commit) --r $(release_type) --show-others docs,infra
generate-release-notes: $(RELEASE_NOTES_DIR) $(TOOLING_BINARIES)
if [ -n "${PRE_RELEASE}" ]; then \
echo ":rotating_light: This is a RELEASE CANDIDATE. Use it only for testing purposes. If you find any bugs, file an [issue](https://github.com/kubernetes-sigs/cluster-api/issues/new)." > $(RELEASE_NOTES_DIR)/$(RELEASE_TAG).md; \
else \
"$(RELEASE_NOTES)" --from=$(PREVIOUS_TAG) --prefix-area-label=false --add-kubernetes-version-support=false > $(RELEASE_NOTES_DIR)/$(RELEASE_TAG).md; \
fi

## --------------------------------------
## Verification
Expand Down
55 changes: 25 additions & 30 deletions docs/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,29 @@

## Manual

1. Login using `gcloud auth login`. You should see
`cluster-api-provider-vsphere` in your list of available projects.
2. Make sure your repo is clean by git's standards
3. If this is a new minor release,
1. Verify that the `metadata.yaml` file has an entry binding the CAPI contract
to this new release version.
If this is not yet done, create a new commit to add this entry.
2. Create a new release branch and push
to github, otherwise switch to it, for example `release-0.7`
4. Create an env var VERSION=v0.x.x Ensure the version is prefixed with a v
5. Tag the repository and push the tag `git tag -m $VERSION $VERSION`
* If you have a GPG key for use with git use `git tag -s -m $VERSION $VERSION`
to push a signed tag.
6. Push the tag using `git push upstream $VERSION`
7. Create a draft release in github and associate it with the tag that
was just created.
8. Checkout the tag you've just created and make sure git is in a clean
state
9. Run `hack/release.sh -l` to generate the docker image. Use `-l` if
the `latest` tag should also be applied to the Docker image. Make a
note of the docker image, which should be of the format
manager:${VERSION}. Ignore the manifest:${VERSION}.
10. Run `make release-manifests VERSION=$VERSION` to generate release
manifests in the `/out` directory, and attach them to the draft
release.
11. Push the created docker image, as well as the latest tag, if required.
12. Finalise the release notes
13. Publish release. Use the pre-release option for release
candidate versions of Cluster API Provider vSphere.
14. Email `kubernetes-sig-cluster-lifecycle@googlegroups.com` to
Push the release tag:

1. If this is a new minor release,
1. Verify that the `metadata.yaml` file has an entry binding the CAPI contract
to this new release version.
If this is not yet done, create a new commit to add this entry.
2. Create a new release branch and push
to github, otherwise switch to it, for example `release-0.7`
2. Create an env var VERSION=v0.x.x Ensure the version is prefixed with a v
3. Tag the repository and push the tag `git tag -m $VERSION $VERSION`
* If you have a GPG key for use with git use `git tag -s -m $VERSION $VERSION`
to push a signed tag.
4. Push the tag using `git push upstream $VERSION`

Wait until:

* The release GitHub action created a GitHub draft release: [link](https://github.com/kubernetes-sigs/cluster-api-provider-vsphere/actions/workflows/release.yaml)
* The post-submit ProwJob pushed the image: [link](https://prow.k8s.io/?job=post-cluster-api-provider-vsphere-release)

Publish the release:

1. Review the release notes
2. Publish release. Use the pre-release option for release
candidate versions of Cluster API Provider vSphere.
3. Email `kubernetes-sig-cluster-lifecycle@googlegroups.com` to
announce the release
4 changes: 2 additions & 2 deletions hack/tools/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ go-apidiff: $(APIDIFF) $(SRCS) ## Build go-apidiff
$(APIDIFF): go.mod
go build -tags=tools -o $@ github.com/joelanford/go-apidiff

release-notes: $(RELEASE_NOTES) $(SRCS)
release-notes: $(RELEASE_NOTES) $(SRCS) ## fetch CAPI's release notes tool
$(RELEASE_NOTES): go.mod
go build -tags=tools -o $@ sigs.k8s.io/kubebuilder-release-tools/notes
go build -tags=tools -o $@ sigs.k8s.io/cluster-api/hack/tools/release

## --------------------------------------
## Generate
Expand Down
7 changes: 4 additions & 3 deletions hack/tools/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ require (
sigs.k8s.io/cluster-api/hack/tools v0.0.0-20230711141913-5dedc1b4f9d5
sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20211110210527-619e6b92dab9
sigs.k8s.io/kind v0.17.0
sigs.k8s.io/kubebuilder-release-tools/notes v0.0.0-20220428224951-d8a44c7aef35
sigs.k8s.io/testing_frameworks v0.1.2
)

replace sigs.k8s.io/cluster-api/hack/tools => github.com/sbueringer/cluster-api/hack/tools v0.0.0-20230720105121-40ae6bbf3343

require (
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect
github.com/acomagu/bufpipe v1.0.3 // indirect
github.com/alessio/shellescape v1.4.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/emirpasic/gods v1.12.0 // indirect
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
github.com/go-git/gcfg v1.5.0 // indirect
Expand Down
17 changes: 10 additions & 7 deletions hack/tools/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jB
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA=
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0=
Expand All @@ -57,13 +58,15 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
Expand Down Expand Up @@ -269,6 +272,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sbueringer/cluster-api/hack/tools v0.0.0-20230720105121-40ae6bbf3343 h1:ZA93o1bA6KASSKuYWw86cLorfSV6sliuPstSTlGI33I=
github.com/sbueringer/cluster-api/hack/tools v0.0.0-20230720105121-40ae6bbf3343/go.mod h1:Soe2mRUAQhTZWHLawYW0lZ3Xd69xAOMKJs6dJH7IMdU=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
Expand Down Expand Up @@ -327,6 +332,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
Expand Down Expand Up @@ -480,6 +486,7 @@ golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down Expand Up @@ -699,8 +706,6 @@ k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/cluster-api/hack/tools v0.0.0-20230711141913-5dedc1b4f9d5 h1:dsC+gSKtxg+HLJSRQgbgxO3ARDeF1lPdNjqXe8fSP/E=
sigs.k8s.io/cluster-api/hack/tools v0.0.0-20230711141913-5dedc1b4f9d5/go.mod h1:7o6wiVgH96FfrzR8KyAYyGrtxbtpd8gnv7Bmjw4RHAc=
sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20211110210527-619e6b92dab9 h1:ylYUI5uaq/guUFerFRVG81FHSA5/3+fERCE1RQbQUZ4=
sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20211110210527-619e6b92dab9/go.mod h1:+sJcI1F0QI0Cv+8fp5rH5B2fK1LxzrAQqYnaPx9nY8I=
sigs.k8s.io/controller-tools v0.12.1 h1:GyQqxzH5wksa4n3YDIJdJJOopztR5VDM+7qsyg5yE4U=
Expand All @@ -709,8 +714,6 @@ sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMm
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/kind v0.17.0 h1:CScmGz/wX66puA06Gj8OZb76Wmk7JIjgWf5JDvY7msM=
sigs.k8s.io/kind v0.17.0/go.mod h1:Qqp8AiwOlMZmJWs37Hgs31xcbiYXjtXlRBSftcnZXQk=
sigs.k8s.io/kubebuilder-release-tools/notes v0.0.0-20220428224951-d8a44c7aef35 h1:nUlVsmPoM5QezMBch4fcKiw14QC9ICge+u4qWLouGLQ=
sigs.k8s.io/kubebuilder-release-tools/notes v0.0.0-20220428224951-d8a44c7aef35/go.mod h1:0MFmf9EVf9hm7ULQMpWPWHfh0w7Ut4Ze09onqy2zDSM=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
sigs.k8s.io/testing_frameworks v0.1.2 h1:vK0+tvjF0BZ/RYFeZ1E6BYBwHJJXhjuZ3TdsEKH+UQM=
Expand Down
2 changes: 1 addition & 1 deletion hack/tools/tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import (
_ "github.com/onsi/ginkgo/v2/ginkgo"
_ "k8s.io/code-generator/cmd/conversion-gen"
_ "sigs.k8s.io/cluster-api/hack/tools/conversion-verifier"
_ "sigs.k8s.io/cluster-api/hack/tools/release"
_ "sigs.k8s.io/controller-runtime/tools/setup-envtest"
_ "sigs.k8s.io/kind"
_ "sigs.k8s.io/kubebuilder-release-tools/notes"
_ "sigs.k8s.io/testing_frameworks/integration"
)

0 comments on commit a6c98a3

Please sign in to comment.