-
Notifications
You must be signed in to change notification settings - Fork 66
147 lines (129 loc) · 5.24 KB
/
Copy pathdocker-publish.yml
File metadata and controls
147 lines (129 loc) · 5.24 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
name: Docker Publish
on:
push:
branches:
- main
tags:
- 'v*.*.*'
- 'v*.*.*-*'
pull_request:
env:
IMAGE: tapflow/tapflow
jobs:
# Build each architecture on its own native runner. arm64 used to build under
# QEMU emulation on an amd64 runner, where the native module compile could hang
# for hours; native runners remove the emulation entirely.
build:
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
runner: ubuntu-24.04
- platform: linux/arm64
runner: ubuntu-24.04-arm
env:
HAS_DOCKERHUB: ${{ secrets.DOCKERHUB_TOKEN != '' && secrets.DOCKERHUB_USERNAME != '' }}
steps:
- name: Prepare platform name
run: echo "PLATFORM_PAIR=${platform//\//-}" >> "$GITHUB_ENV"
env:
platform: ${{ matrix.platform }}
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Warn when Docker Hub credentials are missing
if: github.event_name != 'pull_request' && env.HAS_DOCKERHUB != 'true'
run: echo "::warning::DOCKERHUB_USERNAME/DOCKERHUB_TOKEN are not set — building the image for validation but skipping push."
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
if: github.event_name != 'pull_request' && env.HAS_DOCKERHUB == 'true'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract metadata (labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE }}
- name: Build image (push by digest when publishing)
id: build
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=${{ env.PLATFORM_PAIR }}
cache-to: type=gha,mode=max,scope=${{ env.PLATFORM_PAIR }}
# Publish: push a per-architecture image by digest (merged into a manifest
# list in the merge job). Otherwise (PR / no credentials): build for
# validation only, keeping just the cache.
outputs: ${{ (github.event_name != 'pull_request' && env.HAS_DOCKERHUB == 'true') && format('type=image,name={0},push-by-digest=true,name-canonical=true,push=true', env.IMAGE) || 'type=cacheonly' }}
- name: Export digest
if: github.event_name != 'pull_request' && env.HAS_DOCKERHUB == 'true'
run: |
mkdir -p "${{ runner.temp }}/digests"
digest="${{ steps.build.outputs.digest }}"
touch "${{ runner.temp }}/digests/${digest#sha256:}"
- name: Upload digest
if: github.event_name != 'pull_request' && env.HAS_DOCKERHUB == 'true'
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1
# Combine the per-architecture digests into a single multi-arch manifest list.
# Only runs for real publishes; PRs and credential-less builds validate only.
merge:
needs: build
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
env:
HAS_DOCKERHUB: ${{ secrets.DOCKERHUB_TOKEN != '' && secrets.DOCKERHUB_USERNAME != '' }}
steps:
- name: Note validation-only build
if: env.HAS_DOCKERHUB != 'true'
run: echo "::warning::No Docker Hub credentials — per-architecture validation builds succeeded, nothing to publish."
- name: Download digests
if: env.HAS_DOCKERHUB == 'true'
uses: actions/download-artifact@v4
with:
path: ${{ runner.temp }}/digests
pattern: digests-*
merge-multiple: true
- name: Set up Docker Buildx
if: env.HAS_DOCKERHUB == 'true'
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
if: env.HAS_DOCKERHUB == 'true'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract metadata (tags) for Docker
id: meta
if: env.HAS_DOCKERHUB == 'true'
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE }}
tags: |
type=edge,branch=main
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha
- name: Create manifest list and push
if: env.HAS_DOCKERHUB == 'true'
working-directory: ${{ runner.temp }}/digests
run: |
# shellcheck disable=SC2046 # intentional split: expand -t flags and per-digest refs
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.IMAGE }}@sha256:%s ' *)
- name: Inspect image
if: env.HAS_DOCKERHUB == 'true'
run: docker buildx imagetools inspect ${{ env.IMAGE }}:${{ steps.meta.outputs.version }}