Files
reader/.github/workflows/release.yml
T

124 lines
4.0 KiB
YAML

# Release the single-container image (server + web) to Docker Hub for amd64 and arm64.
#
# push to main -> hectorqin/reader-pro:main, :sha-<short>
# tag v1.2.3 -> hectorqin/reader-pro:1.2.3, :1.2, :latest, :sha-<short>
# manual run -> tags for the chosen ref, as above
#
# CI (ci.yml) runs first; nothing is published from a red build. Each architecture
# is built on its own native runner — the arm64 image under QEMU would run npm ci
# and the Vite build emulated, which is many times slower — and pushed by digest,
# then one job stitches the digests into the multi-arch tags.
#
# Needs repository secrets DOCKER_USERNAME and DOCKER_PASSWORD (a Docker Hub
# password or access token with read/write on hectorqin/reader-pro).
name: Release
on:
push:
branches: [main]
tags: ['v*']
workflow_dispatch:
permissions:
contents: read
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
env:
IMAGE: hectorqin/reader-pro
jobs:
ci:
uses: ./.github/workflows/ci.yml
build:
name: Image · ${{ matrix.platform }}
needs: ci
strategy:
fail-fast: true
matrix:
include:
- platform: linux/amd64
runner: ubuntu-24.04
- platform: linux/arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
steps:
- name: Platform slug
run: echo "PLATFORM_PAIR=${PLATFORM//\//-}" >> "$GITHUB_ENV"
env:
PLATFORM: ${{ matrix.platform }}
- uses: actions/checkout@v5
- id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE }}
- uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- uses: docker/setup-buildx-action@v3
- id: build
uses: docker/build-push-action@v6
with:
context: .
file: server/Dockerfile
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true
cache-from: type=gha,scope=${{ env.PLATFORM_PAIR }}
cache-to: type=gha,mode=max,scope=${{ env.PLATFORM_PAIR }}
- name: Record digest
run: |
mkdir -p "$RUNNER_TEMP/digests"
touch "$RUNNER_TEMP/digests/${DIGEST#sha256:}"
env:
DIGEST: ${{ steps.build.outputs.digest }}
- uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1
publish:
name: Image · multi-arch tags
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
path: ${{ runner.temp }}/digests
pattern: digests-*
merge-multiple: true
- id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha
flavor: |
latest=${{ startsWith(github.ref, 'refs/tags/v') }}
- uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- uses: docker/setup-buildx-action@v3
- name: Create manifest list and push
working-directory: ${{ runner.temp }}/digests
run: |
tags=()
while read -r tag; do tags+=(-t "$tag"); done < <(jq -r '.tags[]' <<< "$DOCKER_METADATA_OUTPUT_JSON")
refs=()
for digest in *; do refs+=("$IMAGE@sha256:$digest"); done
docker buildx imagetools create "${tags[@]}" "${refs[@]}"
- name: Inspect
run: docker buildx imagetools inspect "$IMAGE:$VERSION"
env:
VERSION: ${{ steps.meta.outputs.version }}