This repository was archived by the owner on Aug 29, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
139 lines (122 loc) · 5.42 KB
/
Copy pathdocker-publish.yml
File metadata and controls
139 lines (122 loc) · 5.42 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
# main への push で本番用 Docker イメージをビルドし、GHCR へ公開する。
# 本番環境の更新はこれを pull するだけでよい(README「本番運用」参照)。
# ghcr.io/<owner>/cc-tasks … アプリ本体(Dockerfile の runtime ステージ)
#
# アーキごとに「そのアーキのネイティブランナー」で並列ビルドし、ダイジェストで
# push したものを最後の merge ジョブでマニフェスト(latest / sha-xxxxxxx)にまとめる。
# QEMU エミュレーションだと gradle / npm のビルドが極端に遅く不安定なため。
name: docker-publish
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
packages: write
env:
IMAGE: ghcr.io/${{ github.repository }}
jobs:
# アーキごとにネイティブランナーでビルドし、タグを付けずダイジェストで push する
build:
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
runner: ubuntu-latest
# arm64 はネイティブの arm ランナーでビルドする。
# 無料の ubuntu-24.04-arm ランナーは public リポジトリ限定。
- platform: linux/arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v7
- uses: docker/setup-buildx-action@v4
- uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.IMAGE }}
- id: build
uses: docker/build-push-action@v7
with:
context: .
target: runtime
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
# フッターのビルド番号用。コンテキストに .git を含めないため SHA はここから渡す
build-args: |
GIT_SHA=${{ github.sha }}
# タグではなくダイジェストで push する(マニフェストは merge ジョブで作る)
outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true
cache-from: type=gha,scope=app-${{ matrix.platform }}
cache-to: type=gha,mode=max,scope=app-${{ matrix.platform }}
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v7
with:
name: digests-${{ strategy.job-index }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
# 各アーキのダイジェストを 1 つのマニフェスト(latest / sha-xxxxxxx タグ)にまとめて push する。
# アーキが 1 つでも同じ流れで動く(マニフェストにそのアーキだけが載る)。
merge:
needs: [build]
runs-on: ubuntu-latest
steps:
- name: Download digests
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 }}
- id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.IMAGE }}
# latest(既定ブランチのみ)+ コミット SHA(sha-xxxxxxx)の 2 タグ。
# 障害時は SHA タグを指定して pull すれば戻せる(**残るのは直近 10 世代**。
# それより古い版は下の掃除で消える)。
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=sha
- name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create \
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.IMAGE }}@sha256:%s ' *)
- name: Inspect
run: docker buildx imagetools inspect ${{ env.IMAGE }}:${{ steps.meta.outputs.version }}
# 古い版を消して直近 10 世代だけ残す。
#
# 公開パッケージなので GHCR の容量・転送は無料枠を消費しないが、版は放っておくと
# 際限なく積み上がる(`latest` を付け替えても前の版は SHA タグ付きで残る)。
# 一覧が読めなくなるのと、どれが生きているか分からなくなるのを防ぐための掃除。
#
# **actions/delete-package-versions は使わない。** このリポジトリはマルチアーキで、
# 1 つのタグが manifest list + アーキごとの子イメージで構成される。あちらは
# 子イメージを「タグ無しの版」として消してしまい、残したはずのタグが壊れる。
# この action は manifest list を理解して親子まとめて扱う。
- name: 古いイメージを削除して直近 10 世代だけ残す
uses: dataaxiom/ghcr-cleanup-action@v1
with:
packages: cc-tasks
keep-n-tagged: 10
delete-untagged: true
token: ${{ secrets.GITHUB_TOKEN }}