-
Notifications
You must be signed in to change notification settings - Fork 18
198 lines (177 loc) · 6.67 KB
/
Copy pathdocker-engine.yml
File metadata and controls
198 lines (177 loc) · 6.67 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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
name: docker-engine
# Builds and publishes the ps5upload-engine Docker image to GHCR.
# Tag pushes (v*) publish a multi-arch (amd64 + arm64) manifest.
# PRs that touch engine/ get a build-only smoke-check (no push).
#
# Manual re-run (e.g. after an Actions outage wedges a tag-push run):
# gh workflow run docker-engine.yml -f tag=v3.3.16
on:
push:
tags: ['v*']
pull_request:
paths: ['engine/**', '.github/workflows/docker-engine.yml']
workflow_dispatch:
inputs:
tag:
description: "Release tag to publish (e.g. v3.3.16). Must already exist."
required: true
# Least privilege at the top: read-only by default. Only the jobs that actually
# push to GHCR (build, merge) opt into packages:write below — the PR `verify`
# job inherits read-only and never gets a write-capable token.
permissions:
contents: read
concurrency:
group: docker-engine-${{ github.event.inputs.tag || github.ref }}
cancel-in-progress: true
jobs:
# ── PR gate: build amd64, no push ──────────────────────────────────────────
verify:
if: github.event_name == 'pull_request'
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
- uses: docker/setup-buildx-action@v4
- uses: docker/build-push-action@v7
with:
context: engine
file: engine/Dockerfile
platforms: linux/amd64
push: false
cache-from: type=gha
cache-to: type=gha,mode=max
# ── Resolve + validate the tag ONCE, hand the trusted values to build/merge ─
# Centralizing this means the tag is regex-validated before it ever reaches a
# checkout `ref:` (no ref injection from a hand-typed workflow_dispatch input),
# and the lowercased image name is computed once via the safe env pattern
# instead of interpolating ${{ github.repository_owner }} into shell.
resolve:
if: github.event_name != 'pull_request'
runs-on: ubuntu-24.04
outputs:
tag: ${{ steps.t.outputs.tag }}
version: ${{ steps.t.outputs.version }}
major_minor: ${{ steps.t.outputs.major_minor }}
image: ${{ steps.t.outputs.image }}
steps:
- name: Validate tag + derive image name
id: t
env:
INPUT_TAG: ${{ github.event.inputs.tag || github.ref_name }}
OWNER: ${{ github.repository_owner }}
run: |
raw_tag="$INPUT_TAG"
if ! printf '%s' "$raw_tag" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+([-+._A-Za-z0-9]*)?$'; then
echo "::error::Refusing to proceed: '$raw_tag' is not a valid version tag"
exit 1
fi
version="${raw_tag#v}"
owner_lc="$(printf '%s' "$OWNER" | tr '[:upper:]' '[:lower:]')"
{
echo "tag=$raw_tag"
echo "version=$version"
echo "major_minor=${version%.*}"
echo "image=ghcr.io/${owner_lc}/ps5upload-engine"
} >> "$GITHUB_OUTPUT"
# ── Per-arch native build, push by digest (no tag yet) ─────────────────────
build:
needs: resolve
if: github.event_name != 'pull_request'
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
include:
- { os: ubuntu-24.04, platform: linux/amd64 }
- { os: ubuntu-24.04-arm, platform: linux/arm64 }
env:
IMAGE: ${{ needs.resolve.outputs.image }}
steps:
- uses: actions/checkout@v7
with:
ref: ${{ needs.resolve.outputs.tag }}
- name: Prepare environment
env:
PLATFORM: ${{ matrix.platform }}
run: echo "PLATFORM_PAIR=$(printf '%s' "$PLATFORM" | tr '/' '-')" >> "$GITHUB_ENV"
- uses: docker/setup-buildx-action@v4
- uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@v6
id: meta
with:
images: ${{ env.IMAGE }}
- name: Build and push by digest
id: push
uses: docker/build-push-action@v7
with:
context: engine
file: engine/Dockerfile
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true
cache-from: type=gha,scope=${{ env.PLATFORM_PAIR }}
cache-to: type=gha,mode=max,scope=${{ env.PLATFORM_PAIR }}
- name: Export digest
env:
DIGEST: ${{ steps.push.outputs.digest }}
run: |
mkdir -p /tmp/digests
touch "/tmp/digests/${DIGEST#sha256:}"
- uses: actions/upload-artifact@v7
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
# ── Merge per-arch digests into a multi-arch manifest ──────────────────────
merge:
needs: [resolve, build]
if: github.event_name != 'pull_request'
runs-on: ubuntu-24.04
permissions:
contents: read
packages: write
env:
IMAGE: ${{ needs.resolve.outputs.image }}
VERSION: ${{ needs.resolve.outputs.version }}
MAJOR_MINOR: ${{ needs.resolve.outputs.major_minor }}
steps:
- uses: actions/download-artifact@v8
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- uses: docker/setup-buildx-action@v4
- uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@v6
id: meta
with:
images: ${{ env.IMAGE }}
tags: |
type=raw,value=${{ env.VERSION }}
type=raw,value=${{ env.MAJOR_MINOR }}
type=raw,value=latest
- name: Create and push multi-arch manifest
working-directory: /tmp/digests
env:
META_JSON: ${{ steps.meta.outputs.json }}
run: |
# Word-splitting here is intentional: the jq output expands to
# `-t tagA -t tagB ...` and the printf to space-separated
# `image@sha256:<digest>` operands, each a distinct argv entry.
# shellcheck disable=SC2046
docker buildx imagetools create \
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$META_JSON") \
$(printf "${IMAGE}@sha256:%s " *)
- name: Inspect manifest
run: docker buildx imagetools inspect "${IMAGE}:${VERSION}"