forgejo-mcp/.tekton/release-tools/tasks/push-image-by-digest.yaml
Christoph Görn 3125eec711
feat: ✨ enable Tekton Chains SLSA v1.0 provenance for release-tools image
- add chains.tekton.dev/transparency-upload annotation to publish PipelineRun
- propagate IMAGE_URL + IMAGE_DIGEST as pipeline-level results for Chains binding
- add IMAGE_URL result to push-image-by-digest task (required for image→provenance bind)
- document cosign verify-attestation --type slsaprovenance in README
- update ADR (release-pipeline-migration.md) with Chains addendum; remove from out-of-scope

Closes forgejo-mcp-46j
2026-05-26 15:06:35 +02:00

92 lines
3.8 KiB
YAML

apiVersion: tekton.dev/v1
kind: Task
metadata:
name: release-tools-push-image-by-digest
annotations:
tekton.dev/displayName: "push release-tools image to registry by digest (no tag)"
spec:
description: |
# Path A (decided 2026-05-25): codeberg.org/operate-first/release-tools
# Registry: codeberg.org/operate-first/release-tools
#
# L1 TOCTOU fix: push manifest by digest ONLY here. The human-readable
# vMAJOR.MINOR.PATCH tag is promoted AFTER cosign-sign succeeds (T9).
# This closes the window where an unsigned image could be advertised.
params:
- name: IMAGE
description: |
Local image tag to push (e.g. release-tools:build-tmp). Must already
exist in the buildah store in the workspace.
# Path A (decided 2026-05-25): codeberg.org/operate-first/release-tools
# Registry path working assumption: codeberg.org/operate-first/release-tools
type: string
- name: REGISTRY_IMAGE
description: |
Full registry path without tag (e.g. codeberg.org/operate-first/release-tools).
# Path A (decided 2026-05-25): codeberg.org/operate-first/release-tools
# Working assumption: codeberg.org/operate-first/release-tools
type: string
default: "codeberg.org/operate-first/release-tools"
- name: STORAGE_DRIVER
description: buildah storage driver.
type: string
default: vfs
workspaces:
- name: source
mountPath: /workspace/source
- name: registry-credentials
mountPath: /workspace/registry-creds
optional: false
results:
- name: IMAGE_DIGEST
description: sha256 digest of the pushed manifest (e.g. sha256:abc123...).
- name: IMAGE_URL
description: Registry URL without tag or digest (e.g. codeberg.org/operate-first/release-tools). Used by Tekton Chains to bind image to SLSA provenance.
- name: IMAGE_REPO_DIGEST
description: Full digest reference (e.g. codeberg.org/operate-first/release-tools@sha256:abc123).
steps:
- name: push-by-digest
image: quay.io/buildah/stable:latest
securityContext:
privileged: true
workingDir: $(workspaces.source.path)
script: |
#!/usr/bin/env bash
set -euo pipefail
# Configure registry auth
REGISTRY_AUTH_FILE="$(workspaces.registry-credentials.path)/.dockerconfigjson"
if [ ! -f "${REGISTRY_AUTH_FILE}" ]; then
REGISTRY_AUTH_FILE="$(workspaces.registry-credentials.path)/config.json"
fi
# Use same workspace store as build-image task.
BUILDAH_STORE="$(workspaces.source.path)/.buildah"
LOCAL_IMAGE="localhost/$(params.IMAGE)"
REGISTRY_IMAGE="$(params.REGISTRY_IMAGE)"
echo "Pushing ${LOCAL_IMAGE} to ${REGISTRY_IMAGE} by digest (no version tag)..."
# L1 TOCTOU fix: retag to an ephemeral staging name before pushing so
# buildah does not inherit the version tag (e.g. v1.0.0) at the
# destination. The version tag is promoted AFTER signing by promote-tag.
buildah --root "${BUILDAH_STORE}" \
--storage-driver="$(params.STORAGE_DRIVER)" \
tag "${LOCAL_IMAGE}" release-tools:build-tmp
buildah --root "${BUILDAH_STORE}" push \
--storage-driver="$(params.STORAGE_DRIVER)" \
--authfile="${REGISTRY_AUTH_FILE}" \
--digestfile=/tmp/pushed-digest \
release-tools:build-tmp \
"docker://${REGISTRY_IMAGE}:build-tmp" \
2>&1 | tee /dev/stderr
DIGEST=$(cat /tmp/pushed-digest)
REPO_DIGEST="${REGISTRY_IMAGE}@${DIGEST}"
printf '%s' "${DIGEST}" > "$(results.IMAGE_DIGEST.path)"
printf '%s' "${REGISTRY_IMAGE}" > "$(results.IMAGE_URL.path)"
printf '%s' "${REPO_DIGEST}" > "$(results.IMAGE_REPO_DIGEST.path)"
echo "Pushed by digest: ${REPO_DIGEST}"