Docker #307
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: Docker | |
on: | |
push: | |
branches: | |
- 'main' | |
- 'feature/**' | |
tags: | |
- 'v*.*.*' | |
schedule: | |
- cron: '0 06 * * *' | |
permissions: | |
contents: read | |
jobs: | |
docker: | |
name: Docker | |
runs-on: ubuntu-latest | |
permissions: | |
id-token: write # needed for OIDC Token signing with cosign | |
packages: write # needed for pushing packages | |
strategy: | |
matrix: | |
image: ["olareg"] | |
type: ["scratch", "alpine"] | |
env: | |
ALPINE_NAME: "alpine:3" | |
ALPINE_DIGEST: "sha256:77726ef6b57ddf65bb551896826ec38bc3e53f75cdde31354fbffb4f25238ebd" # 3.20.0 | |
steps: | |
- name: Check out code | |
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 | |
- name: Prepare | |
id: prep | |
run: | | |
mkdir -p "output/${{matrix.image}}" | |
EXT="" | |
if [ "${{ matrix.type }}" != "scratch" ]; then | |
EXT="-${{ matrix.type }}" | |
fi | |
HUB_IMAGE=olareg/${{ matrix.image }} | |
GHCR_IMAGE=ghcr.io/olareg/${{ matrix.image }} | |
VERSION="(devel)" | |
if [ "${{ github.event_name }}" = "schedule" ]; then | |
VERSION=edge | |
elif [[ $GITHUB_REF == refs/tags/* ]]; then | |
VERSION="${GITHUB_REF#refs/tags/}" | |
elif [[ $GITHUB_REF == refs/heads/* ]]; then | |
VERSION="${GITHUB_REF#refs/heads/}" | |
if [ "${{ github.event.repository.default_branch }}" = "$VERSION" ]; then | |
VERSION=edge | |
fi | |
elif [[ $GITHUB_REF == refs/pull/* ]]; then | |
VERSION="pr-${{ github.event.number }}" | |
fi | |
VERSION="$(echo "${VERSION}" | sed -r 's#/+#-#g')" | |
TAGS="${GHCR_IMAGE}:${VERSION}${EXT}" | |
# TAGS="${TAGS},${HUB_IMAGE}:${VERSION}${EXT}" | |
if [[ $VERSION =~ ^v[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then | |
MINOR="${VERSION%.*}" | |
MAJOR="${MINOR%.*}" | |
# TAGS="${TAGS},${HUB_IMAGE}:${MINOR}${EXT},${HUB_IMAGE}:${MAJOR}${EXT}" | |
TAGS="${TAGS},${GHCR_IMAGE}:${MINOR}${EXT},${GHCR_IMAGE}:${MAJOR}${EXT}" | |
if [ "${{ matrix.type }}" == "scratch" ]; then | |
# TAGS="${TAGS},${HUB_IMAGE}:latest" | |
TAGS="${TAGS},${GHCR_IMAGE}:latest" | |
else | |
# TAGS="${TAGS},${HUB_IMAGE}:${{ matrix.type }}" | |
TAGS="${TAGS},${GHCR_IMAGE}:${{ matrix.type }}" | |
fi | |
fi | |
VCS_SEC="$(git log -1 --format=%ct)" | |
VCS_DATE="$(date -d "@${VCS_SEC}" +%Y-%m-%dT%H:%M:%SZ --utc)" | |
REPO_URL="${{github.server_url}}/${{github.repository}}.git" | |
echo "version=${VERSION}" >>$GITHUB_OUTPUT | |
echo "image_hub=${HUB_IMAGE}" >>$GITHUB_OUTPUT | |
echo "image_ghcr=${GHCR_IMAGE}" >>$GITHUB_OUTPUT | |
echo "tags=${TAGS}" >>$GITHUB_OUTPUT | |
echo "vcs_sec=${VCS_SEC}" >>$GITHUB_OUTPUT | |
echo "created=${VCS_DATE}" >>$GITHUB_OUTPUT | |
echo "repo_url=${REPO_URL}" >>$GITHUB_OUTPUT | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 | |
# - name: Login to DockerHub | |
# if: github.repository_owner == 'olareg' | |
# uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 | |
# with: | |
# username: ${{ secrets.DOCKERHUB_USERNAME }} | |
# password: ${{ secrets.DOCKERHUB_TOKEN }} | |
- name: Login to GHCR | |
if: github.repository_owner == 'olareg' | |
uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Build | |
uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0 | |
id: build | |
with: | |
context: . | |
file: ./build/Dockerfile.${{ matrix.image }}.buildkit | |
platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x | |
target: release-${{ matrix.type }} | |
outputs: type=oci,dest=output/${{matrix.image}}-${{matrix.type}}.tar | |
build-args: | | |
SOURCE_DATE_EPOCH=${{ steps.prep.outputs.vcs_sec }} | |
BUILD_DATE=${{ steps.prep.outputs.created }} | |
VCS_REF=${{ github.sha }} | |
VCS_VERSION=${{ steps.prep.outputs.version }} | |
- name: Install cosign | |
if: github.event_name != 'pull_request' && github.repository_owner == 'olareg' | |
uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # v3.5.0 | |
with: | |
cosign-release: "v2.2.4" | |
- name: Install syft | |
if: github.event_name != 'pull_request' && github.repository_owner == 'olareg' | |
uses: anchore/sbom-action/download-syft@e8d2a6937ecead383dfe75190d104edd1f9c5751 # v0.16.0 | |
id: syft | |
with: | |
syft-version: "v1.7.0" | |
# Use regctl to modify olareg images to improve reproducibility | |
- name: Install regctl | |
uses: regclient/actions/regctl-installer@2dac4eff5925ed07edbfe12d2d11af6304df29a6 # main | |
if: github.event_name != 'pull_request' && github.repository_owner == 'olareg' | |
- name: Mutate | |
if: github.event_name != 'pull_request' && github.repository_owner == 'olareg' | |
id: mutate | |
run: | | |
vcs_date="${{ steps.prep.outputs.created }}" | |
base_name="" | |
mkdir -p "output/${{matrix.image}}" | |
if [ "${{matrix.type}}" = "alpine" ]; then | |
base_name="${ALPINE_NAME}" | |
base_digest="${ALPINE_DIGEST}" | |
fi | |
# mutate the image locally | |
local_tag="ocidir://output/${{matrix.image}}:${{matrix.type}}" | |
echo "Loading ${local_tag} from output/${{matrix.image}}-${{matrix.type}}.tar" | |
regctl image import "${local_tag}" "output/${{matrix.image}}-${{matrix.type}}.tar" | |
echo "Modifying image for reproducibility" | |
regctl image mod "${local_tag}" --replace \ | |
--to-oci-referrers --label-to-annotation --annotation-promote | |
if [ -n "$base_name" ] && [ -n "$base_digest" ]; then | |
regctl image mod "${local_tag}" --replace \ | |
--annotation "[*]org.opencontainers.image.base.name=${base_name}" \ | |
--annotation "[*]org.opencontainers.image.base.digest=${base_digest}" \ | |
--reproducible \ | |
--time "set=${vcs_date},base-ref=${base_name}@${base_digest}" | |
else | |
regctl image mod "${local_tag}" --replace \ | |
--reproducible \ | |
--time "set=${vcs_date}" | |
fi | |
echo "digest=$(regctl image digest ${local_tag})" >>$GITHUB_OUTPUT | |
- name: Attach SBOMs | |
if: github.event_name != 'pull_request' && github.repository_owner == 'olareg' | |
id: sbom | |
run: | | |
now_date="$(date +%Y-%m-%dT%H:%M:%SZ --utc)" | |
for digest in $(regctl manifest get ocidir://output/${{matrix.image}}:${{matrix.type}} \ | |
--format '{{range .Manifests}}{{printf "%s\n" .Digest}}{{end}}'); do | |
echo "Attaching SBOMs for ${{matrix.image}}@${digest}" | |
regctl image copy ocidir://output/${{matrix.image}}@${digest} ocidir://output/${{matrix.image}}-sbom -v warn >/dev/null | |
${{steps.syft.outputs.cmd}} scan -q "oci-dir:output/${{matrix.image}}-sbom" \ | |
--source-name "docker:docker.io/olareg/${{matrix.image}}@${digest}" -o cyclonedx-json \ | |
| regctl artifact put --subject "ocidir://output/${{matrix.image}}@${digest}" \ | |
--artifact-type application/vnd.cyclonedx+json \ | |
-m application/vnd.cyclonedx+json \ | |
--annotation "org.opencontainers.image.created=${now_date}" \ | |
--annotation "org.opencontainers.image.description=CycloneDX JSON SBOM" | |
${{steps.syft.outputs.cmd}} scan -q "oci-dir:output/${{matrix.image}}-sbom" \ | |
--source-name "docker:docker.io/olareg/${{matrix.image}}@${digest}" -o spdx-json \ | |
| regctl artifact put --subject "ocidir://output/${{matrix.image}}@${digest}" \ | |
--artifact-type application/spdx+json \ | |
-m application/spdx+json \ | |
--annotation "org.opencontainers.image.created=${now_date}" \ | |
--annotation "org.opencontainers.image.description=SPDX JSON SBOM" | |
rm -r output/${{matrix.image}}-sbom | |
done | |
- name: Push and Sign | |
if: github.event_name != 'pull_request' && github.repository_owner == 'olareg' | |
id: push | |
run: | | |
# loop over the tags | |
image_hub="${{ steps.prep.outputs.image_hub }}" | |
for tag in $(echo ${{ steps.prep.outputs.tags }} | tr , ' '); do | |
digest="$(regctl image digest "ocidir://output/${{matrix.image}}:${{matrix.type}}")" | |
if [ "${digest}" = "$(regctl image digest "${tag}" 2>/dev/null || true)" ]; then | |
# image already pushed, don't add referrers to reproducible builds | |
echo "Skipping ${tag}" | |
else | |
echo "Pushing ${tag}" | |
regctl image copy --referrers "ocidir://output/${{matrix.image}}:${{matrix.type}}@${digest}" "${tag}" | |
cosign sign -y -r "${tag}@${digest}" | |
fi | |
done |