ci: publish the frontend image from the release chain

backend-release.yml creates the GitHub release with GITHUB_TOKEN, and GitHub
never starts workflows from events that token produces, so the frontend image
workflow's `release: published` trigger does not fire for a version bump on
main. It was the only publish workflow left out of the workflow_call fix, so
the next bump would push arc53/docsgpt:<version> and move docsgpt:latest while
docsgpt-fe stayed on the previous release — and the standalone compose file
defaults both images to latest.

Give cife.yml a workflow_call trigger with a version input (same shape as
ci.yml) and call it from backend-release.yml after the release is created. The
release trigger stays for releases created by hand.

While here, bring it in line with ci.yml: run the publishing jobs in the
docker-hub environment, tag from the public arc53 namespace instead of the
login secret, pin the actions by digest, add the OCI version label, and drop
the QEMU step that only ran on the native arm64 runner.
This commit is contained in:
Alex committed 2026-09-12 20:28:58 +01:00
1 parent b2a5480dab
commit 01dfe473d3
2 files changed
+90 -37

No files matched your search

+15 -1
View File
@@ -1,7 +1,8 @@
name: Backend release
# A version bump on main tags the commit, creates the GitHub release, then
# publishes the Docker images and the PyPI package by calling those workflows.
# publishes the backend and frontend Docker images and the PyPI package by
# calling those workflows.
# The release is created with GITHUB_TOKEN, and GitHub never starts workflows
# from events that token produces, so the `release: published` triggers on the
# publish workflows would not fire (0.18.0 got no images that way). Releases
@@ -109,6 +110,19 @@ jobs:
contents: write # release-assets attaches the compose file to the release
packages: write
frontend:
needs: release
if: needs.release.outputs.created == 'true'
uses: $/.github/workflows/cife.yml
with:
version: ${{ needs.release.outputs.version }}
secrets:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
permissions:
contents: read
packages: write
pypi:
needs: release
if: needs.release.outputs.created == 'true'
+75 -36
View File
@@ -1,12 +1,43 @@
name: Build and push DocsGPT-FE Docker image
# Runs for a release created by hand (the release event), or called by the
# backend-release workflow with the version it just tagged: GitHub never starts
# workflows from events GITHUB_TOKEN produces, so a bot-created release does not
# fire the release trigger on its own.
on:
release:
types: [published]
workflow_call:
inputs:
version:
description: Release tag to build and push (the images are tagged with it)
type: string
required: true
secrets:
DOCKER_USERNAME:
required: true
DOCKER_PASSWORD:
required: true
permissions:
contents: read
env:
# The tag being published: passed in by the caller, or the release's own.
RELEASE_TAG: ${{ inputs.version || github.event.release.tag_name }}
jobs:
build:
if: github.repository == 'arc53/DocsGPT'
# Publishing jobs run in a GitHub Actions environment so the registry
# credentials can be scoped to it and protection rules (required reviewers,
# branch restrictions) applied in the repository settings.
environment: docker-hub
env:
# Public namespace the compose files pull from; the login secret only
# authenticates the push.
DOCKERHUB_NAMESPACE: arc53
strategy:
matrix:
include:
@@ -21,92 +52,100 @@ jobs:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Set up QEMU # Only needed for emulation, not for native arm64 builds
if: matrix.platform == 'linux/arm64'
uses: docker/setup-qemu-action@v3
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
persist-credentials: false
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
with:
driver: docker-container
install: true
- name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to ghcr.io
uses: docker/login-action@v3
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Image metadata (OCI labels)
id: meta
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
with:
images: |
${{ env.DOCKERHUB_NAMESPACE }}/docsgpt-fe
ghcr.io/${{ github.repository_owner }}/docsgpt-fe
labels: |
org.opencontainers.image.title=DocsGPT-FE
org.opencontainers.image.version=${{ env.RELEASE_TAG }}
- name: Build and push platform-specific images
uses: docker/build-push-action@v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
file: './frontend/Dockerfile'
platforms: ${{ matrix.platform }}
context: ./frontend
push: true
tags: |
${{ secrets.DOCKER_USERNAME }}/docsgpt-fe:${{ github.event.release.tag_name }}-${{ matrix.suffix }}
ghcr.io/${{ github.repository_owner }}/docsgpt-fe:${{ github.event.release.tag_name }}-${{ matrix.suffix }}
${{ env.DOCKERHUB_NAMESPACE }}/docsgpt-fe:${{ env.RELEASE_TAG }}-${{ matrix.suffix }}
ghcr.io/${{ github.repository_owner }}/docsgpt-fe:${{ env.RELEASE_TAG }}-${{ matrix.suffix }}
labels: ${{ steps.meta.outputs.labels }}
provenance: false
sbom: false
cache-from: type=registry,ref=${{ secrets.DOCKER_USERNAME }}/docsgpt-fe:latest
cache-from: type=registry,ref=${{ env.DOCKERHUB_NAMESPACE }}/docsgpt-fe:latest
cache-to: type=inline
manifest:
if: github.repository == 'arc53/DocsGPT'
# Publishing jobs run in a GitHub Actions environment so the registry
# credentials can be scoped to it and protection rules (required reviewers,
# branch restrictions) applied in the repository settings.
environment: docker-hub
env:
# Public namespace the compose files pull from; the login secret only
# authenticates the push.
DOCKERHUB_NAMESPACE: arc53
needs: build
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
with:
driver: docker-container
install: true
- name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to ghcr.io
uses: docker/login-action@v3
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create and push manifest for DockerHub
- name: Create and push multi-arch manifests
env:
TAG: ${{ env.RELEASE_TAG }}
run: |
set -e
docker manifest create ${{ secrets.DOCKER_USERNAME }}/docsgpt-fe:${{ github.event.release.tag_name }} \
--amend ${{ secrets.DOCKER_USERNAME }}/docsgpt-fe:${{ github.event.release.tag_name }}-amd64 \
--amend ${{ secrets.DOCKER_USERNAME }}/docsgpt-fe:${{ github.event.release.tag_name }}-arm64
docker manifest push ${{ secrets.DOCKER_USERNAME }}/docsgpt-fe:${{ github.event.release.tag_name }}
docker manifest create ${{ secrets.DOCKER_USERNAME }}/docsgpt-fe:latest \
--amend ${{ secrets.DOCKER_USERNAME }}/docsgpt-fe:${{ github.event.release.tag_name }}-amd64 \
--amend ${{ secrets.DOCKER_USERNAME }}/docsgpt-fe:${{ github.event.release.tag_name }}-arm64
docker manifest push ${{ secrets.DOCKER_USERNAME }}/docsgpt-fe:latest
- name: Create and push manifest for ghcr.io
run: |
set -e
docker manifest create ghcr.io/${{ github.repository_owner }}/docsgpt-fe:${{ github.event.release.tag_name }} \
--amend ghcr.io/${{ github.repository_owner }}/docsgpt-fe:${{ github.event.release.tag_name }}-amd64 \
--amend ghcr.io/${{ github.repository_owner }}/docsgpt-fe:${{ github.event.release.tag_name }}-arm64
docker manifest push ghcr.io/${{ github.repository_owner }}/docsgpt-fe:${{ github.event.release.tag_name }}
docker manifest create ghcr.io/${{ github.repository_owner }}/docsgpt-fe:latest \
--amend ghcr.io/${{ github.repository_owner }}/docsgpt-fe:${{ github.event.release.tag_name }}-amd64 \
--amend ghcr.io/${{ github.repository_owner }}/docsgpt-fe:${{ github.event.release.tag_name }}-arm64
docker manifest push ghcr.io/${{ github.repository_owner }}/docsgpt-fe:latest
for repo in "$DOCKERHUB_NAMESPACE/docsgpt-fe" "ghcr.io/${{ github.repository_owner }}/docsgpt-fe"; do
for name in "$TAG" latest; do
docker manifest create "$repo:$name" \
--amend "$repo:$TAG-amd64" \
--amend "$repo:$TAG-arm64"
docker manifest push "$repo:$name"
done
done