Compare commits

..

2 Commits

Author SHA1 Message Date
moilanik 11ca47cf1b index.html korjaus
CI Feature / Load example-gitea-env.conf to pipeline env (push) Successful in 20s
unit-tests Link to Bats reports
CI Feature / Bats tests (push) Successful in 1m24s
acc-tests Link to Cucumber reports
CI Feature / Cucumber tests (push) Successful in 51s
CI Feature / Report Summary (push) Successful in 5s
2026-06-18 06:30:21 +03:00
moilanik 31748e98cc uusi report logiikka
CI Feature / Load example-gitea-env.conf to pipeline env (push) Successful in 24s
unit-tests Link to Bats reports
CI Feature / Bats tests (push) Successful in 1m37s
acc-tests Link to Cucumber reports
CI Feature / Cucumber tests (push) Successful in 1m8s
CI Feature / Report Summary (push) Successful in 5s
2026-06-18 06:19:58 +03:00
12 changed files with 48 additions and 295 deletions
+2 -20
View File
@@ -2,28 +2,10 @@
set -euo pipefail set -euo pipefail
REPORT_DIR="${1:-}" REPORT_DIR="${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; }
if [ -d coverage ]; then if [ -d coverage ]; then
mkdir -p "$COVERAGE_DIR" mkdir -p "$REPORT_DIR/coverage"
cp -a coverage/. "$COVERAGE_DIR/" cp -a coverage/. "$REPORT_DIR/coverage/"
fi
if [ -d "$COVERAGE_DIR" ] && [ ! -f "$COVERAGE_DIR/index.html" ]; then
SHA8="${GITHUB_SHA:0:8}"
{
echo '<!DOCTYPE html><html lang="en"><head><meta charset="utf-8">'
echo "<title>Coverage report ${SHA8}</title>"
echo '<style>body{font-family:sans-serif;margin:2em}h1{color:#1e293b}ul{list-style:none;padding:0}li{margin:.5em 0}a{color:#2563eb}</style>'
echo "</head><body><h1>Coverage report <code>${SHA8}</code></h1><ul>"
while IFS= read -r -d '' f; do
base=$(basename "$f")
name="${base%.*}"
name="${name//-/ }"
echo "<li><a href=\"${base}\">${name^}</a></li>"
done < <(find "$COVERAGE_DIR" -maxdepth 1 -type f \( -name '*.html' -o -name '*.txt' \) ! -name index.html -print0 2>/dev/null || true)
echo '</ul></body></html>'
} > "$COVERAGE_DIR/index.html"
fi fi
+6 -9
View File
@@ -6,9 +6,8 @@ on:
required: true required: true
type: string type: string
bats-image: bats-image:
required: false required: true
type: string type: string
default: gitea.app.keskikuja.site/niko/ci-bats:git
secrets: secrets:
GITEA_TOKEN: GITEA_TOKEN:
required: true required: true
@@ -38,14 +37,12 @@ jobs:
mkdir -p reports/bats mkdir -p reports/bats
bashcov -- bats tests/ > reports/bats/results.txt 2>&1 bashcov -- bats tests/ > reports/bats/results.txt 2>&1
- name: Post-process coverage - name: Post-process reports
if: always() if: always()
run: bash .ci/.gitea/scripts/bats-coverage.sh reports/bats run: |
bash .ci/.gitea/scripts/bats-coverage.sh reports/bats
- name: Post-process test report bash .ci/.gitea/scripts/bats-report.sh reports/bats
if: always()
run: bash .ci/.gitea/scripts/bats-report.sh reports/bats
- name: Report - name: Report
if: always() if: always()
run: bash .ci/scripts/ci-report.sh "Bats test report" unit-tests bats ${{ job.status }} run: bash .ci/scripts/ci-report.sh "Bats test report" unit-tests bats
+8 -28
View File
@@ -1,41 +1,21 @@
name: CI Container Build Bats name: Build CI Bats Container (Manual)
on: on: workflow_dispatch
workflow_dispatch:
inputs:
config_path:
required: true
type: string
default: '.gitea/workflows/example-gitea-env.conf'
description: 'Polku .gitea-env.conf-tiedostoon'
dockerfile_path:
required: true
type: string
default: 'Dockerfile.ci-bats'
description: 'Polku Dockerfileen'
image_name:
required: true
type: string
default: 'ci-bats'
description: 'Kontin nimi ilman registry-polkua'
tag:
required: true
type: string
default: 'latest'
description: 'Image-tägi'
jobs: jobs:
load-config: load-config:
name: Load config
uses: niko/gitea-ci-library/.gitea/workflows/config-provider.yml@main uses: niko/gitea-ci-library/.gitea/workflows/config-provider.yml@main
secrets: inherit secrets: inherit
with: with:
config_path: ${{ inputs.config_path }} config_path: .gitea/workflows/example-gitea-env.conf
build-push: build-push:
name: Build & Push
needs: [load-config] needs: [load-config]
uses: niko/gitea-ci-library/.gitea/workflows/ci-container-build-push.yml@main uses: niko/gitea-ci-library/.gitea/workflows/ci-container-build-push.yml@main
secrets: inherit secrets: inherit
with: with:
env_json: ${{ needs.load-config.outputs.env_json }} env_json: ${{ needs.load-config.outputs.env_json }}
dockerfile_path: ${{ inputs.dockerfile_path }} dockerfile_path: Dockerfile.ci-bats
image_name: ${{ inputs.image_name }} image_name: ci-bats
tag: ${{ inputs.tag }} tag: latest
@@ -25,14 +25,14 @@ on:
jobs: jobs:
load-config: load-config:
uses: niko/gitea-ci-library/.gitea/workflows/config-provider.yml@main uses: niko/gitea-ci-library/.gitea/workflows/config-provider.yml@v1
secrets: inherit secrets: inherit
with: with:
config_path: ${{ inputs.config_path }} config_path: ${{ inputs.config_path }}
build-push: build-push:
needs: [load-config] needs: [load-config]
uses: niko/gitea-ci-library/.gitea/workflows/ci-container-build-push.yml@main uses: niko/gitea-ci-library/.gitea/workflows/ci-container-build-push.yml@v1
secrets: inherit secrets: inherit
with: with:
env_json: ${{ needs.load-config.outputs.env_json }} env_json: ${{ needs.load-config.outputs.env_json }}
+4 -5
View File
@@ -6,9 +6,8 @@ on:
required: true required: true
type: string type: string
cucumber-node-image: cucumber-node-image:
required: false required: true
type: string type: string
default: gitea.app.keskikuja.site/niko/ci-cucumber:latest
secrets: secrets:
GITEA_TOKEN: GITEA_TOKEN:
required: true required: true
@@ -38,10 +37,10 @@ jobs:
run: | run: |
mkdir -p reports/cucumber mkdir -p reports/cucumber
npx cucumber-js \ npx cucumber-js \
--format json:reports/cucumber/results.json \ --format json:reports/cucumber/report.json \
--format html:reports/cucumber/test-report.html 2>&1 --format html:reports/cucumber/report.html 2>&1
- name: Report - name: Report
if: always() if: always()
shell: bash shell: bash
run: bash .ci/scripts/ci-report.sh "Cucumber test report" acc-tests cucumber ${{ job.status }} run: bash .ci/scripts/ci-report.sh "Cucumber test report" acc-tests cucumber
+2
View File
@@ -20,6 +20,7 @@ jobs:
secrets: inherit secrets: inherit
with: with:
env_json: ${{ needs.load-config.outputs.env_json }} env_json: ${{ needs.load-config.outputs.env_json }}
bats-image: gitea.app.keskikuja.site/niko/ci-bats:latest
cucumber: cucumber:
name: Cucumber tests name: Cucumber tests
@@ -28,6 +29,7 @@ jobs:
secrets: inherit secrets: inherit
with: with:
env_json: ${{ needs.load-config.outputs.env_json }} env_json: ${{ needs.load-config.outputs.env_json }}
cucumber-node-image: gitea.app.keskikuja.site/niko/ci-cucumber:latest
report-summary: report-summary:
name: Report Summary name: Report Summary
+2
View File
@@ -29,6 +29,7 @@ jobs:
secrets: inherit secrets: inherit
with: with:
env_json: ${{ needs.load-config.outputs.env_json }} env_json: ${{ needs.load-config.outputs.env_json }}
bats-image: gitea.app.keskikuja.site/niko/ci-bats:latest
cucumber: cucumber:
name: Cucumber tests name: Cucumber tests
@@ -38,6 +39,7 @@ jobs:
secrets: inherit secrets: inherit
with: with:
env_json: ${{ needs.load-config.outputs.env_json }} env_json: ${{ needs.load-config.outputs.env_json }}
cucumber-node-image: gitea.app.keskikuja.site/niko/ci-cucumber:latest
build-push: build-push:
name: Build & Push Docker name: Build & Push Docker
+2 -2
View File
@@ -1,3 +1,3 @@
FROM bats/bats:1.11.0 FROM bats/bats:latest
RUN apk add --no-cache lsof python3 jq curl ruby nodejs git && \ RUN apk add --no-cache lsof python3 jq curl ruby && \
gem install bashcov -v 3.3.0 gem install bashcov -v 3.3.0
+1 -2
View File
@@ -123,8 +123,8 @@ Hae token Giteasta:
```bash ```bash
GITEA_URL="https://<gitea-server-url>" GITEA_URL="https://<gitea-server-url>"
GITEA_ACTIONS_NAMESPACE="gitea-actions"
GITEA_ACTIONS_TOKEN="<registration-token>" GITEA_ACTIONS_TOKEN="<registration-token>"
GITEA_ACTIONS_NAMESPACE="gitea-actions"
``` ```
### 3. Tee secret vain init install yhteydessä ### 3. Tee secret vain init install yhteydessä
@@ -158,7 +158,6 @@ helm upgrade --install act-runner gitea/actions \
--set giteaRootURL="$GITEA_URL" \ --set giteaRootURL="$GITEA_URL" \
--set existingSecret=act-runner-token \ --set existingSecret=act-runner-token \
--set existingSecretKey=token \ --set existingSecretKey=token \
--set statefulset.replicas=3 \
--set statefulset.runner.tag=1.0.8 \ --set statefulset.runner.tag=1.0.8 \
--set statefulset.dind.tag=29.5.2-dind \ --set statefulset.dind.tag=29.5.2-dind \
--set-string 'statefulset.runner.config=log: --set-string 'statefulset.runner.config=log:
+2 -3
View File
@@ -4,7 +4,6 @@ set -euo pipefail
DESCRIPTION="${1:-}" DESCRIPTION="${1:-}"
CONTEXT="${2:-}" CONTEXT="${2:-}"
SUITE="${3:-}" SUITE="${3:-}"
STATUS="${4:-success}"
[ -n "$DESCRIPTION" ] || { echo "ERROR: description argument required" >&2; exit 1; } [ -n "$DESCRIPTION" ] || { echo "ERROR: description argument required" >&2; exit 1; }
[ -n "$CONTEXT" ] || { echo "ERROR: context argument required" >&2; exit 1; } [ -n "$CONTEXT" ] || { echo "ERROR: context argument required" >&2; exit 1; }
@@ -76,12 +75,12 @@ if [ "$TOTAL" -eq 1 ]; then
ENTRY="${SUBDIRS[0]}/index.html" ENTRY="${SUBDIRS[0]}/index.html"
fi fi
URL="${GIT_PAGES_URL}/${GITHUB_REPOSITORY}/reports/${SHA8}/${SUITE}/${ENTRY}" URL="${GIT_PAGES_URL}/${GITHUB_REPOSITORY}/reports/${SHA8}/${SUITE}/${ENTRY}"
bash .ci/scripts/report-status.sh "$STATUS" "$DESCRIPTION" "$CONTEXT" "" "$URL" bash .ci/scripts/report-status.sh success "$DESCRIPTION" "$CONTEXT" "" "$URL"
else else
generate_index generate_index
cp -a "$REPORT_DIR/." "$STAGED/" cp -a "$REPORT_DIR/." "$STAGED/"
bash .ci/scripts/publish-git-pages.sh "$SUITE" bash .ci/scripts/publish-git-pages.sh "$SUITE"
bash .ci/scripts/report-status.sh "$STATUS" "$DESCRIPTION" "$CONTEXT" "$SUITE" bash .ci/scripts/report-status.sh success "$DESCRIPTION" "$CONTEXT" "$SUITE"
fi fi
rm -rf "$STAGED" rm -rf "$STAGED"
+1 -36
View File
@@ -33,42 +33,7 @@ else
fi fi
mkdir -p "$TARGET" mkdir -p "$TARGET"
cp -a "$REPORT_DIR/." "$TARGET/" cp -a "$REPORT_DIR/." "$TARGET/"
if [ ! -f "$TARGET/index.html" ]; then cat > "$WORK/${OWNER}/${REPO}/reports/${SHA8}/.meta" <<EOF
items=()
while IFS= read -r -d '' f; do
items+=("$(basename "$f")")
done < <(find "$TARGET" -maxdepth 1 -type f ! -name index.html -print0 2>/dev/null || true)
while IFS= read -r -d '' d; do
name=$(basename "$d")
[ -f "$d/index.html" ] && items+=("$name")
done < <(find "$TARGET" -maxdepth 1 -type d ! -name . -print0 2>/dev/null || true)
if [ ${#items[@]} -gt 1 ]; then
{
echo '<!DOCTYPE html><html lang="en"><head><meta charset="utf-8">'
echo "<title>Test report ${SHA8}</title>"
echo '<style>body{font-family:sans-serif;margin:2em;max-width:960px}'
echo 'h1{color:#1e293b}ul{list-style:none;padding:0}'
echo 'li{margin:.5em 0;padding:.5em;background:#f8fafc;border-radius:6px}'
echo 'a{color:#2563eb;text-decoration:none}a:hover{text-decoration:underline}'
echo '</style></head><body>'
echo "<h1>Test report <code>${SHA8}</code></h1><ul>"
for item in "${items[@]}"; do
label="${item%.*}"
label="${label//-/ }"
label="${label//_/ }"
if [ -f "$TARGET/$item" ]; then
echo "<li><a href=\"$item\">${label^}</a></li>"
else
echo "<li><a href=\"$item/index.html\">${label^}</a></li>"
fi
done
echo '</ul></body></html>'
} > "$TARGET/index.html"
fi
fi
cat > "$TARGET/.meta" <<EOF
{"branch":"${GITHUB_REF_NAME:-}","sha":"${GITHUB_SHA}","published_at":"$(date -u +%Y-%m-%dT%H:%M:%SZ)"} {"branch":"${GITHUB_REF_NAME:-}","sha":"${GITHUB_SHA}","published_at":"$(date -u +%Y-%m-%dT%H:%M:%SZ)"}
EOF EOF
find "$WORK/$OWNER" \( -type f -o -type l \) -print | sed "s|^${WORK}/||" | tar -cf "$TAR" -C "$WORK" -T - find "$WORK/$OWNER" \( -type f -o -type l \) -print | sed "s|^${WORK}/||" | tar -cf "$TAR" -C "$WORK" -T -
+16 -188
View File
@@ -102,53 +102,6 @@ ja exit-koodi välittyy natiivisti. Ylimääräistä `EXIT=$?` + `echo >> GITHUB
`set -e` ei pelasta pipe-tilanteessa — `|` syö exit-koodin kuten ennenkin. Redirectillä exit-koodi `set -e` ei pelasta pipe-tilanteessa — `|` syö exit-koodin kuten ennenkin. Redirectillä exit-koodi
välittyy luonnollisesti. välittyy luonnollisesti.
**Yksi asia per step:** Älä koskaan niputa useaa komentoa samaan `run:`-blockiin — oli kyse
sitten post-processista tai testi- / tarkistusvaiheista. `bash -e` pysäyttää koko stepin
ensimmäisellä failaavalla komennolla, ja loput jäävät ajamatta.
```yaml
# VÄÄRIN — helm template fail → kubeconform jää ajamatta, report jää tekemättä
- name: Run tests
run: |
helm template ... > /tmp/manifests.yaml
kubeconform ... > results.txt 2>&1
# OIKEIN — erilliset stepit
- name: Helm template
run: helm template platform-helm/ -f values.yaml > /tmp/manifests.yaml 2>&1
- name: Kubeconform
if: success()
run: |
mkdir -p reports/kubeconform
kubeconform ... > reports/kubeconform/results.txt 2>&1
- name: Report
if: always()
run: bash .ci/scripts/ci-report.sh "Helm kubeconform" helm-test kubeconform ${{ job.status }}
```
Sama pätee post-process-steppeihin. Älä koskaan niputa useaa post-process-komentoa
samaan `run:`-blockiin. Käytä erillisiä steppejä `if: always()`:lla, jotta jokainen
vaihe ajetaan itsenäisesti:
```yaml
# VÄÄRIN — jos coverage epäonnistuu, report jää generoimatta
- name: Post-process reports
run: |
bash .ci/.gitea/scripts/bats-coverage.sh reports/bats
bash .ci/.gitea/scripts/bats-report.sh reports/bats
# OIKEIN — erilliset stepit if: always()
- name: Post-process coverage
if: always()
run: bash .ci/.gitea/scripts/bats-coverage.sh reports/bats
- name: Post-process test report
if: always()
run: bash .ci/.gitea/scripts/bats-report.sh reports/bats
```
## 4. Konttipolitiikka ## 4. Konttipolitiikka
1. **Julkiset registry-kontit kiinteällä versiolla**`alpine/helm:3.19.0`, `node:22`, `maven:3.9-eclipse-temurin-21`. 1. **Julkiset registry-kontit kiinteällä versiolla**`alpine/helm:3.19.0`, `node:22`, `maven:3.9-eclipse-temurin-21`.
@@ -159,9 +112,6 @@ vaihe ajetaan itsenäisesti:
`latest` on näille paras käytäntö, ei kompromissi `latest` on näille paras käytäntö, ei kompromissi
3. **Ei koskaan `curl`-latauksia CI-ajon sisällä** — työkalujen asennus CI-stepeissä hidastaa, 3. **Ei koskaan `curl`-latauksia CI-ajon sisällä** — työkalujen asennus CI-stepeissä hidastaa,
epäluotettavaa, ja vaikeuttaa toistettavuutta epäluotettavaa, ja vaikeuttaa toistettavuutta
4. **Konttikuva hallitaan workflow'ssa, ei kutsujassa** — jos workflow vaatii tietyn
konttikuvan, se määritellään oletuksena (`default:`) workflow'n inputissa.
Kutsujan ei tarvitse tietää eikä välittää image-nimeä ellei halua ylikirjoittaa.
CI-kontin build-workflow'n template: [skills/ci-container-build/SKILL.md](../ci-container-build/SKILL.md) — sisältää CI-kontin build-workflow'n template: [skills/ci-container-build/SKILL.md](../ci-container-build/SKILL.md) — sisältää
valmiin `ci-container-build-<kontti>.yml`-pohjan jossa `workflow_dispatch`-tuki manuaaliajoon. valmiin `ci-container-build-<kontti>.yml`-pohjan jossa `workflow_dispatch`-tuki manuaaliajoon.
@@ -171,15 +121,6 @@ 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>:
@@ -206,32 +147,11 @@ jobs:
- name: Report - name: Report
if: always() if: always()
run: bash .ci/scripts/ci-report.sh "<kuvaus>" <context> <suite> ${{ job.status }} run: bash .ci/scripts/ci-report.sh "<kuvaus>" <context> <suite>
``` ```
**Huomio `actions/checkout@v4`:stä:** `container:`-direktiivillä kaikki stepit
ajetaan kontin *sisällä* — myös `actions/checkout@v4`. Se on JavaScript-action
joka vaatii sekä `nodejs` että `git`. Ilman kumpaa tahansa checkout feilaa
`exit 127`.
```dockerfile
# Varmista että kontissa on nodejs + git
RUN apk add --no-cache nodejs git
```
**Tarkista siis aina** että CI-kontin Dockerfilessä on sekä `nodejs` että `git`
asennettuna. Sama pätee mihin tahansa konttiin jota käytetään `container:`-direktiivillä.
**Usean runnerin cache-ongelma:** Jos eri kerroilla käynnistyy eri runnereita,
niillä voi olla eri versio `latest`-imagen digesteistä. Tämä on `latest`-tagin
tunnettu ongelma. Ratkaisuja:
- Rebuildaa kontti ja aja `docker pull <image>` manuaalisesti kaikilla
runnereilla
- Käytä versioitua tagia (`v2`, `v3`, ...) ja päivitä workflow'n default
buildauksen jälkeen
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-siirto, HTML-generointi raa'asta outputista), Jos jälkikäsittely on tarpeen (coverage-extraktio, 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:**
@@ -256,14 +176,13 @@ Kun testi tuottaa raportit suoraan (kuten `pytest --html` tai `cucumber-js --for
- name: Report - name: Report
if: always() if: always()
run: bash .ci/scripts/ci-report.sh "<kuvaus>" <context> <suite> ${{ job.status }} run: bash .ci/scripts/ci-report.sh "<kuvaus>" <context> <suite>
``` ```
### Taso 2: Jälkikäsittely tarvitaan ### Taso 2: Jälkikäsittely tarvitaan
Kun testi tuottaa raakadataa (stdout, coverage-tiedostot) joka pitää muuntaa tai siirtää Kun testi tuottaa raakadataa (stdout, coverage-tiedostot) joka pitää muuntaa tai siirtää
`reports/<suite>/`-hakemistoon, käytetään Post-process-steppejä. **Jokainen operaatio `reports/<suite>/`-hakemistoon, käytetään Post-process-steppiä:
omassa stepissään** — älä koskaan niputa useaa post-process-komentoa samaan `run:`-blockiin:
```yaml ```yaml
- name: Run tests - name: Run tests
@@ -272,29 +191,18 @@ omassa stepissään** — älä koskaan niputa useaa post-process-komentoa samaa
mkdir -p "reports/<suite>" mkdir -p "reports/<suite>"
<testikomento> > "reports/<suite>/results.txt" 2>&1 <testikomento> > "reports/<suite>/results.txt" 2>&1
- name: Post-process coverage - name: Post-process reports
if: always() if: always()
run: <siirrä coverage-data reports/<suite>/coverage/-hakemistoon> run: |
<coverage-extraktio>
- name: Post-process test report <HTML-generointi raa'asta outputista>
if: always()
run: <HTML-generointi raa'asta outputista>
- name: Report - name: Report
if: always() if: always()
run: bash .ci/scripts/ci-report.sh "<kuvaus>" <context> <suite> ${{ job.status }} run: bash .ci/scripts/ci-report.sh "<kuvaus>" <context> <suite>
``` ```
**Huomio subdir-sisällöstä:** Jos testi tuottaa dataa alihakemistoon (esim. **Malli:** `example-bats-tests.yml`.
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
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.
### Monta raportoitavaa tiedostoa ### Monta raportoitavaa tiedostoa
@@ -304,92 +212,12 @@ on enemmän kuin yksi raportoitava item.
``` ```
reports/<suite>/ reports/<suite>/
├── results.txt ← testin stdout (skannataan FILES) ├── results.txt ← testin stdout
├── test-report.html ← generoitu HTML (skannataan FILES) ├── junit.xml testin JUnit XML -output
└── <mikä tahansa>/ ← alihakemisto (skannataan SUBDIRS) └── junit.html ← generoitu HTML (xsltproc, tms.)
└── index.html ← VAIN jos tämä on olemassa
``` ```
**Subdir-sääntö:** Alihakemisto näkyy indexissä VAIN jos se sisältää `index.html`:n. ## 6. Nimeäminen
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ä:
@@ -408,7 +236,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.
## 9. Artifact-kuri ## 7. 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ä.
@@ -604,7 +432,7 @@ Gitean Settings → Branches → Add Rule:
| Skripti | Käyttötarkoitus | | Skripti | Käyttötarkoitus |
|---|---| |---|---|
| `ci-report.sh` | Yhdistetty raportointi: julkaisee git-pagesiin ja asettaa commit-statuksen. Korvaa erilliset `publish-git-pages.sh` + `report-status.sh` -kutsut. Käyttö: `bash .ci/scripts/ci-report.sh "<kuvaus>" <context> <suite> ${{ job.status }}` | | `ci-report.sh` | Yhdistetty raportointi: julkaisee git-pagesiin ja asettaa commit-statuksen. Korvaa erilliset `publish-git-pages.sh` + `report-status.sh` -kutsut. Käyttö: `bash .ci/scripts/ci-report.sh "<kuvaus>" <context> <suite>` |
| `report-status.sh` | POSTaa commit-statuksen linkillä (kutsutaan `ci-report.sh`:n sisältä) | | `report-status.sh` | POSTaa commit-statuksen linkillä (kutsutaan `ci-report.sh`:n sisältä) |
| `publish-git-pages.sh` | Julkaisee raporttihakemiston git-pagesiin (kutsutaan `ci-report.sh`:n sisältä) | | `publish-git-pages.sh` | Julkaisee raporttihakemiston git-pagesiin (kutsutaan `ci-report.sh`:n sisältä) |
| `ci-validate.sh` | Validoi `.conf`-tiedoston (kutsutaan `config-provider.yml`:stä) | | `ci-validate.sh` | Validoi `.conf`-tiedoston (kutsutaan `config-provider.yml`:stä) |