forked from constverum/ProxyBroker
-
-
Notifications
You must be signed in to change notification settings - Fork 139
162 lines (153 loc) · 7.55 KB
/
Copy pathdocker-publish.yml
File metadata and controls
162 lines (153 loc) · 7.55 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
name: Publish Docker Image
# Triggers:
#
# - release: published
# Full tag set (:VERSION, :major.minor, :major, :latest) - the
# canonical "ship a new version" path. Same trigger as
# python-publish.yml, so one release ships PyPI + Docker together.
#
# - workflow_dispatch
# Manual trigger. Two modes depending on inputs:
#
# - With `version` input (e.g. `--field version=2.0.0b2`):
# Publishes the full tag set (:VERSION, :major.minor, :major,
# :latest) using the supplied version string. Builds whatever
# code is at the dispatched ref. Use this for retroactive
# publishes when the release event didn't fire docker-publish
# (e.g. workflow file added after the release was created),
# or to force-republish a specific version.
#
# - Without `version` input:
# Publishes :manual-<timestamp> only. Useful for smoke-testing
# the workflow on master HEAD without affecting any version tags.
on:
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: "Version to publish (e.g. 2.0.0b2). Leave empty for a smoke-test build tagged :manual-<timestamp>."
required: false
default: ""
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write # required to push to ghcr.io
steps:
- name: Check out source
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# ref omitted: uses GITHUB_REF, which for both `release` events
# and `workflow_dispatch` is the ref that triggered the workflow.
# Multi-arch builds need QEMU for cross-compilation under buildx.
- name: Set up QEMU
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
# Buildx is the modern docker builder; supports multi-platform output.
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
# Docker Hub login. Token must be a Hub access token (NOT a password)
# scoped to the proxybroker2 repository for least-privilege.
- name: Log in to Docker Hub
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# GHCR login + push are temporarily disabled. Tracking #206.
# Reason: the GHCR package `ghcr.io/bluet/proxybroker2` doesn't
# exist yet, and `permissions: packages: write` + the OCI source
# label (added in PR #205) aren't sufficient to bootstrap a
# brand-new package from a workflow's GITHUB_TOKEN - the first
# push gets 403 Forbidden. Pre-creating the package once via the
# GHCR web UI (or pushing once with a maintainer PAT scoped to
# write:packages) unblocks subsequent workflow pushes.
# Re-enable by uncommenting the two GHCR-related blocks below
# AND restoring `ghcr.io/bluet/proxybroker2` in the `images:`
# list of the metadata-action step.
#
# - name: Log in to GitHub Container Registry
# uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
# with:
# registry: ghcr.io
# username: ${{ github.actor }}
# password: ${{ secrets.GITHUB_TOKEN }}
# Compute version components for manual workflow_dispatch with version input.
# Strips any leading 'v', then derives major / major.minor by removing
# PEP 440 prerelease/post suffixes (a / b / rc / .dev / .post). Only runs
# when version input is non-empty.
- name: Compute version components (manual dispatch)
id: ver
if: github.event_name == 'workflow_dispatch' && inputs.version != ''
env:
INPUT_VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
version="${INPUT_VERSION#v}"
# Strip prerelease/post suffix to get bare M.N.P
base=$(echo "$version" | sed -E 's/(a|b|rc|\.dev|\.post)[0-9]+.*$//')
major="${base%%.*}"
major_minor=$(echo "$base" | cut -d. -f1-2)
{
echo "version=$version"
echo "major=$major"
echo "major_minor=$major_minor"
} >> "$GITHUB_OUTPUT"
# Tag strategy:
#
# `:VERSION` (e.g. `:2.0.0b2`) - exact version pin.
# Uses type=pep440 (NOT type=semver) because this project
# versions in PEP 440 form (`2.0.0b2`), not SemVer
# (`2.0.0-beta.2`). PyPI mandates PEP 440 - we follow.
#
# `:major.minor` / `:major` / `:latest` - floating aliases.
# Advanced on every release event AND on workflow_dispatch
# with version input. Type=match is used for release events
# (regex on git tag) because metadata-action's pep440/semver
# parsers deliberately hold floating aliases back for
# prereleases - we want them to advance for prereleases too:
# this project has been in beta for a year, and locking
# floating tags to stable releases would freeze them on
# `v2.0.0b1` (May 2025) until 2.0.0 ships.
#
# `:manual-<timestamp>` - per-build tag for workflow_dispatch
# without a version input. Smoke-test builds.
#
# `flavor: latest=false` disables metadata-action's automatic
# `:latest` for the highest stable version. We control `:latest`
# explicitly above so it only fires when we explicitly say so.
#
# Acknowledged side-effect: if a future patch is released for an
# OLDER version line (e.g. 1.5.1 after 2.0.0), floating tags would
# advance backward. Not maintaining old version lines today;
# restore `flavor: latest=auto` if that ever changes.
- name: Extract image metadata (tags, labels)
id: meta
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
with:
images: |
bluet/proxybroker2
flavor: |
latest=false
tags: |
type=pep440,pattern={{version}},enable=${{ github.event_name == 'release' }}
type=match,pattern=v(\d+\.\d+),group=1,enable=${{ github.event_name == 'release' }}
type=match,pattern=v(\d+),group=1,enable=${{ github.event_name == 'release' }}
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
type=raw,value=${{ steps.ver.outputs.version }},enable=${{ steps.ver.outputs.version != '' }}
type=raw,value=${{ steps.ver.outputs.major_minor }},enable=${{ steps.ver.outputs.major_minor != '' }}
type=raw,value=${{ steps.ver.outputs.major }},enable=${{ steps.ver.outputs.major != '' }}
type=raw,value=latest,enable=${{ github.event_name == 'workflow_dispatch' && inputs.version != '' }}
type=raw,value=manual-{{date 'YYYYMMDDHHmmss'}},enable=${{ github.event_name == 'workflow_dispatch' && inputs.version == '' }}
# Build once, push to both registries. cache-from/to use the GitHub
# Actions cache backend so a second run on the same code reuses
# layers and finishes in seconds instead of minutes.
- name: Build and push
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max