push als String statt Boolean, dazu ein Diagnoseschritt #6

Merged
jklein merged 1 commits from push-als-string into main 2026-09-30 19:32:39 +02:00
2 changed files with 88 additions and 14 deletions

No files matched your search

+52 -7
View File
@@ -28,16 +28,37 @@ on:
required: false
default: '0'
type: string
# Bewusst `type: string` und nicht `boolean` — siehe Issue #4. Auf dieser
# Gitea-Version (gemessen an 1.27.0) kommt eine boolesche
# workflow_call-Eingabe im aufgerufenen Workflow gar nicht an: weder ihre
# Vorgabe noch ein ausdruecklich uebergebenes `push: true`. `inputs.push`
# war in beiden Faellen leer, der Baustein baute immer im Pruefmodus und
# meldete dabei Erfolg. Alle Eingaben vom Typ string desselben Laufs
# (platforms, registry, image-owner, container-name) kamen korrekt an;
# push war die einzige boolesche und die einzige, die versagte.
#
# Wer das beim naechsten Aufraeumen "korrekt" auf boolean zurueckstellt,
# holt den Fehler still zurueck: nichts wird veroeffentlicht, und der
# Lauf bleibt gruen.
#
# Die Bedingung `inputs.push && inputs.push != 'false'` musste dafuer
# nicht angefasst werden. Sie wurde seinerzeit ausdruecklich so gebaut,
# dass sie Boolean und String vertraegt (Begruendung am
# 1Password-Schritt), und traegt die Umstellung unveraendert: 'true' ist
# truthy und ungleich 'false', 'false' ist truthy aber gleich 'false'.
push:
description: >-
Whether the built image is pushed. With push: false no credentials are
fetched from 1Password and no registry login happens, so the workflow
doubles as a build check. Caveat: the checkout token comes from the
same 1Password step, so without push the checkout falls back to the
job token — which cannot clone private submodules.
Whether the built image is pushed, as the string 'true' or 'false'.
Deliberately a string, not a boolean: boolean workflow_call inputs do
not reach the called workflow on this Gitea version (see issue #4).
With push: 'false' no credentials are fetched from 1Password and no
registry login happens, so the workflow doubles as a build check.
Caveat: the checkout token comes from the same 1Password step, so
without push the checkout falls back to the job token — which cannot
clone private submodules.
required: false
default: true
type: boolean
default: 'true'
type: string
container-name:
required: true
type: string
@@ -113,6 +134,24 @@ jobs:
# gesetzt, bleibt die Variable leer und Docker nutzt seinen Default.
DOCKER_HOST: ${{ vars.DOCKER_HOST }}
steps:
# Issue #4 blieb so lange unbemerkt, weil nirgends sichtbar war, was
# ueberhaupt ankommt — und weil ein Lauf ohne Push genauso gruen aussieht
# wie einer mit. Der Schritt macht beides sichtbar: den rohen Wert der
# Eingabe und den daraus abgeleiteten Modus. Gleiches Muster wie
# "Docker-Socket ermitteln": rein informativ, mit `|| true` abgesichert,
# damit er den Job unter keinen Umstaenden scheitern laesst.
#
# Der Wert wird ueber die Umgebung gereicht statt in die Kommandozeile
# interpoliert; so bleibt er auch dann harmlos, wenn ein Aufrufer etwas
# Unerwartetes uebergibt.
- name: Eingaben melden
env:
PUSH_ROH: ${{ inputs.push }}
PUSH_MODUS: ${{ (inputs.push && inputs.push != 'false') && 'veroeffentlichen' || 'nur bauen' }}
run: |
echo "push (roh): '${PUSH_ROH}'" || true
echo "Modus: ${PUSH_MODUS}" || true
# Der Token, den Gitea jedem Job stellt, taugt fuer zwei Dinge nicht:
# Er gilt nur fuer das ausfuehrende Repository, waehrend die Submodule in
# eigenen, privaten Repositories liegen — deren Klon scheitert an
@@ -135,6 +174,12 @@ jobs:
# Strings sind truthy), `inputs.push == 'true'` waere beim echten Boolean
# true falsch (ein Vergleich ueber Typgrenzen laeuft ueber Zahlen, 'true'
# wird dabei zu NaN). Die Kombination aus beidem deckt alle vier Faelle ab.
#
# Genau deshalb blieb sie bei der Umstellung von push auf `type: string`
# (Issue #4) unveraendert: sie war von Anfang an fuer beide Schreibweisen
# gebaut. 'true' ergibt wahr, 'false' ergibt falsch, ein leerer Wert
# ergibt falsch — und die Boolean-Faelle gelten unveraendert weiter,
# falls ein Aufrufer doch einmal ein YAML-Boolean uebergibt.
- name: Zugangsdaten aus 1Password laden
id: op-secrets
if: ${{ inputs.push && inputs.push != 'false' }}
+36 -7
View File
@@ -25,7 +25,7 @@ Gepusht wird unter fünf Tags:
Der Checkout holt Submodule mit; die Zugangsdaten dafür und für die Registry
kommen zur Laufzeit aus 1Password Connect.
Mit `push: false` entfällt der Push — der Baustein baut dann nur. Damit nutzt
Mit `push: 'false'` entfällt der Push — der Baustein baut dann nur. Damit nutzt
die CI eines Projekts dieselbe Bau-Logik wie das Deployment, statt sie zu
duplizieren. Siehe [Prüfmodus](#prüfmodus-ohne-push).
@@ -37,7 +37,7 @@ duplizieren. Siehe [Prüfmodus](#prüfmodus-ohne-push).
| `dockerfile` | ja | — | Pfad zum Dockerfile |
| `docker-context` | ja | — | Build-Kontext |
| `image-owner` | ja | — | Eigentümer-Segment des Images, also der mittlere Teil von `<registry>/<owner>/<name>` |
| `push` | nein | `true` | Ob das Image gepusht wird. Bei `false` werden keine Zugangsdaten aus 1Password geholt und es findet kein Registry-Login statt — siehe [Prüfmodus](#prüfmodus-ohne-push) |
| `push` | nein | `'true'` | Zeichenkette `'true'` oder `'false'`. Ob das Image gepusht wird. Bei `'false'` werden keine Zugangsdaten aus 1Password geholt und es findet kein Registry-Login statt — siehe [Prüfmodus](#prüfmodus-ohne-push) |
| `registry` | nein | `git.jk-dev.de` | Registry, für die getaggt und — beim Push — bei der angemeldet wird |
| `version-number` | nein | `0.0.0` | Vollständige Version, wird als Tag gesetzt |
| `version-number-major` | nein | `0` | Major-Anteil für die mitwandernden Tags |
@@ -52,6 +52,23 @@ ist je Projekt verschieden und soll nie stillschweigend geraten werden — genau
das war der Fehler des früher fest verdrahteten `suer`, unter dem die Images
aller Projekte landeten. Die Registry ist dagegen praktisch immer dieselbe.
`push` ist eine Zeichenkette und kein Boolean — und das ist Absicht. Auf dieser
Gitea-Version (gemessen an 1.27.0) werden **boolesche `workflow_call`-Eingaben
nicht an den aufgerufenen Workflow durchgereicht**: Weder ihre Vorgabe noch ein
ausdrücklich übergebenes `push: true` kamen an, `inputs.push` blieb leer, und
der Baustein baute immer im Prüfmodus — bei grünem Lauf. Alle Eingaben vom Typ
`string` kamen im selben Lauf korrekt an. Details in
[Issue #4](https://git.jk-dev.de/workflow-util/pipelines/issues/4).
Deshalb bitte immer in Anführungszeichen schreiben: `push: 'true'` bzw.
`push: 'false'`. Ein unquotiertes `push: false` ist im YAML ein Boolean und
wird verschluckt.
> **Brechende Änderung gegenüber `v1`.** Aufrufer, die `push` als YAML-Boolean
> übergeben, müssen auf `@v2` wechseln und dabei auf die Schreibweise mit
> Anführungszeichen umstellen. Wer `@v1` weiterverwendet, behält das alte
> Verhalten samt Fehler.
Die vier Versionsangaben dienen ausschließlich der Tag-Liste. Sie sind keine
Pflicht mehr, damit ein Prüflauf keine Platzhalter erfinden muss; wer pusht,
übergibt sie wie bisher. Ihre Vorgabe ist bewusst `0.0.0` und nicht leer — die
@@ -63,7 +80,7 @@ Tag-Liste wird auch ohne Push gebildet, und ein leerer Wert ergäbe das ungülti
```yaml
jobs:
image:
uses: workflow-util/pipelines/.gitea/workflows/docker-build-push.yml@v1
uses: workflow-util/pipelines/.gitea/workflows/docker-build-push.yml@v2
with:
version-number: 2026.09.1
version-number-major: '2026'
@@ -73,6 +90,7 @@ jobs:
dockerfile: ./Dockerfile
docker-context: .
image-owner: bekemeyer-klein
push: 'true'
secrets: inherit
```
@@ -81,7 +99,7 @@ dem aufrufenden Repository.
#### Prüfmodus ohne Push
Mit `push: false` baut der Baustein nur und veröffentlicht nichts. Es werden
Mit `push: 'false'` baut der Baustein nur und veröffentlicht nichts. Es werden
dann keine Zugangsdaten aus 1Password geholt und es findet kein Registry-Login
statt. Die CI eines Projekts nutzt damit dieselbe Bau-Logik wie das Deployment,
statt sie zu duplizieren.
@@ -91,15 +109,21 @@ Weder Secrets noch Versionsangaben sind dafür nötig:
```yaml
jobs:
build-check:
uses: workflow-util/pipelines/.gitea/workflows/docker-build-push.yml@v1
uses: workflow-util/pipelines/.gitea/workflows/docker-build-push.yml@v2
with:
container-name: bk-dev-website
dockerfile: ./Dockerfile
docker-context: .
image-owner: bekemeyer-klein
push: false
push: 'false'
```
Die Anführungszeichen sind nicht kosmetisch: `push: false` ohne sie ist ein
YAML-Boolean und kommt im Baustein nicht an (siehe oben). Es griffe dann die
Vorgabe `'true'`, der Lauf versuchte also trotz `push: false` zu
veröffentlichen — sofern Gitea die Typabweichung nicht ohnehin als Fehler
zurückweist.
> **Private Submodule funktionieren in diesem Modus nicht.**
> Der Checkout-Token stammt aus demselben 1Password-Schritt, der ohne Push
> übersprungen wird. Der Checkout fällt deshalb auf den Standard-Token des Jobs
@@ -129,7 +153,7 @@ und müssen in Gitea nicht hinterlegt werden.
Aufrufe bitte immer an einen Tag binden:
```yaml
uses: workflow-util/pipelines/.gitea/workflows/docker-build-push.yml@v1 # so
uses: workflow-util/pipelines/.gitea/workflows/docker-build-push.yml@v2 # so
uses: workflow-util/pipelines/.gitea/workflows/docker-build-push.yml@main # nicht so
```
@@ -140,3 +164,8 @@ im jeweiligen Projekt.
Änderungen hier bekommen deshalb einen neuen Tag. Bricht eine Änderung
bestehende Aufrufe, wird der Major-Anteil erhöht.
`v2` ist genau so ein Fall: Die Umstellung von `push` auf `type: string` bricht
Aufrufe, die den Wert als YAML-Boolean übergeben. `v1` bleibt unverändert
stehen; wer umstellt, wechselt auf `@v2` und schreibt `push: 'true'` bzw.
`push: 'false'`.