mirror of
https://github.com/regclient/regclient.git
synced 2025-04-18 22:44:00 +03:00
- Update config to use yaml anchors and aliases - docker/build-push-action to v6.9.0 - github/codeql-action to v3.26.10 Signed-off-by: Brandon Mitchell <git@bmitch.net>
214 lines
8.9 KiB
YAML
214 lines
8.9 KiB
YAML
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: ["regctl", "regsync", "regbot"]
|
|
type: ["scratch", "alpine"]
|
|
|
|
env:
|
|
ALPINE_NAME: "alpine:3"
|
|
ALPINE_DIGEST: "sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367effd16dc0d06d" # 3.20.3
|
|
|
|
steps:
|
|
- name: Check out code
|
|
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
|
|
|
- name: Prepare
|
|
id: prep
|
|
run: |
|
|
mkdir -p "output/${{matrix.image}}"
|
|
EXT=""
|
|
if [ "${{ matrix.type }}" != "scratch" ]; then
|
|
EXT="-${{ matrix.type }}"
|
|
fi
|
|
HUB_IMAGE=regclient/${{ matrix.image }}
|
|
GHCR_IMAGE=ghcr.io/regclient/${{ 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="${HUB_IMAGE}:${VERSION}${EXT},${GHCR_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@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
|
|
|
|
- name: Login to DockerHub
|
|
if: github.repository_owner == 'regclient'
|
|
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
|
|
with:
|
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
|
|
- name: Login to GHCR
|
|
if: github.repository_owner == 'regclient'
|
|
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ secrets.GHCR_USERNAME }}
|
|
password: ${{ secrets.GHCR_TOKEN }}
|
|
|
|
- name: Build
|
|
uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.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 == 'regclient'
|
|
uses: sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382 # v3.6.0
|
|
with:
|
|
cosign-release: "v2.4.0"
|
|
|
|
- name: Install syft
|
|
if: github.event_name != 'pull_request' && github.repository_owner == 'regclient'
|
|
uses: anchore/sbom-action/download-syft@61119d458adab75f756bc0b9e4bde25725f86a7a # v0.17.2
|
|
id: syft
|
|
with:
|
|
syft-version: "v1.13.0"
|
|
|
|
# Dogfooding, use regctl to modify regclient images to improve reproducibility
|
|
- name: Install regctl
|
|
uses: regclient/actions/regctl-installer@35bc5829dd3d37ace2717971f3151894b43bfabc # main
|
|
if: github.event_name != 'pull_request' && github.repository_owner == 'regclient'
|
|
with:
|
|
release: main
|
|
|
|
- name: Mutate
|
|
if: github.event_name != 'pull_request' && github.repository_owner == 'regclient'
|
|
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 == 'regclient'
|
|
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/regclient/${{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/regclient/${{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 == 'regclient'
|
|
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
|