Skip to content

Commit

Permalink
Automating release creation
Browse files Browse the repository at this point in the history
Signed-off-by: Muhammad Adil Ghaffar <muhammad.adil.ghaffar@est.tech>
  • Loading branch information
adilGhaffarDev committed Nov 8, 2024
1 parent 4ed14e5 commit ca754b1
Show file tree
Hide file tree
Showing 7 changed files with 346 additions and 165 deletions.
134 changes: 106 additions & 28 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -1,39 +1,117 @@
name: release
# This code is borrowed from https://github.com/kubernetes-sigs/cluster-api/blob/main/.github/workflows/release.yaml
name: Create Release

on:
push:
# Sequence of patterns matched against refs/tags
tags:
- "v*"
branches:
- main
paths:
- 'releasenotes/*.md'

permissions: {}

jobs:
build:
name: tag release
push_release_tags:
permissions:
contents: write
runs-on: ubuntu-latest

outputs:
release_tag: ${{ steps.release-version.outputs.release_version }}
steps:
- name: Checkout code
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # tag=v4.1.7
with:
fetch-depth: 0
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@e9772d140489982e0e3704fea5ee93d536f1e275 # tag=v45.0.1
- name: Get release version
id: release-version
run: |
if [[ ${{ steps.changed-files.outputs.all_changed_files_count }} != 1 ]]; then
echo "1 release notes file should be changed to create a release tag, found ${{ steps.changed-files.outputs.all_changed_files_count }}"
exit 1
fi
for changed_file in ${{ steps.changed-files.outputs.all_changed_files }}; do
export RELEASE_VERSION=$(echo "${changed_file}" | grep -oP '(?<=/)[^/]+(?=\.md)')
echo "RELEASE_VERSION=${RELEASE_VERSION}" >> ${GITHUB_ENV}
echo "RELEASE_VERSION=${RELEASE_VERSION}" >> ${GITHUB_OUTPUT}
if [[ "${RELEASE_VERSION}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$ ]]; then
echo "Valid semver: ${RELEASE_VERSION}"
else
echo "Invalid semver: ${RELEASE_VERSION}"
exit 1
fi
done
- name: Determine the release branch to use
run: |
if [[ ${RELEASE_VERSION} =~ beta ]] || [[ ${RELEASE_VERSION} =~ alpha ]]; then
export RELEASE_BRANCH=main
echo "RELEASE_BRANCH=${RELEASE_BRANCH}" >> ${GITHUB_ENV}
echo "This is a beta or alpha release, will use release branch ${RELEASE_BRANCH}"
else
export RELEASE_BRANCH=release-$(echo ${RELEASE_VERSION} | sed -E 's/^v([0-9]+)\.([0-9]+)\..*$/\1.\2/')
echo "RELEASE_BRANCH=${RELEASE_BRANCH}" >> ${GITHUB_ENV}
echo "This is not a beta or alpha release, will use release branch ${RELEASE_BRANCH}"
fi
- name: Create or checkout release branch
run: |
if git show-ref --verify --quiet "refs/remotes/origin/${RELEASE_BRANCH}"; then
echo "Branch ${RELEASE_BRANCH} already exists"
git checkout "${RELEASE_BRANCH}"
else
git checkout -b "${RELEASE_BRANCH}"
git push origin "${RELEASE_BRANCH}"
echo "Created branch ${RELEASE_BRANCH}"
fi
- name: Validate tag does not already exist
run: |
if [[ -n "$(git tag -l "${RELEASE_VERSION}")" ]]; then
echo "Tag ${RELEASE_VERSION} already exists, exiting"
exit 1
fi
- name: Create Release Tag
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
git tag -a ${RELEASE_VERSION} -m ${RELEASE_VERSION}
git tag test/${RELEASE_VERSION}
git push origin ${RELEASE_VERSION}
git push origin test/${RELEASE_VERSION}
echo "Created tags ${RELEASE_VERSION} and test/${RELEASE_VERSION}"
release:
name: create draft release
runs-on: ubuntu-latest
needs: push_release_tags
permissions:
contents: write

if: github.repository == 'metal3-io/ip-address-manager'
steps:
- name: Export RELEASE_TAG var
run: echo "RELEASE_TAG=${GITHUB_REF:10}" >> $GITHUB_ENV
- name: checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Install go
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
with:
go-version: '1.22'
- name: Generate release artifacts and notes
run: |
make release
- name: Release
uses: softprops/action-gh-release@e7a8f85e1c67a31e6ed99a94b41bd0b71bbee6b8 # v2.0.9
with:
draft: true
files: out/*
body_path: releasenotes/${{ env.RELEASE_TAG }}.md
- name: Set env
run: echo "RELEASE_TAG=${RELEASE_TAG}" >> ${GITHUB_ENV}
env:
RELEASE_TAG: ${{needs.push_release_tags.outputs.release_tag}}
- name: checkout code
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # tag=v4.1.7
with:
fetch-depth: 0
ref: ${{ env.RELEASE_TAG }}
- name: Calculate go version
run: echo "go_version=$(make go-version)" >> ${GITHUB_ENV}
- name: Set up Go
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # tag=v5.0.2
with:
go-version: ${{ env.go_version }}
- name: generate release artifacts
run: |
make release
- name: get release notes
run: |
curl -L "https://raw.githubusercontent.com/${{ github.repository }}/main/CHANGELOG/${{ env.RELEASE_TAG }}.md" \
-o "${{ env.RELEASE_TAG }}.md"
- name: Release
uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 # tag=v2.0.8
with:
draft: true
files: out/*
body_path: ${{ env.RELEASE_TAG }}.md
tag_name: ${{ env.RELEASE_TAG }}
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ tilt_config.json
tilt.d/*

out
releasenotes

# Development containers (https://containers.dev/)
.devcontainer

# vscode
.vscode

# Common editor / temporary files
*~
*.tmp
Expand Down
11 changes: 6 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -289,11 +289,8 @@ kind-reset: ## Destroys the "ipam" kind cluster.
## Release
## --------------------------------------

RELEASE_TAG ?= $(shell git describe --abbrev=0 2>/dev/null)
RELEASE_DIR := out
RELEASE_NOTES_DIR := releasenotes
PREVIOUS_TAG ?= $(shell git tag -l | grep -E "^v[0-9]+\.[0-9]+\.[0-9]+" | sort -V | grep -B1 $(RELEASE_TAG) | grep -E "^v[0-9]+\.[0-9]+\.[0-9]+$$" | head -n 1 2>/dev/null)

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

Expand All @@ -304,9 +301,13 @@ $(RELEASE_NOTES_DIR):
release-manifests: $(KUSTOMIZE) $(RELEASE_DIR) ## Builds the manifests to publish with a release
$(KUSTOMIZE) build config/default > $(RELEASE_DIR)/ipam-components.yaml

.PHONY: release-notes-tool
release-notes-tool:
go build -C hack/tools -o $(BIN_DIR) -tags tools github.com/metal3-io/ip-address-manager/hack/tools/release

.PHONY: release-notes
release-notes: $(RELEASE_NOTES_DIR) $(RELEASE_NOTES)
go run ./hack/tools/release/notes.go --from=$(PREVIOUS_TAG) > $(RELEASE_NOTES_DIR)/$(RELEASE_TAG).md
release-notes: $(RELEASE_NOTES_DIR) $(RELEASE_NOTES) release-notes-tool
$(TOOLS_BIN_DIR)/release --releaseTag=$(RELEASE_TAG) > $(RELEASE_NOTES_DIR)/$(RELEASE_TAG).md

.PHONY: release
release:
Expand Down
32 changes: 20 additions & 12 deletions docs/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,25 @@ Clone the repository:
or if using existing repository, verify your intended remote is set to
`metal3-io`: `git remote -v`. For this document, we assume it is `origin`.

- If creating a new minor branch, identify the commit you wish to create the
branch from, and create a branch `release-1.x`:
`git checkout <sha> -b release-1.x` and push it to remote:
`git push origin release-1.x` to create it
- If creating a new patch release, use existing branch `release-1.x`:
`git checkout origin/release-1.x`
### Creating Release Notes

### Tags
- Switch to the main branch: `git checkout main`

First we create a primary release tag, that triggers release note creation and
image building processes.
- Create a new branch for the release notes**:
`git checkout -b release-notes-1.x.x origin/main`

- Create a signed, annotated tag with: `git tag -s -a v1.x.y -m v1.x.y`
- Push the tags to the GitHub repository: `git push origin v1.x.y`
- Generate the release notes: `RELEASE_TAG=v1.x.x make release-notes`
- Replace `v1.x.x` with the new release tag you're creating.
- This command generates the release notes here `releasenotes/<RELEASE_TAG>.md` .

This triggers two things:
- Commit and push your changes, push the new branch and create a pull request.
IMPORTANT_NOTE:
- The commit and PR title should be 🚀 Release v1.x.y.
- Important! The commit should only contain the release notes file, nothing else, otherwise automation will not work.

- Ask maintainers and release team members to review your pull request.

Once PR is merged it triggers three things:

- GitHub action workflow for automated release process creates a draft release
in GitHub repository with correct content, comparing the pushed tag to
Expand All @@ -83,6 +86,11 @@ This triggers two things:
[Quay tags page](https://quay.io/repository/metal3-io/ip-address-manager?tab=tags).
If the release tag build is not visible, check if the action has failed and
retrigger as necessary.
- GH job `create draft release` creates draft release. Don't publish the release until
release tag is visible in
[Quay tags page](https://quay.io/repository/metal3-io/ip-address-manager?tab=tags).
If the release tag build is not visible, check if the action has failed and
retrigger as necessary.

We also need to create one or more tags for the Go modules ecosystem:

Expand Down
67 changes: 37 additions & 30 deletions hack/tools/go.mod
Original file line number Diff line number Diff line change
@@ -1,72 +1,79 @@
module github.com/metal3-io/ip-address-manager/hack/tools

go 1.22.3
go 1.22.7

require (
github.com/jteeuwen/go-bindata v3.0.7+incompatible
k8s.io/code-generator v0.30.6
sigs.k8s.io/controller-tools v0.13.0
sigs.k8s.io/testing_frameworks v0.1.2
)
toolchain go1.22.9

replace github.com/metal3-io/ip-address-manager => ../../

require (
github.com/blang/semver v3.5.1+incompatible
github.com/golang/mock v1.6.0
sigs.k8s.io/kustomize/kustomize/v5 v5.4.3
github.com/google/go-github v17.0.0+incompatible
github.com/jteeuwen/go-bindata v3.0.7+incompatible
github.com/pkg/errors v0.9.1
golang.org/x/oauth2 v0.21.0
k8s.io/code-generator v0.31.2
sigs.k8s.io/controller-tools v0.16.5
sigs.k8s.io/kustomize/kustomize/v5 v5.5.0
sigs.k8s.io/testing_frameworks v0.1.2
)

require (
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/gobuffalo/flect v1.0.2 // indirect
github.com/gobuffalo/flect v1.0.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/onsi/gomega v1.31.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/onsi/gomega v1.34.2 // indirect
github.com/sergi/go-diff v1.2.0 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/cobra v1.8.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
golang.org/x/mod v0.15.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.18.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/tools v0.26.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.29.10 // indirect
k8s.io/apiextensions-apiserver v0.29.10 // indirect
k8s.io/apimachinery v0.30.6 // indirect
k8s.io/api v0.31.2 // indirect
k8s.io/apiextensions-apiserver v0.31.2 // indirect
k8s.io/apimachinery v0.31.2 // indirect
k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 // indirect
k8s.io/klog/v2 v2.120.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/kustomize/api v0.17.3 // indirect
sigs.k8s.io/kustomize/cmd/config v0.14.2 // indirect
sigs.k8s.io/kustomize/kyaml v0.17.2 // indirect
sigs.k8s.io/kustomize/api v0.18.0 // indirect
sigs.k8s.io/kustomize/cmd/config v0.15.0 // indirect
sigs.k8s.io/kustomize/kyaml v0.18.1 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
Loading

0 comments on commit ca754b1

Please sign in to comment.