-
Notifications
You must be signed in to change notification settings - Fork 0
131 lines (118 loc) · 5.49 KB
/
Copy pathrelease.yml
File metadata and controls
131 lines (118 loc) · 5.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
name: Release
# commit -> release-please PR -> merge -> tag vX.Y.Z -> GoReleaser -> binaries + ghcr image
#
# One source of version truth: release-please owns the number, GoReleaser only
# builds what the tag says. Nothing here publishes on an ordinary push to main --
# a release is the act of merging the release PR.
on:
push:
branches: [main]
workflow_dispatch:
inputs:
rebuild-tag:
description: "Re-run GoReleaser against an existing tag (e.g. v0.1.0). Leave empty for a normal run."
required: false
type: string
permissions:
contents: read
jobs:
# Keeps a release PR open against main, and cuts the tag when it is merged.
release-please:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
outputs:
released: ${{ steps.rp.outputs.release_created }}
tag: ${{ steps.rp.outputs.tag_name }}
steps:
# A GitHub App token rather than the
# default GITHUB_TOKEN, because a tag pushed with GITHUB_TOKEN does not
# trigger other workflows -- so anything we later hang off the release tag
# would silently never fire. It also means the release PR and the tag are
# authored by the bot rather than github-actions[bot].
#
# RELEASE_APP_ID / RELEASE_APP_PRIVATE_KEY are organisation secrets, so
# this repo needs nothing added to use them.
- uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1
id: app-token
with:
app-id: ${{ secrets.RELEASE_APP_ID }}
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
# Without a checkout, release-please has no local history and backfills the
# file list for every commit through the API. Cheap on a small repo, but
# This step can die partway through and strand
# a release PR with a manifest conflict nothing heals. Give it the history.
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
- uses: googleapis/release-please-action@16a9c90856f42705d54a6fda1823352bdc62cf38 # v4
id: rp
with:
token: ${{ steps.app-token.outputs.token }}
config-file: release-please-config.json
manifest-file: .release-please-manifest.json
# Builds the tag. Normally that is the tag release-please just cut; rebuild-tag
# lets it re-run against an existing one, for when the publish failed but the
# tag is already out and burning a version number to retry would be silly.
goreleaser:
needs: release-please
if: needs.release-please.outputs.released == 'true' || inputs.rebuild-tag != ''
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: write # upload the release artifacts
packages: write # push to ghcr
steps:
# metsareleasebot, to publish the GitHub release.
- uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1
id: app-token
with:
app-id: ${{ secrets.RELEASE_APP_ID }}
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
# GoReleaser needs the tag release-please just pushed, and the history
# to build a changelog from.
fetch-depth: 0
ref: ${{ inputs.rebuild-tag || needs.release-please.outputs.tag }}
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5
with:
go-version: "1.25"
- uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3
# Log in to GHCR to pull the base image and push the recovery kit.
- uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Pin the recovery image's base by digest, not by the moving :18 tag.
#
# This is the difference between "v1.2.0 contains postgres-barman as it was
# when we released and tested it" and "v1.2.0 contains whatever
# postgres-barman happens to be today". In an incident you are betting on
# the former. Resolve it once, here, and stamp it into the build.
- name: Pin postgres-barman by digest
id: base
run: |
set -euo pipefail
digest=$(docker buildx imagetools inspect \
ghcr.io/metsaapp/postgres-barman:18 \
--format '{{.Manifest.Digest}}')
echo "image=ghcr.io/metsaapp/postgres-barman@${digest}" >> "$GITHUB_OUTPUT"
echo "recovery image will be built FROM ghcr.io/metsaapp/postgres-barman@${digest}"
# On a rebuild, skip the archives and checksums: they were published when the
# tag was first cut and GitHub rejects re-uploading an asset that already
# exists (422 already_exists). GoReleaser uploads archives BEFORE it pushes
# images, so that 422 is what stopped the recovery image ever reaching GHCR.
# Skipping them lets the rebuild get to the part that is actually missing.
- uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6
with:
version: "~> v2"
args: >-
release --clean
${{ inputs.rebuild-tag && '--skip=archive' || '' }}
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
POSTGRES_BARMAN_IMAGE: ${{ steps.base.outputs.image }}