Skip to content

Commit 88f22cc

Browse files
authored
Merge pull request #615 from simonchrz/ci/monthly-minor-on-breaking
Release a new minor version when breaking changes were merged
2 parents e09844e + 7a3b79b commit 88f22cc

4 files changed

Lines changed: 54 additions & 15 deletions

File tree

‎.github/workflows/monthly-release.yml‎

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
name: Monthly patch release
1+
name: Monthly release
22

3-
# Cuts a patch release on the 1st of each month when main is green and
4-
# something has merged since the last release. Scheduled runs only report
5-
# what they would do until the repository variable MONTHLY_RELEASE is "true".
3+
# Cuts a release on the 1st of each month when main is green and something
4+
# has merged since the last release: a patch release, or a new minor version
5+
# if a pull request labelled "breaking" was merged (a new major version from
6+
# 1.0 on). A breaking release is created as a draft, and its images and chart
7+
# are published only when someone publishes the draft, after writing the
8+
# upgrade notes. Scheduled runs only report what they would do until the
9+
# repository variable MONTHLY_RELEASE is "true".
610

711
on:
812
schedule:
@@ -56,6 +60,14 @@ jobs:
5660
5761
sha=$(git rev-parse HEAD)
5862
last=$(git describe --tags --abbrev=0 --match 'v[0-9]*.[0-9]*.[0-9]*' --exclude '*-*')
63+
# A breaking release waits as a draft for its upgrade notes. Building
64+
# on its tag would publish those changes without them. Older tags
65+
# were released by hand and may have no release at all.
66+
draft=$(gh release view "$last" -R "$REPO" --json isDraft --jq .isDraft 2>/dev/null || echo false)
67+
if [ "$draft" = true ]; then
68+
echo "::warning::$last is still a draft, publish it first"
69+
exit 0
70+
fi
5971
merged=$(git rev-list --count "$last..$sha")
6072
if [ "$merged" -eq 0 ]; then
6173
echo "Nothing merged since $last"
@@ -76,18 +88,24 @@ jobs:
7688
fi
7789
7890
since=$(git log -1 --format=%cI "$last")
79-
breaking=$(gh pr list -R "$REPO" --state merged --base main \
91+
breaking=$(gh pr list -R "$REPO" --state merged --base main --limit 1000 \
8092
--search "merged:>$since label:breaking" --json number --jq '.[].number')
81-
if [ -n "$breaking" ]; then
82-
echo "::warning::breaking changes merged since $last (#$(echo "$breaking" | paste -sd, - | sed 's/,/, #/g')), release a new minor version by hand"
83-
exit 0
84-
fi
8593
8694
IFS=. read -r major minor patch <<<"${last#v}"
87-
tag="v$major.$minor.$((patch + 1))"
95+
if [ -z "$breaking" ]; then
96+
tag="v$major.$minor.$((patch + 1))"
97+
else
98+
echo "Breaking changes merged since $last: #$(echo "$breaking" | sort -n | paste -sd, - | sed 's/,/, #/g')"
99+
if [ "$major" -eq 0 ]; then
100+
tag="v0.$((minor + 1)).0"
101+
else
102+
tag="v$((major + 1)).0.0"
103+
fi
104+
fi
88105
echo "$merged commits since $last, next release $tag at $sha"
89106
echo "tag=$tag" >> "$GITHUB_OUTPUT"
90107
echo "sha=$sha" >> "$GITHUB_OUTPUT"
108+
echo "draft=$([ -n "$breaking" ] && echo true || echo false)" >> "$GITHUB_OUTPUT"
91109
92110
# A tag pushed with GITHUB_TOKEN doesn't start other workflows, so the
93111
# release workflows are dispatched on the new tag instead.
@@ -97,13 +115,23 @@ jobs:
97115
TAG: ${{ steps.plan.outputs.tag }}
98116
SHA: ${{ steps.plan.outputs.sha }}
99117
DRY_RUN: ${{ steps.plan.outputs.dry_run }}
118+
DRAFT: ${{ steps.plan.outputs.draft }}
100119
run: |
101120
set -euo pipefail
121+
if [ "$DRAFT" = true ]; then
122+
what="start release.yml for a draft release"
123+
else
124+
what="start release.yml and publish.yml"
125+
fi
102126
if [ "$DRY_RUN" = true ]; then
103-
echo "Dry run: would tag $TAG at $SHA and start release.yml and publish.yml"
127+
echo "Dry run: would tag $TAG at $SHA and $what"
104128
exit 0
105129
fi
106130
gh api "repos/$REPO/git/refs" -f ref="refs/tags/$TAG" -f sha="$SHA" >/dev/null
107-
gh workflow run release.yml -R "$REPO" --ref "$TAG"
108-
gh workflow run publish.yml -R "$REPO" --ref "$TAG"
131+
gh workflow run release.yml -R "$REPO" --ref "$TAG" -f draft="$DRAFT"
132+
if [ "$DRAFT" = true ]; then
133+
echo "::notice::$TAG is a draft release: add the upgrade notes and publish it to push the images and chart"
134+
else
135+
gh workflow run publish.yml -R "$REPO" --ref "$TAG"
136+
fi
109137
echo "Tagged $TAG at $SHA"

‎.github/workflows/publish.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ on:
55
push:
66
tags:
77
- "v*"
8+
# A draft release made by monthly-release.yml is published by hand. Releases
9+
# published with GITHUB_TOKEN don't start this.
10+
release:
11+
types: [published]
812

913
permissions: {}
1014

‎.github/workflows/release.yml‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ on:
66
- "v*"
77
# Started by monthly-release.yml on the tag it creates.
88
workflow_dispatch:
9+
inputs:
10+
draft:
11+
description: Create the release as a draft
12+
type: boolean
13+
default: false
914

1015
permissions:
1116
contents: write
@@ -33,6 +38,6 @@ jobs:
3338
- uses: goreleaser/goreleaser-action@a4f02ab5355a589de60d917a659ce617ed19b3de # v7.3.0
3439
with:
3540
version: "~> v2"
36-
args: release --clean
41+
args: release --clean${{ inputs.draft && ' --draft' || '' }}
3742
env:
3843
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

‎CONTRIBUTING.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,9 @@ Open an issue before a bigger change: anything that changes behaviour users rely
222222

223223
## Releases
224224

225-
A patch release is cut on the 1st of each month by `.github/workflows/monthly-release.yml` when `main` is green and something has merged since the last tag. It is skipped if a pull request labelled `breaking` was merged since then: label pull requests that change behaviour users rely on, and release those as a new minor version by hand.
225+
A release is cut on the 1st of each month by `.github/workflows/monthly-release.yml` when `main` is green and something has merged since the last tag. It is a patch release, or a new minor version if a pull request labelled `breaking` was merged since then (a new major version from 1.0 on), so label pull requests that change behaviour users rely on.
226+
227+
A patch release is published on its own. A breaking release is created as a draft, without images or a chart: write the upgrade notes in it and publish it, which starts `publish.yml` for the images and the chart. Until then the monthly run releases nothing.
226228

227229
Scheduled runs only report what they would release until the repository variable `MONTHLY_RELEASE` is set to `true`. The workflow can also be started by hand from the Actions tab, as a dry run by default.
228230

0 commit comments

Comments
 (0)