Switch artifact signing from the shared cosign-signing-key to the purpose-named cosign-signing-key-artifacts Secret (same key material, no rotation). Completes the isolation split from op1st-emea-b4mad-yn5. Gate: merge only after cosign-signing-key-artifacts is reflected in op1st-pipelines (op1st-emea-b4mad PR landed 2026-05-26). Closes op1st-emea-b4mad-ueq. Related: forgejo-mcp-j52.
116 lines
4 KiB
YAML
116 lines
4 KiB
YAML
apiVersion: tekton.dev/v1beta1
|
|
kind: Task
|
|
metadata:
|
|
name: cosign-sign-release
|
|
annotations:
|
|
tekton.dev/displayName: "cosign sign-blob checksums + upload to Codeberg release"
|
|
spec:
|
|
description: |
|
|
Signs the GoReleaser-produced `checksums.txt` with cosign (key from the
|
|
`cosign-signing-key-artifacts` Secret) and uploads the resulting `.sig` as a
|
|
release asset. Signing the checksum file covers all archives + SBOMs
|
|
transitively via the checksum chain.
|
|
|
|
Skipped (exit 0) if the cosign secret is empty/missing — mirrors the
|
|
behavior of .forgejo/workflows/release.yml so releases continue to ship
|
|
if signing infrastructure is unavailable.
|
|
|
|
The `cosign-signing-key-artifacts` Secret is provisioned in op1st-pipelines
|
|
upstream of this Task (typically via the op1st-gitops repo + emberstack
|
|
reflector). Expected keys: cosign.key, cosign.password, cosign.pub.
|
|
|
|
All tools (cosign, jq, curl) are pre-baked into RELEASE_TOOLS_IMAGE.
|
|
No runtime installs.
|
|
params:
|
|
- name: RELEASE_TOOLS_IMAGE
|
|
description: |
|
|
Pre-built release-tools image containing go, goreleaser, syft, cosign,
|
|
govulncheck, node, npm, jq, curl, mcpb, and openspec.
|
|
type: string
|
|
default: codeberg.org/operate-first/release-tools:latest
|
|
- name: TAG
|
|
description: Tag ref name (e.g. v2.24.0).
|
|
type: string
|
|
- name: REPO
|
|
description: Repo slug owner/name (e.g. goern/forgejo-mcp).
|
|
type: string
|
|
- name: CODEBERG_API
|
|
description: Codeberg API base URL.
|
|
type: string
|
|
default: https://codeberg.org/api/v1
|
|
workspaces:
|
|
- name: source
|
|
mountPath: /workspace/src
|
|
stepTemplate:
|
|
workingDir: $(workspaces.source.path)
|
|
steps:
|
|
- name: sign-checksums
|
|
image: $(params.RELEASE_TOOLS_IMAGE)
|
|
env:
|
|
- name: COSIGN_PRIVATE_KEY
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: cosign-signing-key-artifacts
|
|
key: cosign.key
|
|
optional: true
|
|
- name: COSIGN_PASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: cosign-signing-key-artifacts
|
|
key: cosign.password
|
|
optional: true
|
|
script: |
|
|
#!/usr/bin/env sh
|
|
set -eu
|
|
if [ -z "${COSIGN_PRIVATE_KEY:-}" ]; then
|
|
echo "WARN: COSIGN_PRIVATE_KEY not set; skipping signature step."
|
|
exit 0
|
|
fi
|
|
TAG="$(params.TAG)"
|
|
VERSION="${TAG#v}"
|
|
CHECKSUMS="dist/forgejo-mcp_${VERSION}_checksums.txt"
|
|
if [ ! -f "$CHECKSUMS" ]; then
|
|
echo "ERROR: Expected $CHECKSUMS not produced by GoReleaser" >&2
|
|
exit 1
|
|
fi
|
|
SIG="${CHECKSUMS}.sig"
|
|
KEY_FILE="$(mktemp)"
|
|
trap 'rm -f "$KEY_FILE"' EXIT
|
|
printf '%s' "$COSIGN_PRIVATE_KEY" > "$KEY_FILE"
|
|
cosign sign-blob --yes \
|
|
--key "$KEY_FILE" \
|
|
--bundle "$SIG" \
|
|
"$CHECKSUMS"
|
|
ls -l "$SIG"
|
|
|
|
- name: upload-signature
|
|
image: $(params.RELEASE_TOOLS_IMAGE)
|
|
env:
|
|
- name: GITEA_TOKEN
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: op1st-release-token
|
|
key: token
|
|
script: |
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
TAG="$(params.TAG)"
|
|
VERSION="${TAG#v}"
|
|
SIG="dist/forgejo-mcp_${VERSION}_checksums.txt.sig"
|
|
if [ ! -f "$SIG" ]; then
|
|
echo "INFO: No signature file present; signing step was skipped."
|
|
exit 0
|
|
fi
|
|
RELEASE_ID=$(curl -fsSL \
|
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
|
"$(params.CODEBERG_API)/repos/$(params.REPO)/releases/tags/${TAG}" \
|
|
| jq -r '.id')
|
|
if [ -z "$RELEASE_ID" ] || [ "$RELEASE_ID" = "null" ]; then
|
|
echo "ERROR: Could not resolve release ID for tag ${TAG}" >&2
|
|
exit 1
|
|
fi
|
|
ASSET_NAME=$(basename "$SIG")
|
|
curl -fsSL -X POST \
|
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
|
-F "attachment=@${SIG}" \
|
|
"$(params.CODEBERG_API)/repos/$(params.REPO)/releases/${RELEASE_ID}/assets?name=${ASSET_NAME}"
|