refaktorointia
CI Feature / Validate CI config (push) Successful in 20s
ci-cucumber Cucumber tests OK
CI Feature / Cucumber tests (push) Successful in 1m5s
ci-build Build complete
CI Feature / Report Index (push) Successful in 18s
CI Feature / Load gitea-env.conf to pipeline env (push) Successful in 11s
ci-validate CI config valid
ci-bats Bats tests OK
CI Feature / Bats tests (push) Successful in 1m42s

This commit is contained in:
moilanik
2026-06-15 15:59:35 +03:00
parent 6988488e04
commit 0b683a7166
5 changed files with 188 additions and 18 deletions
+73
View File
@@ -0,0 +1,73 @@
# 8. Exit code — ainoa onnistumisen mittari
## Päätös
Jokaisen `run`-stepin on nostettava virheellinen exit-koodi ylös sellaisenaan.
Exit-koodia ei saa "syödä" missään tilanteessa. Onnistumisen ja epäonnistumisen
päättely tapahtuu **ainoastaan** exit-koodin perusteella — ei tiedostojen
olemassaolon, stdout-tulosteen tai minkään muun heuristiikan perusteella.
## Periaatteet
1. Exit-koodi on ainoa totuus. `0` = onnistui, kaikki muut = epäonnistui.
2. Exit-koodia ei saa syödä. Pipe (`|`) viimeisenä komentona `tee`:hen syö
exit-koodin — `docker run … | tee file` palauttaa aina 0.
3. Data transfer -pipet ovat sallittuja (`tar c . | docker run … tar x`),
koska niiden exit-koodilla ei ole semanttista merkitystä.
4. Testien tai työkalujen ajaminen ei saa päättyä pipeen.
5. `set -o pipefail` ei ole riittävä suojaus — PIPESTATUS resetoituu herkästi.
## Sallitut patternit
```yaml
# Oikein: suora ajo, exit koodi $?:iin
- name: Do work
run: |
some-command
EXIT=$?
echo "EXIT=${EXIT}" >> "${GITHUB_ENV}"
exit ${EXIT}
# Oikein: stdout talteen ilman pipeä
- name: Do work
run: |
some-command > results.txt 2>&1
EXIT=$?
echo "EXIT=${EXIT}" >> "${GITHUB_ENV}"
exit ${EXIT}
# Oikein: docker run ilman pipeä
- name: Run in container
run: |
docker run --rm image command > output.txt 2>&1
EXIT=$?
exit ${EXIT}
```
## Kielletyt patternit
```yaml
# Väärin: pipe syö exit-koodin
- run: docker run … | tee results.txt
# Väärin: pipe syö exit-koodin
- run: tar … | docker … | tee file
# Väärin: onnistumisen päättely tiedoston olemassaolosta
- run: |
some-command || true
[ -f success.txt ] && exit 0 || exit 1
```
## Tausta
Gitea Actionsissa `run`-stepin tila määräytyy viimeisen komennon exit-koodista.
Pipe (`|`) asettaa `$?`:ksi viimeisen komennon tuloksen — jos viimeinen komento
on `tee`, tulos on aina 0 riippumatta siitä mitä aiemmat komennot palauttivat.
Tämä on aiheuttanut tuotannossa tilanteita, joissa testit feilasivat mutta jobi
näytti vihreää, koska `tee` söi exit-koodin. Virhe havaittiin vasta kun raportteja
alettiin lukea manuaalisesti — commit-status valehteli.
Ratkaisu on yksiselitteinen: exit-koodi talteen `$?`-muuttujaan ennen kuin mikään
muu komento ehtii muuttaa sitä, ja stepin viimeinen komento on aina `exit ${EXIT}`.