-
-
Notifications
You must be signed in to change notification settings - Fork 0
111 lines (100 loc) · 4.32 KB
/
Copy pathcontainer-publish.yml
File metadata and controls
111 lines (100 loc) · 4.32 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
# SPDX-License-Identifier: MPL-2.0
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
#
# Container Publish workflow — builds and pushes the container image to
# GitHub Container Registry (ghcr.io) and optionally Docker Hub on version
# tag push (v*) or manual dispatch. Uses Podman + the multi-stage
# Containerfile in container/.
name: Container Publish
on:
push:
tags:
- 'v*'
workflow_dispatch:
permissions: read-all
jobs:
build-and-push:
name: Build & Push Container Image
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
packages: write
id-token: write # mint the OIDC token the attestation is signed with
attestations: write # write the build-provenance attestation (the "claim")
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Extract version metadata
id: meta
run: |
VERSION="${GITHUB_REF_NAME#v}"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "image=ghcr.io/${{ github.repository }}" >> "$GITHUB_OUTPUT"
- name: Check Docker Hub credentials
id: dockerhub
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
run: |
if [ -n "$DOCKERHUB_USERNAME" ]; then
echo "available=true" >> "$GITHUB_OUTPUT"
else
echo "available=false" >> "$GITHUB_OUTPUT"
fi
- name: Log in to GitHub Container Registry
env:
REGISTRY_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REGISTRY_USER: ${{ github.actor }}
run: |
echo "$REGISTRY_TOKEN" | \
podman login ghcr.io -u "$REGISTRY_USER" --password-stdin
- name: Log in to Docker Hub
if: steps.dockerhub.outputs.available == 'true'
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
run: |
echo "$DOCKERHUB_TOKEN" | \
podman login docker.io -u "$DOCKERHUB_USERNAME" --password-stdin
- name: Build container image
run: |
podman build \
--file container/Containerfile \
--tag "${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.version }}" \
--tag "${{ steps.meta.outputs.image }}:latest" \
--label "org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}" \
--label "org.opencontainers.image.description=Bundle of Joy MCP Server — 112 cartridges (111 Zig FFI + 1 JS)" \
--label "org.opencontainers.image.licenses=MPL-2.0" \
--label "org.opencontainers.image.version=${{ steps.meta.outputs.version }}" \
.
- name: Push to GitHub Container Registry
id: push
run: |
# --digestfile makes podman write the digest of the pushed manifest;
# this is the real sha256 the attestation must bind to.
podman push --digestfile=/tmp/ghcr-digest \
"${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.version }}"
podman push "${{ steps.meta.outputs.image }}:latest"
echo "digest=$(cat /tmp/ghcr-digest)" >> "$GITHUB_OUTPUT"
# GitHub native artifact attestation (build provenance) for the pushed
# image — a signed, verifiable claim binding the image digest to this
# build. Verify with:
# gh attest verify oci://ghcr.io/${{ github.repository }}:<tag> \
# --repo ${{ github.repository }}
- name: Attest container provenance
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2
with:
subject-name: ghcr.io/${{ github.repository }}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
- name: Tag and push to Docker Hub
if: steps.dockerhub.outputs.available == 'true'
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
run: |
VERSION="${{ steps.meta.outputs.version }}"
SRC="${{ steps.meta.outputs.image }}"
DST="docker.io/$DOCKERHUB_USERNAME/boj-server"
podman tag "$SRC:$VERSION" "$DST:$VERSION"
podman tag "$SRC:latest" "$DST:latest"
podman push "$DST:$VERSION"
podman push "$DST:latest"