From 31748e98cc1c5c18c59b7c953ae1c598616e33ab Mon Sep 17 00:00:00 2001 From: moilanik Date: Thu, 18 Jun 2026 06:19:58 +0300 Subject: [PATCH 01/12] uusi report logiikka --- .gitea/scripts/bats-coverage.sh | 32 +---- .gitea/workflows/example-bats-tests.yml | 38 ++---- .gitea/workflows/example-cucumber-tests.yml | 32 +---- scripts/ci-report.sh | 88 ++++++++++++ skills/consumer-pipelines/SKILL.md | 144 ++++++++------------ 5 files changed, 167 insertions(+), 167 deletions(-) create mode 100644 scripts/ci-report.sh diff --git a/.gitea/scripts/bats-coverage.sh b/.gitea/scripts/bats-coverage.sh index 43c76d9..2529621 100755 --- a/.gitea/scripts/bats-coverage.sh +++ b/.gitea/scripts/bats-coverage.sh @@ -1,37 +1,11 @@ #!/usr/bin/env bash set -euo pipefail -WORKSPACE_VOLUME="${1:-}" -REPORT_DIR="${2:-}" +REPORT_DIR="${1:-}" -[ -n "$WORKSPACE_VOLUME" ] || { echo "ERROR: workspace volume name required" >&2; exit 1; } [ -n "$REPORT_DIR" ] || { echo "ERROR: report directory required" >&2; exit 1; } -HAS_COVERAGE=false -COVERAGE_SRC="" -if docker run --rm -v "$WORKSPACE_VOLUME":/data alpine sh -c '[ -d /data/coverage ] && ls -A /data/coverage | grep -q .' 2>/dev/null; then - COVERAGE_SRC="/data/coverage" -fi - -if [ -n "$COVERAGE_SRC" ]; then +if [ -d coverage ]; then mkdir -p "$REPORT_DIR/coverage" - docker run --rm -v "$WORKSPACE_VOLUME":/data alpine tar c -C "$COVERAGE_SRC" . | tar x -C "$REPORT_DIR/coverage" - HAS_COVERAGE=true + cp -a coverage/. "$REPORT_DIR/coverage/" fi - -cat > "$REPORT_DIR/index.html" << EOF - -Bats report ${GITHUB_SHA:0:8} - -

Bats report ${GITHUB_SHA:0:8}

-' >> "$REPORT_DIR/index.html" diff --git a/.gitea/workflows/example-bats-tests.yml b/.gitea/workflows/example-bats-tests.yml index 9557334..8b78bc1 100644 --- a/.gitea/workflows/example-bats-tests.yml +++ b/.gitea/workflows/example-bats-tests.yml @@ -23,6 +23,8 @@ env: jobs: bats: runs-on: ubuntu-latest + container: + image: ${{ inputs.bats-image }} steps: - uses: actions/checkout@v4 - uses: actions/checkout@v4 @@ -31,34 +33,16 @@ jobs: path: .ci - name: Run bats tests - id: bats-tests - shell: bash run: | - docker volume create bats-workspace - tar c . | docker run --rm -i -v bats-workspace:/data alpine tar x -C /data - mkdir -p "reports/${GITHUB_SHA:0:8}/bats" - set +e - docker run --rm \ - -v bats-workspace:/data \ - --entrypoint bash ${{ inputs.bats-image }} \ - -c 'cd /data && bashcov -- bats tests/' \ - > "reports/${GITHUB_SHA:0:8}/bats/results.txt" 2>&1 - BATS_EXIT=$? - bash .ci/.gitea/scripts/bats-coverage.sh bats-workspace "reports/${GITHUB_SHA:0:8}/bats" - docker volume rm bats-workspace > /dev/null 2>&1 - bash .ci/.gitea/scripts/bats-report.sh "reports/${GITHUB_SHA:0:8}/bats" - echo "BATS_EXIT=${BATS_EXIT}" >> "${GITHUB_ENV}" - exit ${BATS_EXIT} + mkdir -p reports/bats + bashcov -- bats tests/ > reports/bats/results.txt 2>&1 - - name: Publish bats reports - if: always() - run: bash .ci/scripts/publish-git-pages.sh bats - - - name: Report status + - name: Post-process reports if: always() run: | - if [ "${BATS_EXIT}" = "0" ]; then - bash .ci/scripts/report-status.sh success "Link to Bats reports" unit-tests bats - else - bash .ci/scripts/report-status.sh failure "Link to Bats reports" unit-tests bats - fi + bash .ci/.gitea/scripts/bats-coverage.sh reports/bats + bash .ci/.gitea/scripts/bats-report.sh reports/bats + + - name: Report + if: always() + run: bash .ci/scripts/ci-report.sh "Bats test report" unit-tests bats diff --git a/.gitea/workflows/example-cucumber-tests.yml b/.gitea/workflows/example-cucumber-tests.yml index 88fb68b..24acb58 100644 --- a/.gitea/workflows/example-cucumber-tests.yml +++ b/.gitea/workflows/example-cucumber-tests.yml @@ -33,36 +33,14 @@ jobs: path: .ci - name: Run cucumber tests - id: cucumber-tests shell: bash run: | - mkdir -p "reports/${GITHUB_SHA:0:8}/cucumber" - set +e + mkdir -p reports/cucumber npx cucumber-js \ - --format json:"reports/${GITHUB_SHA:0:8}/cucumber/report.json" \ - --format html:"reports/${GITHUB_SHA:0:8}/cucumber/index.html" 2>&1 - CUCUMBER_EXIT=$? - echo "CUCUMBER_EXIT=${CUCUMBER_EXIT}" >> "${GITHUB_ENV}" - exit ${CUCUMBER_EXIT} + --format json:reports/cucumber/report.json \ + --format html:reports/cucumber/report.html 2>&1 - - name: Publish cucumber reports - if: always() - run: bash .ci/scripts/publish-git-pages.sh cucumber - - - name: Report status + - name: Report if: always() shell: bash - run: | - if [ "${CUCUMBER_EXIT}" = "0" ]; then - if [ -f "reports/${GITHUB_SHA:0:8}/cucumber/index.html" ]; then - bash .ci/scripts/report-status.sh success "Link to Cucumber reports" acc-tests cucumber - else - bash .ci/scripts/report-status.sh success "Link to Cucumber reports" acc-tests - fi - else - if [ -f "reports/${GITHUB_SHA:0:8}/cucumber/index.html" ]; then - bash .ci/scripts/report-status.sh failure "Link to Cucumber reports" acc-tests cucumber - else - bash .ci/scripts/report-status.sh failure "Link to Cucumber reports" acc-tests - fi - fi + run: bash .ci/scripts/ci-report.sh "Cucumber test report" acc-tests cucumber diff --git a/scripts/ci-report.sh b/scripts/ci-report.sh new file mode 100644 index 0000000..1e833ed --- /dev/null +++ b/scripts/ci-report.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +set -euo pipefail + +DESCRIPTION="${1:-}" +CONTEXT="${2:-}" +SUITE="${3:-}" + +[ -n "$DESCRIPTION" ] || { echo "ERROR: description argument required" >&2; exit 1; } +[ -n "$CONTEXT" ] || { echo "ERROR: context argument required" >&2; exit 1; } +[ -n "$SUITE" ] || { echo "ERROR: suite argument required" >&2; exit 1; } + +REPORT_DIR="reports/${SUITE}" + +if [ ! -d "$REPORT_DIR" ]; then + echo "ERROR: $REPORT_DIR not found" >&2 + bash .ci/scripts/report-status.sh failure "$DESCRIPTION" "$CONTEXT" + exit 1 +fi + +cd "$REPORT_DIR" + +FILES=() +while IFS= read -r -d '' f; do + FILES+=("$(basename "$f")") +done < <(find . -maxdepth 1 -type f ! -name index.html -print0 2>/dev/null || true) + +SUBDIRS=() +while IFS= read -r -d '' d; do + name="${d#./}" + [ -f "$name/index.html" ] && SUBDIRS+=("$name") +done < <(find . -maxdepth 1 -type d ! -name . -print0 2>/dev/null || true) + +TOTAL=$(( ${#FILES[@]} + ${#SUBDIRS[@]} )) + +if [ "$TOTAL" -eq 0 ]; then + echo "ERROR: no reportable items in $REPORT_DIR" >&2 + bash .ci/scripts/report-status.sh failure "$DESCRIPTION" "$CONTEXT" + exit 1 +fi + +SHA8="${GITHUB_SHA:0:8}" + +humanize() { + local name="$1" + name="${name%.*}" + name="${name//-/ }" + name="${name//_/ }" + echo "${name^}" +} + +generate_index() { + local html + html='' + html+="$DESCRIPTION" + html+='' + html+="

$DESCRIPTION

' + printf '%s' "$html" > index.html +} + +cd - > /dev/null + +# Stage reports for backward-compatible publish +STAGED="reports/${SHA8}/${SUITE}" +mkdir -p "$STAGED" +cp -a "$REPORT_DIR/." "$STAGED/" + +if [ "$TOTAL" -eq 1 ]; then + if [ ${#FILES[@]} -eq 1 ]; then + ENTRY="${FILES[0]}" + else + ENTRY="${SUBDIRS[0]}/index.html" + fi + bash .ci/scripts/publish-git-pages.sh "$SUITE" + URL="${GIT_PAGES_URL}/${GITHUB_REPOSITORY}/reports/${SHA8}/${SUITE}/${ENTRY}" + bash .ci/scripts/report-status.sh success "$DESCRIPTION" "$CONTEXT" "" "$URL" +else + bash .ci/scripts/publish-git-pages.sh "$SUITE" + bash .ci/scripts/report-status.sh success "$DESCRIPTION" "$CONTEXT" "$SUITE" +fi + +rm -rf "$STAGED" diff --git a/skills/consumer-pipelines/SKILL.md b/skills/consumer-pipelines/SKILL.md index 92ba264..732b99c 100644 --- a/skills/consumer-pipelines/SKILL.md +++ b/skills/consumer-pipelines/SKILL.md @@ -79,16 +79,14 @@ Ei monoliittista `ci-tests.yml`. Jokainen testityyppi tai operaatio on oma `work ## 3. Exit-koodin käsittely -Jokainen testi kaappaa komentonsa exit-koodin eksplisiittisesti: +`set -e` on oletuksena käytössä Gitea Actions -stepeissä — ensimmäinen feilaava komento pysäyttää stepin +ja exit-koodi välittyy natiivisti. Ylimääräistä `EXIT=$?` + `echo >> GITHUB_ENV` -käärettä ei tarvita. ```yaml - name: Run tests shell: bash run: | > results.txt 2>&1 - EXIT=$? - echo "EXIT=${EXIT}" >> "${GITHUB_ENV}" - exit ${EXIT} ``` **Miksi ei pipeä (`| tee`):** @@ -101,8 +99,8 @@ Jokainen testi kaappaa komentonsa exit-koodin eksplisiittisesti: > results.txt 2>&1 ``` -Ilman `EXIT=$?` + `exit ${EXIT}` komento voi feilata mutta job menee läpi vihreänä — `container:`-modessa -shellin käyttäytyminen vaihtelee. +`set -e` ei pelasta pipe-tilanteessa — `|` syö exit-koodin kuten ennenkin. Redirectillä exit-koodi +välittyy luonnollisesti. ## 4. Konttipolitiikka @@ -120,38 +118,15 @@ valmiin `ci-container-build-.yml`-pohjan jossa `workflow_dispatch`-tuki ### 4.1 CI-kontin ajaminen jobissa -CI-kontin voi ajaa joko `container:`-direktiivillä (kaikki stepit kontissa) -tai `docker run --rm`:llä stepin sisällä (checkout natiivisti). Molemmat tavat -toimivat. +Ainoa sallittu tapa on `container:`-direktiivi. `docker run` komennolla kontin +käynnistäminen stepin sisällä on anti-pattern. ```yaml -# Tapa A: container:-direktiivi jobs: : runs-on: ubuntu-latest container: image: ${{ inputs. }} - steps: - - uses: actions/checkout@v4 - - uses: actions/checkout@v4 - with: - repository: /gitea-ci-library - path: .ci - - name: Run - shell: bash - run: | - mkdir -p "reports/${GITHUB_SHA:0:8}/" - > "reports/${GITHUB_SHA:0:8}//results.txt" 2>&1 - EXIT=$? - echo "EXIT=${EXIT}" >> "${GITHUB_ENV}" - exit ${EXIT} -``` - -```yaml -# Tapa B: docker run --rm stepin sisällä (kuten example-bats-tests.yml) -jobs: - : - runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/checkout@v4 @@ -162,86 +137,86 @@ jobs: - name: Run shell: bash run: | - docker volume create ws- - tar c . | docker run --rm -i -v ws-:/data alpine tar x -C /data - mkdir -p "reports/${GITHUB_SHA:0:8}/" - set +e - docker run --rm \ - -v ws-:/data \ - --entrypoint bash ${{ inputs. }} \ - -c 'cd /data && ' \ - > "reports/${GITHUB_SHA:0:8}//results.txt" 2>&1 - EXIT=$? - docker volume rm ws- > /dev/null 2>&1 - echo "EXIT=${EXIT}" >> "${GITHUB_ENV}" - exit ${EXIT} + mkdir -p "reports/" + > "reports//results.txt" 2>&1 - - name: Publish reports - if: always() - run: bash .ci/scripts/publish-git-pages.sh - - - name: Report status + - name: Post-process reports if: always() run: | - if [ "${EXIT}" = "0" ]; then - bash .ci/scripts/report-status.sh success "" - else - bash .ci/scripts/report-status.sh failure "" - fi + + + - name: Report + if: always() + run: bash .ci/scripts/ci-report.sh "" ``` -**Malli:** `example-bats-tests.yml` (tapa B). +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), +se tehdään omassa stepissä `if: always()` — katso tarkemmin [Raporttitasot](#5-raporttitasot). + +**Mallit:** +- `example-cucumber-tests.yml` — ei post-processia +- `example-bats-tests.yml` — post-process coverage + report ## 5. Raporttitasot -Testi tuottaa raportin `reports/${GITHUB_SHA:0:8}//`-hakemistoon. `publish-git-pages.sh` julkaisee sen, -`report-status.sh` linkittää commit-statusin siihen. Molemmat `if: always()`. +Testi tuottaa raportin `reports//`-hakemistoon. Yksi `ci-report.sh`-kutsu hoitaa sekä +julkaisun että commit-statuksen — erillistä Publish + Report Status -kaksivaiheisuutta ei tarvita. -### Taso 1: Pelkkä teksti +### Taso 1: Ei jälkikäsittelyä -Kun testi tuottaa vain stdout/stderr — tallennetaan `results.txt`: +Kun testi tuottaa raportit suoraan (kuten `pytest --html` tai `cucumber-js --format html`): ```yaml - name: Run tests shell: bash run: | - mkdir -p "reports/${GITHUB_SHA:0:8}/" - > "reports/${GITHUB_SHA:0:8}//results.txt" 2>&1 - EXIT=$? - echo "EXIT=${EXIT}" >> "${GITHUB_ENV}" - exit ${EXIT} + mkdir -p "reports/" + -- name: Publish reports +- name: Report if: always() - shell: bash - run: bash .ci/scripts/publish-git-pages.sh + run: bash .ci/scripts/ci-report.sh "" +``` -- name: Report status - if: always() +### Taso 2: Jälkikäsittely tarvitaan + +Kun testi tuottaa raakadataa (stdout, coverage-tiedostot) joka pitää muuntaa tai siirtää +`reports//`-hakemistoon, käytetään Post-process-steppiä: + +```yaml +- name: Run tests shell: bash run: | - if [ "${EXIT}" = "0" ]; then - bash .ci/scripts/report-status.sh success "" - else - bash .ci/scripts/report-status.sh failure "" - fi + mkdir -p "reports/" + > "reports//results.txt" 2>&1 + +- name: Post-process reports + if: always() + run: | + + + +- name: Report + if: always() + run: bash .ci/scripts/ci-report.sh "" ``` -### Taso 2: HTML-raportti +**Malli:** `example-bats-tests.yml`. -Kun testi tuottaa strukturoitua dataa (JUnit XML, coverage, tms.) — generoidaan HTML ja `index.html`: +### Monta raportoitavaa tiedostoa + +Kun `reports//`-hakemistossa on useita tiedostoja tai alihakemistoja, +`ci-report.sh` generoi automaattisesti `reports//index.html` jos hakemistossa +on enemmän kuin yksi raportoitava item. ``` -reports/// -├── index.html ← generoitu: linkit alla oleviin +reports// ├── results.txt ← testin stdout ├── junit.xml ← testin JUnit XML -output └── junit.html ← generoitu HTML (xsltproc, tms.) ``` -`index.html` linkittää kaikkiin raporttitiedostoihin. Selain avaa sen ja navigoi sieltä -yksittäisiin raportteihin. - ## 6. Nimeäminen Tiedostonimet `.gitea/workflows/`-kansiossa noudattavat yhtenäistä rakennetta, jotta @@ -457,8 +432,9 @@ Gitean Settings → Branches → Add Rule: | Skripti | Käyttötarkoitus | |---|---| -| `report-status.sh` | POSTaa commit-statuksen linkillä | -| `publish-git-pages.sh` | Julkaisee raporttihakemiston git-pagesiin | +| `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 "" ` | +| `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ä) | | `ci-validate.sh` | Validoi `.conf`-tiedoston (kutsutaan `config-provider.yml`:stä) | --- @@ -499,7 +475,7 @@ Ei pipeä (`|`) komennon perässä — se syö exit-koodin. Käytä redirectiä ### Commit-status vain raporttilinkille (ADR 0007) -`report-status.sh`-skriptiä käytetään VAIN kun on raportti linkitettäväksi. +`ci-report.sh`-skriptiä käytetään VAIN kun on raportti linkitettäväksi. Tool-jobit (build, deploy) luottavat Gitean natiiviin job-statukseen. ### Providerin checkout ei kuulu consumerille -- 2.52.0 From 11ca47cf1bf88559f06cd386c781052028580155 Mon Sep 17 00:00:00 2001 From: moilanik Date: Thu, 18 Jun 2026 06:30:21 +0300 Subject: [PATCH 02/12] index.html korjaus --- scripts/ci-report.sh | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/scripts/ci-report.sh b/scripts/ci-report.sh index 1e833ed..9cc1dd7 100644 --- a/scripts/ci-report.sh +++ b/scripts/ci-report.sh @@ -17,18 +17,16 @@ if [ ! -d "$REPORT_DIR" ]; then exit 1 fi -cd "$REPORT_DIR" - FILES=() while IFS= read -r -d '' f; do FILES+=("$(basename "$f")") -done < <(find . -maxdepth 1 -type f ! -name index.html -print0 2>/dev/null || true) +done < <(find "$REPORT_DIR" -maxdepth 1 -type f ! -name index.html -print0 2>/dev/null || true) SUBDIRS=() while IFS= read -r -d '' d; do - name="${d#./}" - [ -f "$name/index.html" ] && SUBDIRS+=("$name") -done < <(find . -maxdepth 1 -type d ! -name . -print0 2>/dev/null || true) + name="${d#$REPORT_DIR/}" + [ -f "$d/index.html" ] && SUBDIRS+=("$name") +done < <(find "$REPORT_DIR" -maxdepth 1 -type d ! -name . -print0 2>/dev/null || true) TOTAL=$(( ${#FILES[@]} + ${#SUBDIRS[@]} )) @@ -61,26 +59,26 @@ generate_index() { html+="
  • ${d^}
  • " done html+='' - printf '%s' "$html" > index.html + printf '%s' "$html" > "$REPORT_DIR/index.html" } -cd - > /dev/null - -# Stage reports for backward-compatible publish STAGED="reports/${SHA8}/${SUITE}" mkdir -p "$STAGED" -cp -a "$REPORT_DIR/." "$STAGED/" if [ "$TOTAL" -eq 1 ]; then + cp -a "$REPORT_DIR/." "$STAGED/" + bash .ci/scripts/publish-git-pages.sh "$SUITE" + if [ ${#FILES[@]} -eq 1 ]; then ENTRY="${FILES[0]}" else ENTRY="${SUBDIRS[0]}/index.html" fi - bash .ci/scripts/publish-git-pages.sh "$SUITE" URL="${GIT_PAGES_URL}/${GITHUB_REPOSITORY}/reports/${SHA8}/${SUITE}/${ENTRY}" bash .ci/scripts/report-status.sh success "$DESCRIPTION" "$CONTEXT" "" "$URL" else + generate_index + cp -a "$REPORT_DIR/." "$STAGED/" bash .ci/scripts/publish-git-pages.sh "$SUITE" bash .ci/scripts/report-status.sh success "$DESCRIPTION" "$CONTEXT" "$SUITE" fi -- 2.52.0 From 010adaa58a37c5888e4988c72809b8b39bc24988 Mon Sep 17 00:00:00 2001 From: moilanik Date: Thu, 18 Jun 2026 07:12:52 +0300 Subject: [PATCH 03/12] useita runner --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e02fb62..4a69310 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,7 @@ helm upgrade --install act-runner gitea/actions \ --set giteaRootURL="$GITEA_URL" \ --set existingSecret=act-runner-token \ --set existingSecretKey=token \ + --set statefulset.replicas=3 \ --set statefulset.runner.tag=1.0.8 \ --set statefulset.dind.tag=29.5.2-dind \ --set-string 'statefulset.runner.config=log: -- 2.52.0 From 39547e9578e6eccea7135dbbd691df40a3c74d73 Mon Sep 17 00:00:00 2001 From: moilanik Date: Thu, 18 Jun 2026 07:17:51 +0300 Subject: [PATCH 04/12] post process vain 1 asia per steppi --- .gitea/workflows/example-bats-tests.yml | 10 ++++--- skills/consumer-pipelines/SKILL.md | 39 +++++++++++++++++++++---- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/.gitea/workflows/example-bats-tests.yml b/.gitea/workflows/example-bats-tests.yml index 8b78bc1..b884e1e 100644 --- a/.gitea/workflows/example-bats-tests.yml +++ b/.gitea/workflows/example-bats-tests.yml @@ -37,11 +37,13 @@ jobs: mkdir -p reports/bats bashcov -- bats tests/ > reports/bats/results.txt 2>&1 - - name: Post-process reports + - name: Post-process coverage if: always() - run: | - bash .ci/.gitea/scripts/bats-coverage.sh reports/bats - bash .ci/.gitea/scripts/bats-report.sh reports/bats + 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 - name: Report if: always() diff --git a/skills/consumer-pipelines/SKILL.md b/skills/consumer-pipelines/SKILL.md index 732b99c..385bc7d 100644 --- a/skills/consumer-pipelines/SKILL.md +++ b/skills/consumer-pipelines/SKILL.md @@ -102,6 +102,27 @@ 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 välittyy luonnollisesti. +**Yksi asia per step:** Älä koskaan niputa useaa post-process-komentoa samaan `run:`-blockiin. +`bash -e` pysäyttää koko stepin jos yksi komento epäonnistuu — seuraavat jäävät ajamatta. +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 1. **Julkiset registry-kontit kiinteällä versiolla** — `alpine/helm:3.19.0`, `node:22`, `maven:3.9-eclipse-temurin-21`. @@ -182,7 +203,8 @@ Kun testi tuottaa raportit suoraan (kuten `pytest --html` tai `cucumber-js --for ### Taso 2: Jälkikäsittely tarvitaan Kun testi tuottaa raakadataa (stdout, coverage-tiedostot) joka pitää muuntaa tai siirtää -`reports//`-hakemistoon, käytetään Post-process-steppiä: +`reports//`-hakemistoon, käytetään Post-process-steppejä. **Jokainen operaatio +omassa stepissään** — älä koskaan niputa useaa post-process-komentoa samaan `run:`-blockiin: ```yaml - name: Run tests @@ -191,17 +213,24 @@ Kun testi tuottaa raakadataa (stdout, coverage-tiedostot) joka pitää muuntaa t mkdir -p "reports/" > "reports//results.txt" 2>&1 -- name: Post-process reports +- name: Post-process coverage if: always() - run: | - - + run: + +- name: Post-process test report + if: always() + run: - name: Report if: always() run: bash .ci/scripts/ci-report.sh "" ``` +**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 -- 2.52.0 From 160d83a5047b626146d793c75b026fc3aebb3dd6 Mon Sep 17 00:00:00 2001 From: moilanik Date: Thu, 18 Jun 2026 08:06:58 +0300 Subject: [PATCH 05/12] index julkaisu logiikka --- README.md | 2 +- scripts/publish-git-pages.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4a69310..a94da3a 100644 --- a/README.md +++ b/README.md @@ -123,8 +123,8 @@ Hae token Giteasta: ```bash GITEA_URL="https://" -GITEA_ACTIONS_TOKEN="" GITEA_ACTIONS_NAMESPACE="gitea-actions" +GITEA_ACTIONS_TOKEN="" ``` ### 3. Tee secret vain init install yhteydessä diff --git a/scripts/publish-git-pages.sh b/scripts/publish-git-pages.sh index 81228a7..df8d411 100755 --- a/scripts/publish-git-pages.sh +++ b/scripts/publish-git-pages.sh @@ -33,7 +33,7 @@ else fi mkdir -p "$TARGET" cp -a "$REPORT_DIR/." "$TARGET/" -cat > "$WORK/${OWNER}/${REPO}/reports/${SHA8}/.meta" < "$TARGET/.meta" < Date: Thu, 18 Jun 2026 08:50:13 +0300 Subject: [PATCH 06/12] =?UTF-8?q?=C3=A4=C3=A4h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/publish-git-pages.sh | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/scripts/publish-git-pages.sh b/scripts/publish-git-pages.sh index df8d411..acee12c 100755 --- a/scripts/publish-git-pages.sh +++ b/scripts/publish-git-pages.sh @@ -33,6 +33,41 @@ else fi mkdir -p "$TARGET" cp -a "$REPORT_DIR/." "$TARGET/" +if [ ! -f "$TARGET/index.html" ]; then + 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 '' + echo "Test report ${SHA8}" + echo '' + echo "

    Test report ${SHA8}

      " + for item in "${items[@]}"; do + label="${item%.*}" + label="${label//-/ }" + label="${label//_/ }" + if [ -f "$TARGET/$item" ]; then + echo "
    • ${label^}
    • " + else + echo "
    • ${label^}
    • " + fi + done + echo '
    ' + } > "$TARGET/index.html" + fi +fi + cat > "$TARGET/.meta" < Date: Thu, 18 Jun 2026 09:23:54 +0300 Subject: [PATCH 07/12] coverage report fix --- .gitea/scripts/bats-coverage.sh | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/.gitea/scripts/bats-coverage.sh b/.gitea/scripts/bats-coverage.sh index 2529621..8fbc522 100755 --- a/.gitea/scripts/bats-coverage.sh +++ b/.gitea/scripts/bats-coverage.sh @@ -5,7 +5,26 @@ REPORT_DIR="${1:-}" [ -n "$REPORT_DIR" ] || { echo "ERROR: report directory required" >&2; exit 1; } +COVERAGE_DIR="$REPORT_DIR/coverage" + if [ -d coverage ]; then - mkdir -p "$REPORT_DIR/coverage" - cp -a coverage/. "$REPORT_DIR/coverage/" + mkdir -p "$COVERAGE_DIR" + cp -a coverage/. "$COVERAGE_DIR/" +fi + +if [ -d "$COVERAGE_DIR" ] && [ ! -f "$COVERAGE_DIR/index.html" ]; then + SHA8="${GITHUB_SHA:0:8}" + { + echo '' + echo "Coverage report ${SHA8}" + echo '' + echo "

    Coverage report ${SHA8}

      " + while IFS= read -r -d '' f; do + base=$(basename "$f") + name="${base%.*}" + name="${name//-/ }" + echo "
    • ${name^}
    • " + done < <(find "$COVERAGE_DIR" -maxdepth 1 -type f \( -name '*.html' -o -name '*.txt' \) ! -name index.html -print0 2>/dev/null || true) + echo '
    ' + } > "$COVERAGE_DIR/index.html" fi -- 2.52.0 From 36b8af6cf323de702c5c96ad5507942cf7dcd3f6 Mon Sep 17 00:00:00 2001 From: moilanik Date: Thu, 18 Jun 2026 10:06:27 +0300 Subject: [PATCH 08/12] debug echo, ongelman eristys --- .gitea/scripts/bats-coverage.sh | 8 ++++++++ scripts/ci-report.sh | 13 +++++++++++++ 2 files changed, 21 insertions(+) diff --git a/.gitea/scripts/bats-coverage.sh b/.gitea/scripts/bats-coverage.sh index 8fbc522..b1226bc 100755 --- a/.gitea/scripts/bats-coverage.sh +++ b/.gitea/scripts/bats-coverage.sh @@ -7,11 +7,19 @@ REPORT_DIR="${1:-}" COVERAGE_DIR="$REPORT_DIR/coverage" +echo "DEBUG[bats-coverage]: CWD=$(pwd)" >&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 +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 9cc1dd7..8890b32 100644 --- a/scripts/ci-report.sh +++ b/scripts/ci-report.sh @@ -28,6 +28,19 @@ 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 -- 2.52.0 From cf71134b7500ef241a20a8b2cdfd248afff99ee8 Mon Sep 17 00:00:00 2001 From: moilanik Date: Thu, 18 Jun 2026 10:21:48 +0300 Subject: [PATCH 09/12] fasd --- .gitea/scripts/bats-coverage.sh | 34 +++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/.gitea/scripts/bats-coverage.sh b/.gitea/scripts/bats-coverage.sh index b1226bc..7b552b9 100755 --- a/.gitea/scripts/bats-coverage.sh +++ b/.gitea/scripts/bats-coverage.sh @@ -1,21 +1,35 @@ #!/usr/bin/env bash set -euo pipefail -REPORT_DIR="${1:-}" +COVERAGE_VOLUME="${2:+${1:-}}" +REPORT_DIR="${2:-${1:-}}" [ -n "$REPORT_DIR" ] || { echo "ERROR: report directory required" >&2; exit 1; } COVERAGE_DIR="$REPORT_DIR/coverage" -echo "DEBUG[bats-coverage]: CWD=$(pwd)" >&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 +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 fi echo "DEBUG[bats-coverage]: target $COVERAGE_DIR/index.html exists? $([ -f "$COVERAGE_DIR/index.html" ] && echo YES || echo NO)" >&2 -- 2.52.0 From 0f371adafaaf2e631377f9baa01f87fcf0418934 Mon Sep 17 00:00:00 2001 From: moilanik Date: Thu, 18 Jun 2026 10:37:37 +0300 Subject: [PATCH 10/12] =?UTF-8?q?skill=20p=C3=A4ivitetty!=20uusi=20convent?= =?UTF-8?q?io=20cunsumer=20pipeline=20toteutukseen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/scripts/bats-coverage.sh | 33 ++------- scripts/ci-report.sh | 13 ---- skills/consumer-pipelines/SKILL.md | 111 ++++++++++++++++++++++++++--- 3 files changed, 107 insertions(+), 50 deletions(-) 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ä. -- 2.52.0 From 56031a03b87acf96617076fbd716a50bae36269d Mon Sep 17 00:00:00 2001 From: moilanik Date: Thu, 18 Jun 2026 10:42:08 +0300 Subject: [PATCH 11/12] kontti hallitaan workflowssa --- .gitea/workflows/example-bats-tests.yml | 3 ++- .gitea/workflows/example-cucumber-tests.yml | 3 ++- .gitea/workflows/example-feature.yml | 2 -- .gitea/workflows/example-main.yml | 2 -- skills/consumer-pipelines/SKILL.md | 3 +++ 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.gitea/workflows/example-bats-tests.yml b/.gitea/workflows/example-bats-tests.yml index b884e1e..b3f8443 100644 --- a/.gitea/workflows/example-bats-tests.yml +++ b/.gitea/workflows/example-bats-tests.yml @@ -6,8 +6,9 @@ on: required: true type: string bats-image: - required: true + required: false type: string + default: gitea.app.keskikuja.site/niko/ci-bats:latest secrets: GITEA_TOKEN: required: true diff --git a/.gitea/workflows/example-cucumber-tests.yml b/.gitea/workflows/example-cucumber-tests.yml index 24acb58..d604044 100644 --- a/.gitea/workflows/example-cucumber-tests.yml +++ b/.gitea/workflows/example-cucumber-tests.yml @@ -6,8 +6,9 @@ on: required: true type: string cucumber-node-image: - required: true + required: false type: string + default: gitea.app.keskikuja.site/niko/ci-cucumber:latest secrets: GITEA_TOKEN: required: true diff --git a/.gitea/workflows/example-feature.yml b/.gitea/workflows/example-feature.yml index 47d0fd5..42d79b2 100644 --- a/.gitea/workflows/example-feature.yml +++ b/.gitea/workflows/example-feature.yml @@ -20,7 +20,6 @@ jobs: secrets: inherit with: env_json: ${{ needs.load-config.outputs.env_json }} - bats-image: gitea.app.keskikuja.site/niko/ci-bats:latest cucumber: name: Cucumber tests @@ -29,7 +28,6 @@ jobs: secrets: inherit with: env_json: ${{ needs.load-config.outputs.env_json }} - cucumber-node-image: gitea.app.keskikuja.site/niko/ci-cucumber:latest report-summary: name: Report Summary diff --git a/.gitea/workflows/example-main.yml b/.gitea/workflows/example-main.yml index 5cc8c4c..a734123 100644 --- a/.gitea/workflows/example-main.yml +++ b/.gitea/workflows/example-main.yml @@ -29,7 +29,6 @@ jobs: secrets: inherit with: env_json: ${{ needs.load-config.outputs.env_json }} - bats-image: gitea.app.keskikuja.site/niko/ci-bats:latest cucumber: name: Cucumber tests @@ -39,7 +38,6 @@ jobs: secrets: inherit with: env_json: ${{ needs.load-config.outputs.env_json }} - cucumber-node-image: gitea.app.keskikuja.site/niko/ci-cucumber:latest build-push: name: Build & Push Docker diff --git a/skills/consumer-pipelines/SKILL.md b/skills/consumer-pipelines/SKILL.md index ebc269f..c3b881b 100644 --- a/skills/consumer-pipelines/SKILL.md +++ b/skills/consumer-pipelines/SKILL.md @@ -133,6 +133,9 @@ Käytä erillisiä steppejä `if: always()`:lla, jotta jokainen vaihe ajetaan it `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, 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ää valmiin `ci-container-build-.yml`-pohjan jossa `workflow_dispatch`-tuki manuaaliajoon. -- 2.52.0 From b06e198603c6d1cfb4850b1d676008e304a429b4 Mon Sep 17 00:00:00 2001 From: moilanik Date: Thu, 18 Jun 2026 12:54:32 +0300 Subject: [PATCH 12/12] fixes --- .gitea/workflows/example-build-ci-cucumber.yml | 4 ++-- Dockerfile.ci-bats | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/example-build-ci-cucumber.yml b/.gitea/workflows/example-build-ci-cucumber.yml index d45c482..5821f2f 100644 --- a/.gitea/workflows/example-build-ci-cucumber.yml +++ b/.gitea/workflows/example-build-ci-cucumber.yml @@ -25,14 +25,14 @@ on: jobs: load-config: - uses: niko/gitea-ci-library/.gitea/workflows/config-provider.yml@v1 + uses: niko/gitea-ci-library/.gitea/workflows/config-provider.yml@main secrets: inherit with: config_path: ${{ inputs.config_path }} build-push: needs: [load-config] - uses: niko/gitea-ci-library/.gitea/workflows/ci-container-build-push.yml@v1 + uses: niko/gitea-ci-library/.gitea/workflows/ci-container-build-push.yml@main secrets: inherit with: env_json: ${{ needs.load-config.outputs.env_json }} diff --git a/Dockerfile.ci-bats b/Dockerfile.ci-bats index 1ca8e17..6c54ae0 100644 --- a/Dockerfile.ci-bats +++ b/Dockerfile.ci-bats @@ -1,3 +1,3 @@ -FROM bats/bats:latest +FROM bats/bats:1.11.0 RUN apk add --no-cache lsof python3 jq curl ruby && \ gem install bashcov -v 3.3.0 -- 2.52.0