Skip to content

v10.8.5 - Hotfix

v10.8.5 - Hotfix #13

name: "Build: Release Container"
on:
release:
types: [published]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
# `release: [published]` also fires for PRE-releases, and this job moves :latest — the tag
# every stable customer follows. Without this guard, ticking "set as a pre-release" in the
# GitHub UI would ship that build to the entire estate. Negation form (not `== false`) so a
# missing or blank value cannot evaluate truthy.
#
# Consequence: publishing a pre-release now produces NO image at all. The run still shows in
# the Actions tab as *skipped* - that is the signal that nothing shipped. If a release
# candidate channel is ever wanted, this is the hook point: build on prerelease, push
# :<version> plus a moving :prerelease, and keep :latest behind this same condition.
if: ${{ !github.event.release.prerelease }}
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Set lower case image name
run: echo "IMAGE_NAME_LC=${REPO,,}" >> $GITHUB_ENV
env:
REPO: ${{ github.repository }}
- name: Extract version from tag
id: version
run: |
# Strip 'v' prefix if present (e.g. v1.2.3 → 1.2.3)
TAG="${GITHUB_REF_NAME#v}"
echo "app_version=$TAG" >> $GITHUB_OUTPUT
echo "build_date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
# Persist the Next.js compile cache and yarn cache across runs (BuildKit
# cache mounts are not exported by type=gha). Separate key prefix and gha
# scope from dev/nightly — release builds a different Dockerfile/base image.
# Weekly rotation rather than per-run - see the note in dev-container.yml.
- name: Compute cache epoch
id: cache-epoch
run: echo "week=$(date -u +%Y-%W)" >> $GITHUB_OUTPUT
- name: Restore frontend build caches
id: build-cache
uses: actions/cache@v4
with:
path: |
yarn-cache
next-cache
key: cipp-frontend-cache-release-${{ hashFiles('frontend/yarn.lock') }}-${{ steps.cache-epoch.outputs.week }}
restore-keys: |
cipp-frontend-cache-release-${{ hashFiles('frontend/yarn.lock') }}-
cipp-frontend-cache-release-
- name: Inject build caches into BuildKit
uses: reproducible-containers/buildkit-cache-dance@v3.4.0
with:
builder: ${{ steps.buildx.outputs.name }}
cache-map: |
{
"yarn-cache": "/usr/local/share/.cache/yarn",
"next-cache": "/build/.next/cache"
}
skip-extraction: ${{ steps.build-cache.outputs.cache-hit }}
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: build/Dockerfile.release
push: true
cache-from: type=gha,scope=release
cache-to: type=gha,mode=max,scope=release
build-args: |
APP_VERSION=${{ steps.version.outputs.app_version }}
COMMIT_SHA=${{ github.sha }}
IMAGE_TAG=latest
BUILD_DATE=${{ steps.version.outputs.build_date }}
DOTNET_REGISTRY=${{ vars.DOTNET_REGISTRY || 'ghcr.io/cyberdrain' }}
# :latest is the stable channel every customer follows. Nothing conditional or
# experimental should ever be added here - gate it at the job `if` instead.
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}:latest
${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}:${{ steps.version.outputs.app_version }}
labels: |
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.description=CIPP - CIPP Next Generation
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.version=${{ steps.version.outputs.app_version }}
org.opencontainers.image.created=${{ steps.version.outputs.build_date }}