mirror of
https://github.com/regclient/regclient.git
synced 2025-04-18 22:44:00 +03:00
- Go to v1.24.2 - ECR Helper to latest commit - anchore/syft to v1.22.0 - library/registry to v3.0.0 - securego/gosec to v2.22.3 - google/osv-scanner to v2.0.1 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:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c" # 3.21.3
|
|
|
|
steps:
|
|
- name: Check out code
|
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- 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@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
|
|
|
- name: Login to DockerHub
|
|
if: github.repository_owner == 'regclient'
|
|
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
|
with:
|
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
|
|
- name: Login to GHCR
|
|
if: github.repository_owner == 'regclient'
|
|
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ secrets.GHCR_USERNAME }}
|
|
password: ${{ secrets.GHCR_TOKEN }}
|
|
|
|
- name: Build
|
|
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.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@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a # v3.8.1
|
|
with:
|
|
cosign-release: "v2.4.3"
|
|
|
|
- name: Install syft
|
|
if: github.event_name != 'pull_request' && github.repository_owner == 'regclient'
|
|
uses: anchore/sbom-action/download-syft@f325610c9f50a54015d37c8d16cb3b0e2c8f4de0 # v0.18.0
|
|
id: syft
|
|
with:
|
|
syft-version: "v1.22.0"
|
|
|
|
# Dogfooding, use regctl to modify regclient images to improve reproducibility
|
|
- name: Install regctl
|
|
uses: regclient/actions/regctl-installer@ce5fd131e371ffcdd7508b478cb223b3511a9183 # 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
|