Repository navigation
111 lines (105 loc) · 5.7 KB
/
Copy pathrelease.yml
File metadata and controls
111 lines (105 loc) · 5.7 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
name: Release
# Runs semantic-release against every push to main. Almost every conventional-commit type triggers at least a patch release (see .releaserc.json's commit-analyzer releaseRules), so in practice this fires on nearly every push, stamping the collection version into galaxy.yml and the arc role's heartbeat, autoscaler, pull-secret-renewer and node-recovery image defaults, building the collection tarball, and, if a release was actually published, building and pushing all five container images (runner, heartbeat, autoscaler, pull-secret-renewer, node-recovery) tagged with the exact new version alongside floating major and latest tags on the same manifest.
#
# The release commit and tag are pushed over SSH with a write-enabled deploy key (secret RELEASE_DEPLOY_KEY): actions/checkout loads it for every later git command, and .releaserc.json's repositoryUrl is the SSH remote, so @semantic-release/git pushes with it. A deploy key is scoped to this one repository and can be listed as a ruleset bypass actor. It can't call the GitHub API, so the semantic-release process uses the ordinary secrets.GITHUB_TOKEN for creating the Release and uploading the collection tarball, which need no bypass.
#
# The release commit message carries [skip ci]: the image build happens in this same job/run immediately after semantic-release publishes, using the exact version it just decided, so there is nothing useful for a second, separately-triggered run of this workflow (or of ci.yml) to do against that commit - ci.yml's own lint jobs already ran against every commit before it reached main, and re-running them again against a commit that only changed a version stamp and a changelog is pure cost.
on:
push:
branches: [main]
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: read
jobs:
release:
name: Release
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: write # to push the release commit/tag and create the GitHub Release
issues: write # to comment on released issues
pull-requests: write # to comment on released pull requests
outputs:
published: ${{ steps.before.outputs.version != steps.after.outputs.version }}
version: ${{ steps.after.outputs.version }}
steps:
- uses: actions/checkout@v7
with:
# semantic-release analyses the full commit history since the last release.
fetch-depth: 0
ssh-key: ${{ secrets.RELEASE_DEPLOY_KEY }}
- uses: actions/setup-node@v7
with:
node-version: '22'
cache: npm
- run: npm ci
- name: Read pre-release version
id: before
run: echo "version=$(grep '^version:' galaxy.yml | awk '{print $2}')" >> "$GITHUB_OUTPUT"
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GALAXY_API_KEY: ${{ secrets.GALAXY_API_KEY }}
run: npx semantic-release
- name: Read post-release version
id: after
run: echo "version=$(grep '^version:' galaxy.yml | awk '{print $2}')" >> "$GITHUB_OUTPUT"
build-images:
name: Build and push (${{ matrix.name }})
needs: [release]
if: needs.release.outputs.published == 'true'
# GitHub-hosted, like the rest of this repository's CI, so a release never depends on the fleet it ships images for. QEMU builds the arm64 half of each multi-arch image.
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
matrix:
include:
- name: runner
dockerfile: Dockerfile
image: ghcr.io/exadev/github-runner
- name: heartbeat
dockerfile: heartbeat/Dockerfile
image: ghcr.io/exadev/github-runner-heartbeat
- name: autoscaler
dockerfile: autoscaler/Dockerfile
image: ghcr.io/exadev/github-runner-autoscaler
- name: pull-secret-renewer
dockerfile: pull-secret-renewer/Dockerfile
image: ghcr.io/exadev/github-runner-pull-secret-renewer
- name: node-recovery
dockerfile: node-recovery/Dockerfile
image: ghcr.io/exadev/github-runner-node-recovery
steps:
- uses: actions/checkout@v7
with:
# The tag this release just pushed, not main: an image carries the scripts the role runs from it, so it is built from exactly the commit whose stamped defaults name it, even if another commit has reached main since.
ref: v${{ needs.release.outputs.version }}
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Derive tags
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ matrix.image }}
# value overrides the automatic ref-derived tag: this workflow triggers on a push to main, not a tag push, so there is no git tag for these patterns to derive from on their own. needs.release.outputs.version is the exact version semantic-release just published (no leading v), so it's prefixed here to satisfy each pattern's own parser.
tags: |
type=semver,pattern={{version}},value=v${{ needs.release.outputs.version }}
type=semver,pattern={{major}},value=v${{ needs.release.outputs.version }}
type=raw,value=latest
- uses: docker/build-push-action@v6
with:
context: .
file: ${{ matrix.dockerfile }}
platforms: linux/arm64,linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}