CI-Pipelines
Jedes Release liefert yasrt-linux-{amd64,arm64} und yasrt-darwin-{arm64,amd64} mit SHA256SUMS und einer detached cosign-Signatur darüber. Die Binaries werden einmal in meiner Pipeline gebaut und signiert; auf GitHub liegen dieselben Dateien, dort wird nichts neu gebaut.
- Binary:
go install github.com/ohartwig/yasrt/cmd/yasrt@latestoder die signierten Releases - Image:
registry.ole-hartwig.eu/devops/images/yasrt:1trägt das Binary mitgit,gpgundssh-keygen - Prüfen:
cosign verify-blob --key <public-key> --signature SHA256SUMS.sig --insecure-ignore-tlog=true SHA256SUMS, dannsha256sum -c SHA256SUMS
GitLab CI
stages: [version, build, release]
default:
image:
name: registry.ole-hartwig.eu/devops/images/yasrt:1
entrypoint: [""]
version:
stage: version
variables: { GIT_DEPTH: 0 } # yasrt braucht die ganze Historie
script: yasrt next --output .release.env
artifacts:
reports: { dotenv: .release.env }
rules: [{ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH }]
build:
stage: build
image: dein/build-image
script:
- '[ "$RELEASE_STATUS" = "release" ] || exit 0' # im Script gaten, nicht in rules:
- make build VERSION=$RELEASE_VERSION
rules: [{ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH }]
release:
stage: release
variables: { GIT_DEPTH: 0 }
script: yasrt release
rules: [{ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH }]
GitLab wertet rules: aus, wenn die Pipeline entsteht, bevor .release.env existiert. Downstream-Jobs gaten deshalb im Script auf RELEASE_STATUS. Das Projekt muss Job-Token-Pushes erlauben (Settings → CI/CD → Job token permissions → Allow Git push requests to the repository), und wer auf den Default-Branch mergen darf, muss den Release-Tag anlegen dürfen; yasrt check prüft beides. Ein Push mit dem Job-Token startet keine Pipeline, und genau das verhindert, dass der Release-Commit sich selbst noch einmal released.
Ein Repository, dessen Veröffentlichung auf dem Tag laufen muss (etwa weil das OIDC-Vertrauen einer Signierrolle auf ref_type:tag begrenzt ist), behält diese Pipeline, indem das Release sie startet: after_release.triggers expandiert ${tag}, ${version} und CI-Variablen in project, ref und variables; { project: "${CI_PROJECT_PATH}", ref: "${tag}" } startet die Tag-Pipeline, die der Job-Token-Push nicht gestartet hat.
Ein Trigger geht mit dem Job-Token raus, es sei denn, der Eintrag nennt mit token_var eine Variable mit einem Pipeline-Trigger-Token des Zielprojekts. Der Unterschied ist, als wer die gestartete Pipeline läuft: mit dem Job-Token als der Nutzer hinter dem Release-Job, der im Zielprojekt Pipelines starten dürfen muss; mit einem Trigger-Token als dessen Besitzer, egal wer gemerged hat.
Eine CI/CD-Komponente mit dieser Form (version, release, eine geteilte Defaults-Schicht, product und tag-format als Inputs) liegt auf meiner Instanz unter devops/ci-cd-components/release-tools.
GitHub Actions und Forgejo Actions
permissions: { contents: write }
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with: { fetch-depth: 0 }
- run: yasrt next --output .release.env
- run: make build # gatet innen auf RELEASE_STATUS
- run: yasrt release
env: { GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} } # FORGEJO_TOKEN auf Forgejo
Ein Push mit GITHUB_TOKEN startet keinen Workflow, der Changelog-Commit released sich also nicht selbst. Wo die Plattform an ihren Variablen nicht zu erkennen ist, sag --forge gitlab|github|forgejo oder setz YASRT_FORGE. Vollständige Dateien liegen unter docs/examples im Repository.
Weiter
Konfiguration und Hooks
Eine Zeile pro Repository, Organisationsdefaults darunter, Hooks an fünf Punkten des Releases.