feat(ci): add Tekton release pipeline mirroring Forgejo Actions release #150

Merged
goern merged 0 commits from refs/pull/150/head into main 2026-05-25 11:27:10 +00:00
goern commented 2026-05-25 09:17:58 +00:00 (Migrated from codeberg.org)

Summary

Ports .forgejo/workflows/release.yml to op1st-pipelines Tekton via Pipelines-as-Code, triggered on refs/tags/v* push. Runs in parallel with the existing Forgejo Actions release workflow — no removal in this PR.

Tracks bead forgejo-mcp-d4b. Related: forgejo-mcp-td8 (canonical CI gate decision).

What's in the PR

Pipeline

  • .tekton/on-tag-push-release.yaml — PipelineRun, PaC trigger on [push] matching [refs/tags/v*]. Workspace 8Gi.
  • .tekton/tasks/goreleaser-release.yaml — install syft + goreleaser, run release (GORELEASER_FORCE_TOKEN=gitea), smoke-test linux/amd64 binary version banner.
  • .tekton/tasks/cosign-sign-release.yamlsign-blob of checksums.txt, upload .sig to Codeberg release. Skipped (warn) if cosign-release-key Secret absent — mirrors Forgejo workflow's fail-open behavior.
  • .tekton/tasks/mcpb-pack.yaml — pack .mcpb per (goos, goarch) (linux/darwin × amd64/arm64), version-stamp extension/manifest.json, upload each to Codeberg release.

Shape: fetch-source → resolve-tag → goreleaser-release → { cosign-sign-release ∥ mcpb-pack }

Docs

  • docs/design/release-pipeline-migration.md — ADR: rationale, alternatives rejected (hard cutover, cross-repo workflow_call, Tekton Chains in place of cosign sign-blob, single mega-image), secrets, trigger semantics, cutover criteria, rollback.
  • docs/plans/tekton-release-runbook.md — operator runbook: provisioning, cutting a release, observing runs, common failure modes.

Secrets required in op1st-pipelines

Secret Keys Purpose
forgejo-release-token token Codeberg PAT with write:repository
cosign-release-key cosign.key, cosign.password, cosign.pub sign-blob of checksums

Provisioning commands in the ADR.

Test plan

  • Operator provisions forgejo-release-token + cosign-release-key Secrets in op1st-pipelines.
  • On next tag push, verify PaC controller logs show match and PipelineRun is created.
  • tkn pr logs --last -f — confirm goreleaser-release Task succeeds.
  • Confirm checksums.txt.sig + 4× .mcpb appear on the Codeberg release.
  • cosign verify-blob --key cosign.pub --signature checksums.txt.sig checksums.txt succeeds.
  • Repeat for one more release; if cutover criteria in the ADR hold, follow-up PR removes .forgejo/workflows/release.yml.

Out of scope

  • Migrating PR + push-to-main CI (forgejo-mcp-td8).
  • Konflux integration / container release.
  • Publishing Tekton Chains in-toto provenance to the release.
## Summary Ports `.forgejo/workflows/release.yml` to op1st-pipelines Tekton via Pipelines-as-Code, triggered on `refs/tags/v*` push. Runs **in parallel** with the existing Forgejo Actions release workflow — no removal in this PR. Tracks bead `forgejo-mcp-d4b`. Related: `forgejo-mcp-td8` (canonical CI gate decision). ## What's in the PR ### Pipeline - `.tekton/on-tag-push-release.yaml` — PipelineRun, PaC trigger on `[push]` matching `[refs/tags/v*]`. Workspace 8Gi. - `.tekton/tasks/goreleaser-release.yaml` — install syft + goreleaser, run release (`GORELEASER_FORCE_TOKEN=gitea`), smoke-test linux/amd64 binary version banner. - `.tekton/tasks/cosign-sign-release.yaml` — `sign-blob` of `checksums.txt`, upload `.sig` to Codeberg release. Skipped (warn) if `cosign-release-key` Secret absent — mirrors Forgejo workflow's fail-open behavior. - `.tekton/tasks/mcpb-pack.yaml` — pack `.mcpb` per `(goos, goarch)` (linux/darwin × amd64/arm64), version-stamp `extension/manifest.json`, upload each to Codeberg release. Shape: `fetch-source → resolve-tag → goreleaser-release → { cosign-sign-release ∥ mcpb-pack }` ### Docs - `docs/design/release-pipeline-migration.md` — ADR: rationale, alternatives rejected (hard cutover, cross-repo `workflow_call`, Tekton Chains in place of `cosign sign-blob`, single mega-image), secrets, trigger semantics, **cutover criteria**, rollback. - `docs/plans/tekton-release-runbook.md` — operator runbook: provisioning, cutting a release, observing runs, common failure modes. ## Secrets required in `op1st-pipelines` | Secret | Keys | Purpose | |--------|------|---------| | `forgejo-release-token` | `token` | Codeberg PAT with `write:repository` | | `cosign-release-key` | `cosign.key`, `cosign.password`, `cosign.pub` | `sign-blob` of checksums | Provisioning commands in the ADR. ## Test plan - [ ] Operator provisions `forgejo-release-token` + `cosign-release-key` Secrets in `op1st-pipelines`. - [ ] On next tag push, verify PaC controller logs show match and PipelineRun is created. - [ ] `tkn pr logs --last -f` — confirm goreleaser-release Task succeeds. - [ ] Confirm `checksums.txt.sig` + 4× `.mcpb` appear on the Codeberg release. - [ ] `cosign verify-blob --key cosign.pub --signature checksums.txt.sig checksums.txt` succeeds. - [ ] Repeat for one more release; if cutover criteria in the ADR hold, follow-up PR removes `.forgejo/workflows/release.yml`. ## Out of scope - Migrating PR + push-to-main CI (`forgejo-mcp-td8`). - Konflux integration / container release. - Publishing Tekton Chains in-toto provenance to the release.
op1st-gitops commented 2026-05-25 09:18:35 +00:00 (Migrated from codeberg.org)

op1st Pipelines as Code/code-scans-4wtn2 is running.

Starting Pipelinerun code-scans-4wtn2 in namespace op1st-pipelines

You can monitor the execution using the op1st Pipelines as Code PipelineRun viewer or through the command line by
using the tkn CLI with the following command:

tkn pr logs -n op1st-pipelines code-scans-4wtn2 -f

op1st Pipelines as Code/code-scans-4wtn2 is running. Starting Pipelinerun <b>[code-scans-4wtn2](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-4wtn2)</b> in namespace <b>op1st-pipelines</b> You can monitor the execution using the [op1st Pipelines as Code](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-4wtn2) PipelineRun viewer or through the command line by using the [tkn](https://tekton.dev/docs/cli/#installation) CLI with the following command: <code>tkn pr logs -n op1st-pipelines code-scans-4wtn2 -f</code>
op1st-gitops commented 2026-05-25 09:18:35 +00:00 (Migrated from codeberg.org)

op1st Pipelines as Code/on-pull-request- has failed.
There was an error creating the PipelineRun: on-pull-request-

cannot use the API on the provider platform to create a in_progress status:

op1st Pipelines as Code/on-pull-request- has <b>failed</b>. There was an error creating the PipelineRun: <b>on-pull-request-</b> cannot use the API on the provider platform to create a in_progress status:
op1st-gitops commented 2026-05-25 09:18:55 +00:00 (Migrated from codeberg.org)

op1st Pipelines as Code/code-scans-4wtn2 has successfully validated your commit.


Task Statuses:

StatusDurationName
Succeeded 11 seconds

fetch-source

Succeeded 8 seconds

gitleaks-version

Succeeded 9 seconds

gitleaks

op1st Pipelines as Code/code-scans-4wtn2 has <b>successfully</b> validated your commit. <ul> <li><b>Namespace</b>: <a href="https://detailurl.setting.custom-console-url-namespace.is.not.configured">op1st-pipelines</a></li> <li><b>PipelineRun:</b> <a href="https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-4wtn2">code-scans-4wtn2</a></li> </ul> <hr> <h4>Task Statuses:</h4> <table> <tr><th>Status</th><th>Duration</th><th>Name</th></tr> <tr> <td>Succeeded</td> <td>11 seconds</td><td> [fetch-source](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-4wtn2/logs/fetch-source) </td></tr> <tr> <td>Succeeded</td> <td>8 seconds</td><td> [gitleaks-version](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-4wtn2/logs/gitleaks-version) </td></tr> <tr> <td>Succeeded</td> <td>9 seconds</td><td> [gitleaks](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-4wtn2/logs/gitleaks) </td></tr> </table>
op1st-gitops commented 2026-05-25 10:54:03 +00:00 (Migrated from codeberg.org)

op1st Pipelines as Code/on-pull-request-9ptgc is running.

Starting Pipelinerun on-pull-request-9ptgc in namespace op1st-pipelines

You can monitor the execution using the op1st Pipelines as Code PipelineRun viewer or through the command line by
using the tkn CLI with the following command:

tkn pr logs -n op1st-pipelines on-pull-request-9ptgc -f

op1st Pipelines as Code/on-pull-request-9ptgc is running. Starting Pipelinerun <b>[on-pull-request-9ptgc](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/on-pull-request-9ptgc)</b> in namespace <b>op1st-pipelines</b> You can monitor the execution using the [op1st Pipelines as Code](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/on-pull-request-9ptgc) PipelineRun viewer or through the command line by using the [tkn](https://tekton.dev/docs/cli/#installation) CLI with the following command: <code>tkn pr logs -n op1st-pipelines on-pull-request-9ptgc -f</code>
op1st-gitops commented 2026-05-25 10:54:03 +00:00 (Migrated from codeberg.org)

op1st Pipelines as Code/code-scans-fz92v is running.

Starting Pipelinerun code-scans-fz92v in namespace op1st-pipelines

You can monitor the execution using the op1st Pipelines as Code PipelineRun viewer or through the command line by
using the tkn CLI with the following command:

tkn pr logs -n op1st-pipelines code-scans-fz92v -f

op1st Pipelines as Code/code-scans-fz92v is running. Starting Pipelinerun <b>[code-scans-fz92v](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-fz92v)</b> in namespace <b>op1st-pipelines</b> You can monitor the execution using the [op1st Pipelines as Code](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-fz92v) PipelineRun viewer or through the command line by using the [tkn](https://tekton.dev/docs/cli/#installation) CLI with the following command: <code>tkn pr logs -n op1st-pipelines code-scans-fz92v -f</code>
op1st-gitops commented 2026-05-25 10:54:24 +00:00 (Migrated from codeberg.org)

op1st Pipelines as Code/code-scans-fz92v has successfully validated your commit.


Task Statuses:

StatusDurationName
Succeeded 12 seconds

fetch-source

Succeeded 8 seconds

gitleaks-version

Succeeded 8 seconds

gitleaks

op1st Pipelines as Code/code-scans-fz92v has <b>successfully</b> validated your commit. <ul> <li><b>Namespace</b>: <a href="https://detailurl.setting.custom-console-url-namespace.is.not.configured">op1st-pipelines</a></li> <li><b>PipelineRun:</b> <a href="https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-fz92v">code-scans-fz92v</a></li> </ul> <hr> <h4>Task Statuses:</h4> <table> <tr><th>Status</th><th>Duration</th><th>Name</th></tr> <tr> <td>Succeeded</td> <td>12 seconds</td><td> [fetch-source](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-fz92v/logs/fetch-source) </td></tr> <tr> <td>Succeeded</td> <td>8 seconds</td><td> [gitleaks-version](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-fz92v/logs/gitleaks-version) </td></tr> <tr> <td>Succeeded</td> <td>8 seconds</td><td> [gitleaks](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-fz92v/logs/gitleaks) </td></tr> </table>
op1st-gitops commented 2026-05-25 10:55:29 +00:00 (Migrated from codeberg.org)

op1st Pipelines as Code/on-pull-request-9ptgc has successfully validated your commit.


Task Statuses:

StatusDurationName
Succeeded 12 seconds

fetch-source

Succeeded 1 minute

build-and-test

op1st Pipelines as Code/on-pull-request-9ptgc has <b>successfully</b> validated your commit. <ul> <li><b>Namespace</b>: <a href="https://detailurl.setting.custom-console-url-namespace.is.not.configured">op1st-pipelines</a></li> <li><b>PipelineRun:</b> <a href="https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/on-pull-request-9ptgc">on-pull-request-9ptgc</a></li> </ul> <hr> <h4>Task Statuses:</h4> <table> <tr><th>Status</th><th>Duration</th><th>Name</th></tr> <tr> <td>Succeeded</td> <td>12 seconds</td><td> [fetch-source](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/on-pull-request-9ptgc/logs/fetch-source) </td></tr> <tr> <td>Succeeded</td> <td>1 minute</td><td> [build-and-test](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/on-pull-request-9ptgc/logs/build-and-test) </td></tr> </table>
op1st-gitops commented 2026-05-25 11:24:38 +00:00 (Migrated from codeberg.org)

op1st Pipelines as Code/on-pull-request-s89hh is running.

Starting Pipelinerun on-pull-request-s89hh in namespace op1st-pipelines

You can monitor the execution using the op1st Pipelines as Code PipelineRun viewer or through the command line by
using the tkn CLI with the following command:

tkn pr logs -n op1st-pipelines on-pull-request-s89hh -f

op1st Pipelines as Code/on-pull-request-s89hh is running. Starting Pipelinerun <b>[on-pull-request-s89hh](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/on-pull-request-s89hh)</b> in namespace <b>op1st-pipelines</b> You can monitor the execution using the [op1st Pipelines as Code](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/on-pull-request-s89hh) PipelineRun viewer or through the command line by using the [tkn](https://tekton.dev/docs/cli/#installation) CLI with the following command: <code>tkn pr logs -n op1st-pipelines on-pull-request-s89hh -f</code>
op1st-gitops commented 2026-05-25 11:24:38 +00:00 (Migrated from codeberg.org)

op1st Pipelines as Code/code-scans-lw4gk is running.

Starting Pipelinerun code-scans-lw4gk in namespace op1st-pipelines

You can monitor the execution using the op1st Pipelines as Code PipelineRun viewer or through the command line by
using the tkn CLI with the following command:

tkn pr logs -n op1st-pipelines code-scans-lw4gk -f

op1st Pipelines as Code/code-scans-lw4gk is running. Starting Pipelinerun <b>[code-scans-lw4gk](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-lw4gk)</b> in namespace <b>op1st-pipelines</b> You can monitor the execution using the [op1st Pipelines as Code](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-lw4gk) PipelineRun viewer or through the command line by using the [tkn](https://tekton.dev/docs/cli/#installation) CLI with the following command: <code>tkn pr logs -n op1st-pipelines code-scans-lw4gk -f</code>
op1st-gitops commented 2026-05-25 11:25:06 +00:00 (Migrated from codeberg.org)

op1st Pipelines as Code/code-scans-lw4gk has successfully validated your commit.


Task Statuses:

StatusDurationName
Succeeded 17 seconds

fetch-source

Succeeded 11 seconds

gitleaks-version

Succeeded 9 seconds

gitleaks

op1st Pipelines as Code/code-scans-lw4gk has <b>successfully</b> validated your commit. <ul> <li><b>Namespace</b>: <a href="https://detailurl.setting.custom-console-url-namespace.is.not.configured">op1st-pipelines</a></li> <li><b>PipelineRun:</b> <a href="https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-lw4gk">code-scans-lw4gk</a></li> </ul> <hr> <h4>Task Statuses:</h4> <table> <tr><th>Status</th><th>Duration</th><th>Name</th></tr> <tr> <td>Succeeded</td> <td>17 seconds</td><td> [fetch-source](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-lw4gk/logs/fetch-source) </td></tr> <tr> <td>Succeeded</td> <td>11 seconds</td><td> [gitleaks-version](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-lw4gk/logs/gitleaks-version) </td></tr> <tr> <td>Succeeded</td> <td>9 seconds</td><td> [gitleaks](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/code-scans-lw4gk/logs/gitleaks) </td></tr> </table>
op1st-gitops commented 2026-05-25 11:26:11 +00:00 (Migrated from codeberg.org)

op1st Pipelines as Code/on-pull-request-s89hh has successfully validated your commit.


Task Statuses:

StatusDurationName
Succeeded 17 seconds

fetch-source

Succeeded 1 minute

build-and-test

op1st Pipelines as Code/on-pull-request-s89hh has <b>successfully</b> validated your commit. <ul> <li><b>Namespace</b>: <a href="https://detailurl.setting.custom-console-url-namespace.is.not.configured">op1st-pipelines</a></li> <li><b>PipelineRun:</b> <a href="https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/on-pull-request-s89hh">on-pull-request-s89hh</a></li> </ul> <hr> <h4>Task Statuses:</h4> <table> <tr><th>Status</th><th>Duration</th><th>Name</th></tr> <tr> <td>Succeeded</td> <td>17 seconds</td><td> [fetch-source](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/on-pull-request-s89hh/logs/fetch-source) </td></tr> <tr> <td>Succeeded</td> <td>1 minute</td><td> [build-and-test](https://console-openshift-console.apps.nostromo.erdgeschoss.b4mad.emea.operate-first.cloud/k8s/ns/op1st-pipelines/tekton.dev~v1~PipelineRun/on-pull-request-s89hh/logs/build-and-test) </td></tr> </table>
goern commented 2026-05-25 11:27:02 +00:00 (Migrated from codeberg.org)

Secret validation — complete

Read-only inspection of op1st-pipelines namespace (key names only, no values decoded):

Secret Status
op1st-release-token (Opaque, keys: token, username, reflected from op1st-gitops/op1st-release-token) shape matches
cosign-signing-key (Opaque, keys: cosign.key, cosign.password, cosign.pub) shape matches

Other Codeberg secrets in the namespace ruled out:

  • codeberg-pusherkubernetes.io/dockerconfigjson, wrong shape
  • codeberg-runner-openshift-pac — PaC per-repo, read:repository + write:repository.status scope only
  • codeberg-org-op1st-pipelines — PaC controller identity (org token + webhook HMAC)

Operator-confirmable preconditions (verified, cannot be checked from cluster):

  • op1st-release-token.token carries write:repository on goern/forgejo-mcp
  • cosign-signing-key.cosign.pub bytes match secrets/cosign.pub@791ef6d

Pipeline is ready. Next v* tag push triggers the Tekton run alongside the existing .forgejo/workflows/release.yml. Cutover stays deferred until 2 consecutive Tekton releases satisfy the ADR criteria.

## Secret validation — complete Read-only inspection of `op1st-pipelines` namespace (key names only, no values decoded): | Secret | Status | |---|---| | `op1st-release-token` (Opaque, keys: `token`, `username`, reflected from `op1st-gitops/op1st-release-token`) | ✅ shape matches | | `cosign-signing-key` (Opaque, keys: `cosign.key`, `cosign.password`, `cosign.pub`) | ✅ shape matches | Other Codeberg secrets in the namespace ruled out: - `codeberg-pusher` — `kubernetes.io/dockerconfigjson`, wrong shape - `codeberg-runner-openshift-pac` — PaC per-repo, `read:repository + write:repository.status` scope only - `codeberg-org-op1st-pipelines` — PaC controller identity (org token + webhook HMAC) Operator-confirmable preconditions (verified, cannot be checked from cluster): - ✅ `op1st-release-token.token` carries `write:repository` on `goern/forgejo-mcp` - ✅ `cosign-signing-key.cosign.pub` bytes match `secrets/cosign.pub@791ef6d` Pipeline is ready. Next `v*` tag push triggers the Tekton run alongside the existing `.forgejo/workflows/release.yml`. Cutover stays deferred until 2 consecutive Tekton releases satisfy the ADR criteria.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
agentic-forges/forgejo-mcp!150
No description provided.