skill päivitetty! uusi conventio cunsumer pipeline toteutukseen
CI Feature / Load example-gitea-env.conf to pipeline env (push) Successful in 19s
acc-tests Link to Cucumber reports
CI Feature / Cucumber tests (push) Successful in 1m12s
unit-tests Link to Bats reports
CI Feature / Bats tests (push) Successful in 1m37s
CI Feature / Report Summary (push) Successful in 5s
CI Feature / Load example-gitea-env.conf to pipeline env (push) Successful in 19s
acc-tests Link to Cucumber reports
CI Feature / Cucumber tests (push) Successful in 1m12s
unit-tests Link to Bats reports
CI Feature / Bats tests (push) Successful in 1m37s
CI Feature / Report Summary (push) Successful in 5s
This commit is contained in:
@@ -1,38 +1,15 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
COVERAGE_VOLUME="${2:+${1:-}}"
|
REPORT_DIR="${1:-}"
|
||||||
REPORT_DIR="${2:-${1:-}}"
|
COVERAGE_DIR="${REPORT_DIR}/coverage"
|
||||||
|
|
||||||
[ -n "$REPORT_DIR" ] || { echo "ERROR: report directory required" >&2; exit 1; }
|
[ -n "$REPORT_DIR" ] || { echo "ERROR: report directory required" >&2; exit 1; }
|
||||||
|
|
||||||
COVERAGE_DIR="$REPORT_DIR/coverage"
|
|
||||||
|
|
||||||
if [ -n "$COVERAGE_VOLUME" ]; then
|
|
||||||
echo "DEBUG[bats-coverage]: OLD convention — extracting from volume '$1' to '$REPORT_DIR'" >&2
|
|
||||||
if docker run --rm -v "$COVERAGE_VOLUME":/data alpine sh -c '
|
|
||||||
[ -d /data/coverage ] && ls -A /data/coverage | grep -q .
|
|
||||||
' 2>/dev/null; then
|
|
||||||
echo "DEBUG[bats-coverage]: coverage found in volume $COVERAGE_VOLUME" >&2
|
|
||||||
mkdir -p "$COVERAGE_DIR"
|
|
||||||
docker run --rm -v "$COVERAGE_VOLUME":/data alpine tar c -C /data/coverage . | tar x -C "$COVERAGE_DIR"
|
|
||||||
echo "DEBUG[bats-coverage]: extracted from volume to $COVERAGE_DIR" >&2
|
|
||||||
else
|
|
||||||
echo "DEBUG[bats-coverage]: no coverage in volume $COVERAGE_VOLUME" >&2
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "DEBUG[bats-coverage]: NEW convention — copying from ./coverage/ to '$REPORT_DIR'" >&2
|
|
||||||
echo "DEBUG[bats-coverage]: coverage dir exists? $([ -d coverage ] && echo YES || echo NO)" >&2
|
|
||||||
if [ -d coverage ]; then
|
if [ -d coverage ]; then
|
||||||
echo "DEBUG[bats-coverage]: files in coverage/: $(ls coverage/ 2>/dev/null | wc -l)" >&2
|
|
||||||
echo "DEBUG[bats-coverage]: coverage/index.html exists? $([ -f coverage/index.html ] && echo YES || echo NO)" >&2
|
|
||||||
mkdir -p "$COVERAGE_DIR"
|
mkdir -p "$COVERAGE_DIR"
|
||||||
cp -a coverage/. "$COVERAGE_DIR/"
|
cp -a coverage/. "$COVERAGE_DIR/"
|
||||||
echo "DEBUG[bats-coverage]: copied to $COVERAGE_DIR" >&2
|
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
echo "DEBUG[bats-coverage]: target $COVERAGE_DIR/index.html exists? $([ -f "$COVERAGE_DIR/index.html" ] && echo YES || echo NO)" >&2
|
|
||||||
|
|
||||||
if [ -d "$COVERAGE_DIR" ] && [ ! -f "$COVERAGE_DIR/index.html" ]; then
|
if [ -d "$COVERAGE_DIR" ] && [ ! -f "$COVERAGE_DIR/index.html" ]; then
|
||||||
SHA8="${GITHUB_SHA:0:8}"
|
SHA8="${GITHUB_SHA:0:8}"
|
||||||
|
|||||||
@@ -28,19 +28,6 @@ while IFS= read -r -d '' d; do
|
|||||||
[ -f "$d/index.html" ] && SUBDIRS+=("$name")
|
[ -f "$d/index.html" ] && SUBDIRS+=("$name")
|
||||||
done < <(find "$REPORT_DIR" -maxdepth 1 -type d ! -name . -print0 2>/dev/null || true)
|
done < <(find "$REPORT_DIR" -maxdepth 1 -type d ! -name . -print0 2>/dev/null || true)
|
||||||
|
|
||||||
echo "DEBUG[ci-report]: REPORT_DIR=$REPORT_DIR" >&2
|
|
||||||
echo "DEBUG[ci-report]: files found (${#FILES[@]}): ${FILES[*]:-}" >&2
|
|
||||||
echo "DEBUG[ci-report]: subdirs with index.html (${#SUBDIRS[@]}): ${SUBDIRS[*]:-}" >&2
|
|
||||||
echo "DEBUG[ci-report]: TOTAL=$(( ${#FILES[@]} + ${#SUBDIRS[@]} ))" >&2
|
|
||||||
echo "DEBUG[ci-report]: ls -la $REPORT_DIR/:" >&2
|
|
||||||
find "$REPORT_DIR" -maxdepth 2 -not -path '*/\.*' 2>/dev/null | while IFS= read -r p; do
|
|
||||||
if [ -f "$p" ]; then
|
|
||||||
echo " FILE $(basename "$p")" >&2
|
|
||||||
elif [ -d "$p" ] && [ "$p" != "$REPORT_DIR" ]; then
|
|
||||||
echo " DIR $(basename "$p")/ has-index.html=$([ -f "$p/index.html" ] && echo YES || echo NO)" >&2
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
TOTAL=$(( ${#FILES[@]} + ${#SUBDIRS[@]} ))
|
TOTAL=$(( ${#FILES[@]} + ${#SUBDIRS[@]} ))
|
||||||
|
|
||||||
if [ "$TOTAL" -eq 0 ]; then
|
if [ "$TOTAL" -eq 0 ]; then
|
||||||
|
|||||||
@@ -142,6 +142,15 @@ valmiin `ci-container-build-<kontti>.yml`-pohjan jossa `workflow_dispatch`-tuki
|
|||||||
Ainoa sallittu tapa on `container:`-direktiivi. `docker run` komennolla kontin
|
Ainoa sallittu tapa on `container:`-direktiivi. `docker run` komennolla kontin
|
||||||
käynnistäminen stepin sisällä on anti-pattern.
|
käynnistäminen stepin sisällä on anti-pattern.
|
||||||
|
|
||||||
|
**Miksi:** `docker run` erilliskonttina aiheuttaa:
|
||||||
|
- Tiedostojen jako vaatii erillisen volyyminhallinnan (`docker volume create`)
|
||||||
|
- Coverage-data jää volyymiin, ei filesystemille → post-process-skriptit eivät löydä sitä
|
||||||
|
- Ylimääräisiä siirtoja (`tar`, `docker cp`), jotka voivat epäonnistua hiljaa
|
||||||
|
- Vaikeampi debugata (data on kontissa, ei CWD:ssä)
|
||||||
|
|
||||||
|
`container:`-direktiivillä kaikki ajetaan samassa kontissa — tiedostot ovat suoraan
|
||||||
|
filesystemillä, post-process-skriptit näkevät ne ilman erillistä siirtoa.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
jobs:
|
jobs:
|
||||||
<työkalu>:
|
<työkalu>:
|
||||||
@@ -172,7 +181,7 @@ jobs:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Jos testi tuottaa raportteja suoraan ilman jälkikäsittelyä, Post-process-steppiä ei tarvita.
|
Jos testi tuottaa raportteja suoraan ilman jälkikäsittelyä, Post-process-steppiä ei tarvita.
|
||||||
Jos jälkikäsittely on tarpeen (coverage-extraktio, HTML-generointi raa'asta outputista),
|
Jos jälkikäsittely on tarpeen (coverage-siirto, HTML-generointi raa'asta outputista),
|
||||||
se tehdään omassa stepissä `if: always()` — katso tarkemmin [Raporttitasot](#5-raporttitasot).
|
se tehdään omassa stepissä `if: always()` — katso tarkemmin [Raporttitasot](#5-raporttitasot).
|
||||||
|
|
||||||
**Mallit:**
|
**Mallit:**
|
||||||
@@ -215,7 +224,7 @@ omassa stepissään** — älä koskaan niputa useaa post-process-komentoa samaa
|
|||||||
|
|
||||||
- name: Post-process coverage
|
- name: Post-process coverage
|
||||||
if: always()
|
if: always()
|
||||||
run: <coverage-extraktio>
|
run: <siirrä coverage-data reports/<suite>/coverage/-hakemistoon>
|
||||||
|
|
||||||
- name: Post-process test report
|
- name: Post-process test report
|
||||||
if: always()
|
if: always()
|
||||||
@@ -226,13 +235,17 @@ omassa stepissään** — älä koskaan niputa useaa post-process-komentoa samaa
|
|||||||
run: bash .ci/scripts/ci-report.sh "<kuvaus>" <context> <suite>
|
run: bash .ci/scripts/ci-report.sh "<kuvaus>" <context> <suite>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Huomio subdir-sisällöstä:** Jos testi tuottaa dataa alihakemistoon (esim.
|
||||||
|
coverage `./coverage/`-kansioon), se pitää erikseen SIIRTÄÄ
|
||||||
|
`reports/<suite>/<subdir>/`-hakemistoon ennen `ci-report.sh`:n ajoa.
|
||||||
|
Ilman siirtoa sisältö ei näy index-sivulla, vaikka työkalu tuottaisi sen oikein.
|
||||||
|
Subdir vaatii lisäksi `index.html`:n, jotta `ci-report.sh` löytää sen.
|
||||||
|
|
||||||
**Miksi:** Gitea Actions käyttää `bash -e`-oletusta. Jos yksi post-process-komento
|
**Miksi:** Gitea Actions käyttää `bash -e`-oletusta. Jos yksi post-process-komento
|
||||||
epäonnistuu (esim. `set -euo pipefail`-skripti), koko stepi pysähtyy eivätkä seuraavat
|
epäonnistuu (esim. `set -euo pipefail`-skripti), koko stepi pysähtyy eivätkä seuraavat
|
||||||
komennot käynnisty — raportti jää julkaisematta. Erilliset stepit `if: always()` takaavat
|
komennot käynnisty — raportti jää julkaisematta. Erilliset stepit `if: always()` takaavat
|
||||||
että jokainen post-process-vaihe ajetaan itsenäisesti.
|
että jokainen post-process-vaihe ajetaan itsenäisesti.
|
||||||
|
|
||||||
**Malli:** `example-bats-tests.yml`.
|
|
||||||
|
|
||||||
### Monta raportoitavaa tiedostoa
|
### Monta raportoitavaa tiedostoa
|
||||||
|
|
||||||
Kun `reports/<suite>/`-hakemistossa on useita tiedostoja tai alihakemistoja,
|
Kun `reports/<suite>/`-hakemistossa on useita tiedostoja tai alihakemistoja,
|
||||||
@@ -241,12 +254,92 @@ on enemmän kuin yksi raportoitava item.
|
|||||||
|
|
||||||
```
|
```
|
||||||
reports/<suite>/
|
reports/<suite>/
|
||||||
├── results.txt ← testin stdout
|
├── results.txt ← testin stdout (skannataan FILES)
|
||||||
├── junit.xml ← testin JUnit XML -output
|
├── test-report.html ← generoitu HTML (skannataan FILES)
|
||||||
└── junit.html ← generoitu HTML (xsltproc, tms.)
|
└── <mikä tahansa>/ ← alihakemisto (skannataan SUBDIRS)
|
||||||
|
└── index.html ← VAIN jos tämä on olemassa
|
||||||
```
|
```
|
||||||
|
|
||||||
## 6. Nimeäminen
|
**Subdir-sääntö:** Alihakemisto näkyy indexissä VAIN jos se sisältää `index.html`:n.
|
||||||
|
Pelkkä tyhjä subdir ilman `index.html`:ää ei näy — tämä on yleisin syy miksi
|
||||||
|
jokin raportin osa (kuten coverage) puuttuu indexistä.
|
||||||
|
|
||||||
|
## 6. Raportin julkaisukelpoisuus
|
||||||
|
|
||||||
|
`ci-report.sh` päättää onko raportti julkaisukelpoinen skannaamalla
|
||||||
|
`reports/<suite>/`-hakemistoa.
|
||||||
|
|
||||||
|
### Mitä skannataan
|
||||||
|
|
||||||
|
| Mitä | Sääntö |
|
||||||
|
|---|---|
|
||||||
|
| **Tiedostot (FILES)** | Kaikki `reports/<suite>/`-juuressa olevat tiedostot paitsi `index.html` |
|
||||||
|
| **Alihakemistot (SUBDIRS)** | Vain ne, joissa on `index.html` |
|
||||||
|
|
||||||
|
### Julkaisukelpoisuus
|
||||||
|
|
||||||
|
| Tila | Seuraus |
|
||||||
|
|---|---|
|
||||||
|
| `FILES + SUBDIRS = 0` | **Failure** — `ci-report.sh` palauttaa virheen, raporttia ei julkaista |
|
||||||
|
| `FILES + SUBDIRS = 1` | Suora linkki itemiin — ei generoi index-sivua |
|
||||||
|
| `FILES + SUBDIRS > 1` | Generoi `reports/<suite>/index.html`-sivun, linkit kaikkiin itemeihin |
|
||||||
|
|
||||||
|
### Esimerkki: coverage-näkymä
|
||||||
|
|
||||||
|
```
|
||||||
|
reports/<suite>/coverage/index.html ← on olemassa
|
||||||
|
```
|
||||||
|
|
||||||
|
Coverage-dataa ei siirretä automaattisesti. Testin tai post-process-stepin pitää
|
||||||
|
siirtää coverage `reports/<suite>/coverage/`-hakemistoon ja varmistaa että
|
||||||
|
`index.html` on mukana. Sama periaate pätee mihin tahansa subdir-sisältöön.
|
||||||
|
|
||||||
|
## 7. Debug-ohje: raportti ei näy
|
||||||
|
|
||||||
|
### 1. Aja lokaalisti samalla komennolla kuin CI
|
||||||
|
|
||||||
|
Näet mitä tiedostoja syntyy, mihin ne tulevat ja mikä on työkalun exit-koodi.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Esimerkki
|
||||||
|
mkdir -p reports/bats
|
||||||
|
bashcov -- bats tests/ > reports/bats/results.txt 2>&1
|
||||||
|
echo "exit: $?"
|
||||||
|
ls -la reports/bats/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Lisää `echo "DEBUG: ..." >&2` ennen ja jälkeen kriittisen operaation
|
||||||
|
|
||||||
|
Debuggaus stderriin (`>&2`) näkyy CI-logissa eikä häiritse skriptin normaalia outputia.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "DEBUG: coverage exists? $([ -d coverage ] && echo YES || echo NO)" >&2
|
||||||
|
echo "DEBUG: target/index.html exists? $([ -f reports/suite/coverage/index.html ] && echo YES || echo NO)" >&2
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Tarkista kutsuparametrit
|
||||||
|
|
||||||
|
Yleisin virhe: skripti odottaa `$1` = X, mutta kutsuja antaa `$1` = Y ja `$2` = X.
|
||||||
|
Skripti lukee väärän parametrin ja etsii dataa väärästä paikasta.
|
||||||
|
|
||||||
|
### 4. Tarkista tiedostopolut
|
||||||
|
|
||||||
|
1. Onko lähdetiedosto olemassa ennen kopiointia?
|
||||||
|
2. Onko kohde olemassa kopioinnin jälkeen?
|
||||||
|
3. Onko `index.html` subdirissä (vaaditaan `ci-report.sh`:lle)?
|
||||||
|
|
||||||
|
Jos vastaus johonkin on "ei" — tiedät mikä pitää korjata.
|
||||||
|
|
||||||
|
### 5. Poista debug-echot kun ongelma on korjattu
|
||||||
|
|
||||||
|
Debug-rivit eivät kuulu tuotantoon.
|
||||||
|
|
||||||
|
### 6. Älä kokeile — debuggaa
|
||||||
|
|
||||||
|
Kokeilu = arvaus. Debuggaus = lisää echo, aja, lue logi, eristä ongelma.
|
||||||
|
Vasta sitten korjaa. Tämä on nopeampi tie oikeaan ratkaisuun.
|
||||||
|
|
||||||
|
## 8. Nimeäminen
|
||||||
|
|
||||||
Tiedostonimet `.gitea/workflows/`-kansiossa noudattavat yhtenäistä rakennetta, jotta
|
Tiedostonimet `.gitea/workflows/`-kansiossa noudattavat yhtenäistä rakennetta, jotta
|
||||||
tiedostot löytyvät nopeasti ja niiden rooli on selvillä:
|
tiedostot löytyvät nopeasti ja niiden rooli on selvillä:
|
||||||
@@ -265,7 +358,7 @@ Single repossa `<komponentti>` jätetään pois — tiedostot ovat suoraan `ci-f
|
|||||||
Monorepossa prefiksi pitää komponentin tiedostot yhdessä: `ls <komponentti>.*` löytää kaikki
|
Monorepossa prefiksi pitää komponentin tiedostot yhdessä: `ls <komponentti>.*` löytää kaikki
|
||||||
kerralla.
|
kerralla.
|
||||||
|
|
||||||
## 7. Artifact-kuri
|
## 9. Artifact-kuri
|
||||||
|
|
||||||
Gitea Actionsin `upload-artifact` jättää pysyvän tiedoston. Artifakteja ei käytetä
|
Gitea Actionsin `upload-artifact` jättää pysyvän tiedoston. Artifakteja ei käytetä
|
||||||
workflow_call:ien väliseen datan siirtoon ellei se ole teknisesti välttämätöntä.
|
workflow_call:ien väliseen datan siirtoon ellei se ole teknisesti välttämätöntä.
|
||||||
|
|||||||
Reference in New Issue
Block a user