-
Notifications
You must be signed in to change notification settings - Fork 5
105 lines (96 loc) · 4.02 KB
/
publish-docker.yml
File metadata and controls
105 lines (96 loc) · 4.02 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
name: publish-docker
# Builds, tests, and publishes the socket-basics image to GHCR and Docker Hub.
#
# Flow: resolve-version → build-test-push → create-release
#
# Tag convention:
# v2.0.0 — immutable exact release (floating major tags intentionally not published)
# See docs/github-action.md → "Pinning strategies" for the full rationale.
#
# Required repository secrets:
# DOCKERHUB_USERNAME — Docker Hub account name
# DOCKERHUB_TOKEN — Docker Hub access token (read/write)
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
workflow_dispatch:
inputs:
tag:
description: "Full git tag to publish (e.g. v2.0.0 for new releases, 1.1.3 for old). Must exist in the repo."
required: true
# Default: deny everything. Each job below grants only what it needs.
permissions:
contents: read
concurrency:
group: publish-docker-${{ github.ref }}
cancel-in-progress: false # never cancel an in-flight publish
jobs:
# ── Job 1: Resolve version ─────────────────────────────────────────────────
# Computes a clean semver string (no v prefix) consumed by downstream jobs.
resolve-version:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.clean }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref }}
persist-credentials: false
- name: 🏷️ Resolve version
id: version
env:
EVENT_NAME: ${{ github.event_name }}
INPUT_TAG: ${{ inputs.tag }}
REF_NAME: ${{ github.ref_name }}
run: |
if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
CLEAN="$INPUT_TAG" # full tag as provided (e.g. 1.1.3 or v2.0.0)
else
CLEAN="$REF_NAME" # e.g. v2.0.0
fi
CLEAN="${CLEAN#v}" # strip leading v if present → 2.0.0 or 1.1.3
echo "clean=$CLEAN" >> "$GITHUB_OUTPUT"
# ── Job 2: Build → test → push ─────────────────────────────────────────────
# Delegates all Docker steps to the reusable _docker-pipeline workflow.
build-test-push:
name: publish (socket-basics)
needs: resolve-version
permissions:
contents: read
packages: write # push images to GHCR
uses: ./.github/workflows/_docker-pipeline.yml
with:
name: socket-basics
dockerfile: Dockerfile
context: .
check_set: main
push: true
tag_push: ${{ github.ref_type == 'tag' }}
version: ${{ needs.resolve-version.outputs.version }}
secrets:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
# ── Job 3: Create GitHub release ───────────────────────────────────────────
# Runs once after the image is successfully pushed (not for workflow_dispatch
# re-publishes — those don't create new releases).
# Generates categorised release notes from merged PR labels (.github/release.yml).
# CHANGELOG updates are intentionally human-authored in the release PR so this
# workflow never needs to push commits to the protected default branch.
create-release:
needs: [resolve-version, build-test-push]
if: github.ref_type == 'tag'
permissions:
contents: write # create GitHub release
runs-on: ubuntu-latest
steps:
- name: 📝 Create GitHub release with auto-generated notes
env:
GH_TOKEN: ${{ github.token }}
REF_NAME: ${{ github.ref_name }}
run: |
gh release create "$REF_NAME" \
--title "$REF_NAME" \
--generate-notes \
--verify-tag \
|| echo "Release already exists (re-run scenario) — skipping creation"