diff --git a/.gitea/scripts/bats-coverage.sh b/.gitea/scripts/bats-coverage.sh index 7b552b9..ce34c87 100755 --- a/.gitea/scripts/bats-coverage.sh +++ b/.gitea/scripts/bats-coverage.sh @@ -1,39 +1,16 @@ #!/usr/bin/env bash set -euo pipefail -COVERAGE_VOLUME="${2:+${1:-}}" -REPORT_DIR="${2:-${1:-}}" +REPORT_DIR="${1:-}" +COVERAGE_DIR="${REPORT_DIR}/coverage" [ -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 - 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" - cp -a coverage/. "$COVERAGE_DIR/" - echo "DEBUG[bats-coverage]: copied to $COVERAGE_DIR" >&2 - fi +if [ -d coverage ]; then + mkdir -p "$COVERAGE_DIR" + cp -a coverage/. "$COVERAGE_DIR/" 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 SHA8="${GITHUB_SHA:0:8}" { diff --git a/scripts/ci-report.sh b/scripts/ci-report.sh index 8890b32..9cc1dd7 100644 --- a/scripts/ci-report.sh +++ b/scripts/ci-report.sh @@ -28,19 +28,6 @@ while IFS= read -r -d '' d; do [ -f "$d/index.html" ] && SUBDIRS+=("$name") 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[@]} )) if [ "$TOTAL" -eq 0 ]; then diff --git a/skills/consumer-pipelines/SKILL.md b/skills/consumer-pipelines/SKILL.md index 385bc7d..ebc269f 100644 --- a/skills/consumer-pipelines/SKILL.md +++ b/skills/consumer-pipelines/SKILL.md @@ -142,6 +142,15 @@ valmiin `ci-container-build-.yml`-pohjan jossa `workflow_dispatch`-tuki Ainoa sallittu tapa on `container:`-direktiivi. `docker run` komennolla kontin 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 jobs: : @@ -172,7 +181,7 @@ jobs: ``` 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). **Mallit:** @@ -215,7 +224,7 @@ omassa stepissään** — älä koskaan niputa useaa post-process-komentoa samaa - name: Post-process coverage if: always() - run: + run: /coverage/-hakemistoon> - name: Post-process test report if: always() @@ -226,13 +235,17 @@ omassa stepissään** — älä koskaan niputa useaa post-process-komentoa samaa run: bash .ci/scripts/ci-report.sh "" ``` +**Huomio subdir-sisällöstä:** Jos testi tuottaa dataa alihakemistoon (esim. +coverage `./coverage/`-kansioon), se pitää erikseen SIIRTÄÄ +`reports///`-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 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 että jokainen post-process-vaihe ajetaan itsenäisesti. -**Malli:** `example-bats-tests.yml`. - ### Monta raportoitavaa tiedostoa Kun `reports//`-hakemistossa on useita tiedostoja tai alihakemistoja, @@ -241,12 +254,92 @@ on enemmän kuin yksi raportoitava item. ``` reports// -├── results.txt ← testin stdout -├── junit.xml ← testin JUnit XML -output -└── junit.html ← generoitu HTML (xsltproc, tms.) +├── results.txt ← testin stdout (skannataan FILES) +├── test-report.html ← generoitu HTML (skannataan FILES) +└── / ← 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//`-hakemistoa. + +### Mitä skannataan + +| Mitä | Sääntö | +|---|---| +| **Tiedostot (FILES)** | Kaikki `reports//`-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//index.html`-sivun, linkit kaikkiin itemeihin | + +### Esimerkki: coverage-näkymä + +``` +reports//coverage/index.html ← on olemassa +``` + +Coverage-dataa ei siirretä automaattisesti. Testin tai post-process-stepin pitää +siirtää coverage `reports//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 tiedostot löytyvät nopeasti ja niiden rooli on selvillä: @@ -265,7 +358,7 @@ Single repossa `` jätetään pois — tiedostot ovat suoraan `ci-f Monorepossa prefiksi pitää komponentin tiedostot yhdessä: `ls .*` löytää kaikki kerralla. -## 7. Artifact-kuri +## 9. Artifact-kuri 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ä.