Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Publish Docker Image to Registries | |
on: | |
release: | |
types: | |
- published # Runs only when a GitHub Release is published | |
workflow_dispatch: # Allows for manual execution | |
env: | |
ALPINE_VERSION: "23-alpine" | |
DEBIAN_VERSION: "23-slim" | |
# Registry URLs | |
DOCKERHUB_REGISTRY: docker.io | |
GITHUB_REGISTRY: ghcr.io | |
# Docker Hub image name (using Docker Hub username) | |
DOCKERHUB_IMAGE_NAME: ${{ secrets.DOCKER_USERNAME }}/${{ github.event.repository.name }} | |
# GitHub image name (formatted as `account/repo`) | |
GITHUB_IMAGE_NAME: ${{ github.repository }} | |
jobs: | |
check-lockfile: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
- name: Setup Node.js | |
uses: actions/setup-node@v4 | |
with: | |
node-version: '20' # Adjust as needed | |
- name: Install dependencies | |
run: npm ci | |
- name: Check for lock-file changes | |
run: | | |
git diff --exit-code package-lock.json || ( | |
echo "🫥 package-lock.json is outdated or missing. Please run 'npm install' and commit the updated lockfile." | |
exit 1 | |
) | |
build-and-push-to-registries: | |
needs: check-lockfile # Runs only after `check-lockfile` completes successfully | |
name: Push Docker images to Docker Hub and GitHub Container Registry | |
strategy: | |
matrix: | |
variant: [alpine, debian] | |
runs-on: ubuntu-latest | |
permissions: | |
actions: write | |
contents: write | |
packages: write | |
# This is used to complete the identity challenge with sigstore/fulcio when running outside of PRs. | |
id-token: write | |
steps: | |
- name: Check out the repo | |
uses: actions/[email protected] | |
# Install the cosign tool (except on PR) | |
# https://github.com/sigstore/cosign-installer | |
- name: Install cosign | |
if: github.event_name != 'pull_request' | |
uses: sigstore/[email protected] | |
with: | |
cosign-release: 'v2.2.4' | |
# Set up BuildKit Docker container builder to be able to build multi-platform images and export cache | |
# https://github.com/docker/setup-buildx-action | |
- name: Set up Docker Buildx | |
uses: docker/[email protected] | |
# Log in to Docker Hub (except on PR) | |
- name: Log in to Docker Hub | |
if: github.event_name != 'pull_request' | |
uses: docker/[email protected] | |
with: | |
username: ${{ secrets.DOCKER_USERNAME }} | |
password: ${{ secrets.DOCKER_PASSWORD }} | |
# Log in to GitHub Container Registry (except on PR) | |
- name: Log in to GitHub Container Registry | |
if: github.event_name != 'pull_request' | |
uses: docker/[email protected] | |
with: | |
registry: ${{ env.GITHUB_REGISTRY }} | |
username: ${{ github.repository_owner }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
# Combined metadata extraction for both registries | |
- name: Extract Docker metadata | |
id: meta | |
uses: docker/[email protected] | |
with: | |
images: | | |
${{ env.DOCKERHUB_IMAGE_NAME }} | |
${{ env.GITHUB_REGISTRY }}/${{ env.GITHUB_IMAGE_NAME }} | |
tags: | | |
# Tag non-main branches (...for Alpine variant, add suffix) | |
type=ref,event=branch,suffix=-${{ matrix.variant }},enable=${{ matrix.variant == 'alpine' && github.ref != 'refs/heads/main' }} | |
type=ref,event=branch,enable=${{ matrix.variant == 'debian' && github.ref != 'refs/heads/main' }} | |
# Tag matrix.variant (Alpine) releases as version (1.0.0), major.minor (1.0), major (1), and matrix.variant (alpine) | |
type=semver,pattern={{version}},suffix=-${{ matrix.variant }},enable=${{ matrix.variant == 'alpine' }} | |
type=semver,pattern={{major}}.{{minor}},suffix=-${{ matrix.variant }},enable=${{ matrix.variant == 'alpine' }} | |
type=semver,pattern={{major}},suffix=-${{ matrix.variant }},enable=${{ matrix.variant == 'alpine' }} | |
type=raw,value=${{ matrix.variant }},enable=${{ matrix.variant == 'alpine' && github.ref == 'refs/heads/main' }} | |
# Tag default (Debian) releases as version (1.0.0), major.minor (1.0), major (1), and latest | |
type=semver,pattern={{version}},enable=${{ matrix.variant == 'debian' }} | |
type=semver,pattern={{major}}.{{minor}},enable=${{ matrix.variant == 'debian' }} | |
type=semver,pattern={{major}},enable=${{ matrix.variant == 'debian' }} | |
type=raw,value=latest,enable=${{ matrix.variant == 'debian' && github.ref == 'refs/heads/main' }} | |
- name: Set up QEMU | |
uses: docker/[email protected] | |
# Build and push Docker image with Buildx to both registries (don't push on PR) | |
- name: Build and push Docker image | |
id: build-and-push | |
uses: docker/[email protected] | |
with: | |
context: . | |
push: ${{ github.event_name != 'pull_request' }} | |
tags: ${{ steps.meta.outputs.tags }} | |
labels: ${{ steps.meta.outputs.labels }} | |
build-args: | | |
VARIANT=${{ matrix.variant }} | |
ALPINE_VERSION=${{ env.ALPINE_VERSION }} | |
DEBIAN_VERSION=${{ env.DEBIAN_VERSION }} | |
platforms: linux/amd64,linux/arm64 | |
cache-from: type=gha | |
cache-to: type=gha,mode=max | |
# Sign the resulting Docker image digests | |
- name: Sign the published Docker images | |
if: ${{ github.event_name != 'pull_request' }} | |
env: | |
TAGS: ${{ steps.meta.outputs.tags }} | |
DIGEST: ${{ steps.build-and-push.outputs.digest }} | |
run: | | |
echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} | |
# For use in other workflows (e.g. 'generate-readme', etc.) | |
- name: Save Build Version to Repository Variable | |
if: matrix.variant == 'debian' && github.run_attempt == 1 | |
run: | | |
VERSION="${{ steps.meta.outputs.version }}" | |
# Check if VERSION is empty and set a fallback value | |
if [ -z "$VERSION" ]; then | |
# Fetch the latest release using Git | |
VERSION=$(git tag -l --sort=-v:refname | grep -E '^v?[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1 || echo "3.1.0") | |
fi | |
echo "Setting BUILD_VERSION to $VERSION" | |
gh variable set BUILD_VERSION --body "$VERSION" | |
env: | |
GH_TOKEN: ${{ secrets.GH_PAT }} # Needs to be PAT w/ Read access to metadata and secrets & Read and Write access to actions, actions variables, and code |