Skip to content

Commit

Permalink
Release workflow (#88)
Browse files Browse the repository at this point in the history
* Release workflow

Closes #72

This change proposes to start using semver from the get-go. This means
the `edge` particle would go last, so we'd start with `0.0.1-edge`. The
charts' `version` and `appVersion` entries would match that, with
`version` being able to drift when chart-only changes happen (I added details
into the `RELEASE.md` file). After multiple edge releases we could issue
the stable by bumping the minor part and dropping the suffix: `0.1.0`.

Unlike linkerd2, the latest image tag (currently `0.0.1-edge`) is
hard-coded into the `values.yaml` file. It needs to be manually bumped
on each release, but this allows people (and us during testing) to consume
the chart directly from the source code without any preprocessing.

As described in `RELEASE.md`, after having merged the release notes in
`CHANGES.md`, one would need to tag `main` and that triggers the new
`release.yml` workflow, which:

- builds and pushes the docker image
- runs the integration tests pulling that image
- creates the release in github (currently won't hold any assets, just
  the change notes)
- will publish the chart into the `https://helm.linkerd.io` helm repo.
  • Loading branch information
alpeb authored Mar 9, 2022
1 parent 65d9ce4 commit bcc14fe
Show file tree
Hide file tree
Showing 9 changed files with 283 additions and 6 deletions.
143 changes: 143 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
name: Release

on:
push:
tags:
- "[0-9]+.[0-9]+.[0-9]+*"

permissions:
contents: read

env:
DOCKER_REGISTRY: ghcr.io/linkerd

jobs:

docker-build:
runs-on: ubuntu-20.04
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Docker build
uses: ./.github/actions/docker-build
with:
docker-registry: ${{ env.DOCKER_REGISTRY }}
docker-tag: ${{ github.ref_name }}
docker-target: linux-amd64
docker-push: 1
docker-ghcr-username: ${{ secrets.DOCKER_GHCR_USERNAME }}
docker-ghcr-pat: ${{ secrets.DOCKER_GHCR_PAT }}
component: failover

integration-tests:
runs-on: ubuntu-20.04
timeout-minutes: 10
needs: [docker-build]
steps:
- name: Checkout code
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Set up Helm
uses: azure/setup-helm@a517f2ff6560563a369e16ca7c7d136b6164423f
- name: Create cluster
uses: AbsaOSS/k3d-action@5d155528f6d4a35f72c4cf3590e22fa0dde1e28a
with:
cluster-name: testing
- name: Install linkerd
run: |
curl -sL https://run.linkerd.io/install-edge | sh
export PATH=$PATH:~/.linkerd2/bin
linkerd install | kubectl apply -f -
linkerd check
- name: Install linkerd-smi
run: |
helm repo add linkerd-smi https://linkerd.github.io/linkerd-smi
helm repo up
helm install linkerd-smi -n linkerd-smi --create-namespace --wait linkerd-smi/linkerd-smi
- name: Install current linkerd-failover
run: |
helm install linkerd-failover -n linkerd-failover --create-namespace --wait \
--set image.registry=${{ env.DOCKER_REGISTRY }} \
--set image.tag=${{ github.ref_name }} \
charts/linkerd-failover
- name: Test routing to primary
uses: ./.github/actions/failover-test
with:
westReplicas: 1
westShouldReceiveTraffic: true
centralReplicas: 1
centralShouldReceiveTraffic: false
eastReplicas: 1
eastShouldReceiveTraffic: false
- name: Test failover to secondaries
uses: ./.github/actions/failover-test
with:
westReplicas: 0
westShouldReceiveTraffic: false
centralReplicas: 1
centralShouldReceiveTraffic: true
eastReplicas: 1
eastShouldReceiveTraffic: true
- name: Test removal of one secondary
uses: ./.github/actions/failover-test
with:
westReplicas: 0
westShouldReceiveTraffic: false
centralReplicas: 0
centralShouldReceiveTraffic: false
eastReplicas: 1
eastShouldReceiveTraffic: true
- name: Test reestablishment of primary
uses: ./.github/actions/failover-test
with:
westReplicas: 1
westShouldReceiveTraffic: true
centralReplicas: 0
centralShouldReceiveTraffic: false
eastReplicas: 1
eastShouldReceiveTraffic: false

gh-release:
name: Create GH release
timeout-minutes: 10
runs-on: ubuntu-20.04
needs: [integration-tests]
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
- name: Extract release notes
run: |
. bin/_release.sh
extract_release_notes NOTES.md
- name: Create release
id: create_release
uses: softprops/action-gh-release@fb0163a75bee697a9cfec2c931801de7c7f10042
with:
draft: false
prerelease: false
body_path: NOTES.md

chart-deploy:
name: Helm chart deploy
timeout-minutes: 10
runs-on: ubuntu-20.04
needs: [gh-release]
steps:
- name: Checkout code
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
- name: Set up Helm
uses: azure/setup-helm@a517f2ff6560563a369e16ca7c7d136b6164423f
- name: Log into GCP
uses: 'google-github-actions/auth@8d125895b958610ec414ca4dae010257eaa814d3'
with:
credentials_json: ${{ secrets.LINKERD_SITE_TOKEN }}
- name: Helm chart creation and upload
run: |
mkdir -p target/helm
helm --app-version "${{ github.ref_name }}" -d target/helm package charts/linkerd-failover
# backup index file before changing it
gsutil cp gs://helm.linkerd.io/edge/index.yaml "target/helm/index-pre-failover-${{ github.ref_name }}".yaml
helm repo index --url https://helm.linkerd.io/edge/ --merge "target/helm/index-pre-failover-${{ github.ref_name }}".yaml target/helm
gsutil rsync target/helm gs://helm.linkerd.io/edge
7 changes: 7 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Changes

## 0.0.1-edge

First release!

Please check the README.md for instructions.
95 changes: 95 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Linkerd-failover Release

This document contains instructions for releasing the Linkerd-failover
extension.

## Version schema

### Example

```text
0.0.1-edge
0.0.2-edge
0.0.3-edge
0.1.0
0.2.0-edge
0.2.1-edge
0.2.2-edge
...
0.1.1 (maintenance release for 0.1.0 stable)
...
```

### Explanation

Note we use semver, both for edge and stable releases. Edge releases use the
pattern `major.minor.patch-edge` and stable releases just drop the `edge`
suffix.

Successive edge releases only bump the patch part, regardless of how big the
changes are. When an edge release is ready to become the next stable release, we
bump the minor part (or major if there are backwards-incompatible changes) and
drop the `edge` suffix. The following edge release will bump the minor part, as
to leave room for maintenance releases of the previous stable release.

## Release procedure

### 1. Create the release branch

Create a branch in the `linkerd-failover` repo, `username/X.X.X-edge` (replace
with your username and the actual release number).

### 2. Update the Helm charts versions

- Update the `appVersion` in the `Chart.yaml` files for the `linkerd-failover`
and `linkerd-failover` charts. `appVersion` should match the actual
version/tag.
- Also update their `version` entry. During the first few releases this will
match `appVersion`, but may drift apart in the future when there are changes
to the chart templates but no changes in the underlying `failover` docker
image.
- Update the `tag` entry in the `linkerd-failover` chart with the same value you
used for `version`.

Rules for changes in the `version` entry:

- patch bump for minor changes
- minor bump for additions/removals
- major bump for backwards-incompatible changes, most notably changes that
change the structure of `values.yaml`

Finally, keep in mind chart version changes require updating the charts README
files (through `bin/helm-docs`).

### 3. Update the release notes

On this branch, add the release notes for this version in `CHANGES.md`.

Note: To see all of the changes since the previous release, run the command
below in the `linkerd-failover` repo.

```bash
git log Y.Y.Y-edge..HEAD
```

### 4. Post a PR that includes the changes

This PR needs an approval from a "code owner." Feel free to ping one of the code
owners if you've gotten feedback and approvals from other team members.

### 5. Merge release notes branch, then create the release tag

After the review has passed and the branch has been merged, follow the
instructions below to properly create and push the release tag from the
appropriate branch. Replace `TAG` below with the `appVersion` you used in step 2
above.

**Note**: This will create a GPG-signed tag, so users must have GPG signing
setup in their local git config.

```bash
git checkout main git pull notes=$(. "bin"/_release.sh; extract_release_notes)
git tag -s -F "$notes" TAG
git push origin TAG
```
28 changes: 28 additions & 0 deletions bin/_release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
# shellcheck disable=SC2120
# (disabling SC2120 so that we can use functions with optional args
# see https://github.com/koalaman/shellcheck/wiki/SC2120#exceptions )

set -eu

extract_release_notes() {
bindir=$( cd "${BASH_SOURCE[0]%/*}" && pwd )
rootdir=$( cd "$bindir"/.. && pwd )

if [ $# -eq 0 ]
then
# Make temporary file to save the release commit message into.
tmp=$(mktemp -t release-commit-message.XXX.txt)
else
tmp="$rootdir/$1"
fi

# Save commit message into temporary file.
#
# Match each occurrence of the regex and increment `n` by 1. While n == 1
# (which is true only for the first section) print that line of `CHANGES.md`.
# This ends up being the first section of release changes.
awk '/^## [0-9]+\.[0-9]+\.[0-9]+.*/{n++} n==1' "$rootdir"/CHANGES.md > "$tmp"

echo "$tmp"
}
3 changes: 2 additions & 1 deletion charts/linkerd-failover-tests/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ keywords:
kubeVersion: ">=1.20.0-0"
sources:
- https://github.com/linkerd/linkerd-failover/
version: 0.1.0
appVersion: 0.0.1-edge
version: 0.0.1-edge
icon: https://linkerd.io/images/logo-only-200h.png
maintainers:
- name: Linkerd authors
Expand Down
3 changes: 2 additions & 1 deletion charts/linkerd-failover-tests/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<!-- markdownlint-disable -->
# linkerd-failover-tests

![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square)
![Version: 0.0.1-edge](https://img.shields.io/badge/Version-0.0.1--edge-informational?style=flat-square)
![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)
![AppVersion: 0.0.1-edge](https://img.shields.io/badge/AppVersion-0.0.1--edge-informational?style=flat-square)

**Homepage:** <https://linkerd.io>

Expand Down
3 changes: 2 additions & 1 deletion charts/linkerd-failover/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ keywords:
kubeVersion: ">=1.20.0-0"
sources:
- https://github.com/linkerd/linkerd-failover/
version: 0.1.0
appVersion: 0.0.1-edge
version: 0.0.1-edge
icon: https://linkerd.io/images/logo-only-200h.png
maintainers:
- name: Linkerd authors
Expand Down
5 changes: 3 additions & 2 deletions charts/linkerd-failover/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<!-- markdownlint-disable -->
# linkerd-failover

![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square)
![Version: 0.0.1-edge](https://img.shields.io/badge/Version-0.0.1--edge-informational?style=flat-square)
![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)
![AppVersion: 0.0.1-edge](https://img.shields.io/badge/AppVersion-0.0.1--edge-informational?style=flat-square)

**Homepage:** <https://linkerd.io>

Expand Down Expand Up @@ -52,7 +53,7 @@ Kubernetes: `>=1.20.0-0`

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| image | object | `{"name":"failover","registry":"cr.l5d.io/linkerd","tag":"latest"}` | Docker image |
| image | object | `{"name":"failover","registry":"cr.l5d.io/linkerd","tag":"0.0.1-edge"}` | Docker image |
| logFormat | string | `"plain"` | Log format (`plain` or `json`) |
| logLevel | string | `"linkerd=info,warn"` | Log level |
| selector | string | `nil` | Determines which `TrafficSplit` instances to consider for failover. If empty, defaults to failover.linkerd.io/controlled-by={{ .Release.Name }} |
Expand Down
2 changes: 1 addition & 1 deletion charts/linkerd-failover/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ logFormat: plain
image:
registry: cr.l5d.io/linkerd
name: failover
tag: latest
tag: 0.0.1-edge

# -- Determines which `TrafficSplit` instances to consider for failover. If
# empty, defaults to failover.linkerd.io/controlled-by={{ .Release.Name }}
Expand Down

0 comments on commit bcc14fe

Please sign in to comment.