Skip to content

Release

Release #77

Workflow file for this run

#
# SPDX-FileCopyrightText: 2021-2025 Jens A. Koch
# SPDX-License-Identifier: MIT
# This file is part of jakoch/jupyter-devbox.
#
name: Release
on:
# You can manually run this workflow.
workflow_dispatch:
# This workflow runs on pushing a semantic versionized tag (e.g. v1.0.0).
# This workflow does not run when pushing to the main branch.
push:
#branches:
# - main
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
# This workflow runs on schedule: every Sunday at 2 am.
schedule:
- cron: "0 2 * * 0"
env:
DOCKERHUB_IMAGE: ${{ github.repository }}
GHCR_IMAGE: ghcr.io/${{ github.repository }}
jobs:
# ---------------------------------------------------------------------------------------
build:
# ---------------------------------------------------------------------------------------
name: "Build Container"
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
config:
- { platform: "linux/amd64", folder: "amd64" }
- { platform: "linux/arm64", folder: "arm64v8" }
steps:
- name: ✂️ Free Disk Space
uses: jlumbroso/free-disk-space@v1.3.0 # https://github.com/jlumbroso/free-disk-space
with:
tool-cache: true
docker-images: false
- name: 🤘 Checkout
uses: actions/checkout@v4 # https://github.com/actions/checkout
- name: 🔽 Setup QEMU
uses: docker/setup-qemu-action@v3 # https://github.com/docker/setup-qemu-action
with:
platforms: ${{ matrix.config.platform }}
- name: 🔽 Setup Docker Buildx
uses: docker/setup-buildx-action@v3
#- name: 🔒 Login to DockerHub Container Registry
# if: github.event_name != 'pull_request'
# uses: docker/login-action@v3 # https://github.com/docker/login-action
# with:
# username: ${{ secrets.DOCKERHUB_USERNAME }}
# password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: 🔒 Login to Github Container Registry (GHCR)
if: github.event_name != 'pull_request'
uses: docker/login-action@v3 # https://github.com/docker/login-action
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: ✏ Setup Docker Metadata
id: metadata
uses: docker/metadata-action@v5 # https://github.com/docker/metadata-action/
with:
images: |
${{ env.GHCR_IMAGE }}
flavor: |
latest=auto
tags: |
type=schedule,pattern={{ date 'YYYYMMDD' }}
type=semver,pattern={{ version }}
type=semver,pattern={{ major }}.{{ minor }}
type=raw,value={{ date 'YYYYMMDD' }}-sha-{{ sha }},enabled=${{ github.event_name == 'push' }}
type=raw,value=latest
- name: ✏ Create info.json
run: |
jq -n --arg version "${{ github.ref_name }}" --arg commit "${{ github.sha }}" --arg date "$(date -u +%F)" '{ version: $version, commit: $commit, date: $date }' > info.json
- name: 📦 🚀 Build and Push by Digest
id: build
uses: docker/build-push-action@v6 # https://github.com/docker/build-push-action
with:
context: .
file: .devcontainer/${{ matrix.config.folder }}/Dockerfile
platforms: ${{ matrix.config.platform }}
labels: ${{ steps.metadata.outputs.labels }}
outputs: type=image,name=${{ env.GHCR_IMAGE }},push-by-digest=true,name-canonical=true,push=true
- name: ✏ Export Digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: 🔼 Upload Digest
uses: actions/upload-artifact@v4 # https://github.com/actions/upload-artifact
with:
name: digest-${{ matrix.config.folder }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
- name: 🔍 Run hadolint
uses: hadolint/hadolint-action@v3.1.0 # https://github.com/hadolint/hadolint-action
with:
dockerfile: .devcontainer/${{ matrix.config.folder }}/Dockerfile
no-fail: true
# ---------------------------------------------------------------------------------------
merge:
# ---------------------------------------------------------------------------------------
name: "Merge Metadata and Push Manifest"
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
needs:
- build
steps:
- name: 🔽 Download digests
uses: actions/download-artifact@v4 # https://github.com/actions/download-artifact
with:
path: /tmp/digests
pattern: digest-*
merge-multiple: true
- name: ❔ Display downloaded artifacts
run: ls -R /tmp/digests
#- name: 🔒 Login to DockerHub Container Registry
# if: github.event_name != 'pull_request'
# uses: docker/login-action@v3 # https://github.com/docker/login-action
# with:
# username: ${{ secrets.DOCKERHUB_USERNAME }}
# password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: 🔒 Login to Github Container Registry (GHCR)
if: github.event_name != 'pull_request'
uses: docker/login-action@v3 # https://github.com/docker/login-action
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: 🔽 Setup Docker Buildx
uses: docker/setup-buildx-action@v3 # https://github.com/docker/setup-buildx-action
- name: ✏ Setup Docker Metadata
id: metadata
uses: docker/metadata-action@v5 # https://github.com/docker/metadata-action
with:
images: |
${{ env.GHCR_IMAGE }}
tags: |
type=sha
type=raw,value=latest
type=ref,event=tag
- name: 📦 🚀 Create and Push Manifest
working-directory: /tmp/digests
run: |
tags=$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")
sources=$(printf '${{ env.GHCR_IMAGE }}@sha256:%s ' *)
echo "$sources"
docker buildx imagetools create $tags $sources
- name: 🔍 Inspect Manifest
run: |
docker buildx imagetools inspect ${{ env.GHCR_IMAGE }}:latest --raw
#- name: 🛡️🔍 Scan Image for Vulnerabilities
# uses: aquasecurity/trivy-action@master # https://github.com/aquasecurity/trivy-action
# with:
# image-ref: '${{ env.GHCR_IMAGE }}:latest'
# format: 'sarif'
# output: 'trivy-results.sarif'
# severity: 'CRITICAL,HIGH'
# ignore-unfixed: true
# upload fails: https://github.com/github/codeql-action/issues/2117
#- name: 🛡️🔼 Upload scan results to GitHub Security tab
# uses: github/codeql-action/upload-sarif@v3 # https://github.com/github/codeql-action
# with:
# sarif_file: 'trivy-results.sarif'