Files
gitea-ci-library/skills/consumer-pipelines/SKILL.md
T
moilanik 31748e98cc
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
uusi report logiikka
2026-06-18 06:19:58 +03:00

16 KiB

name, description, activation-gate, category, impact
name description activation-gate category impact
consumer-pipelines Creating or modifying consumer CI pipelines, .gitea/workflows/ files, reusable test workflows, monorepo CI configuration, or CI routing files (ci-feature.yml, ci-main.yml, ci-*.yml). Activates when the user asks to build, fix, or change consumer-side Gitea Actions pipelines that use gitea-ci-library providers. User mentions consumer pipelines, ci-feature.yml, ci-main.yml, test workflows, .gitea/workflows/ files, monorepo CI, routing files, or asks to create/modify CI pipelines on top of gitea-ci-library. ci high

Consumer Pipelines — Pipeline Standards

Säännöt joilla consumer-projektit rakentavat CI-pipelinejä gitea-ci-library-kirjaston päälle. Nämä eivät ole provider-kirjaston sääntöjä — ne kuvaavat miten consumerin kuuluu käyttää kirjastoa oikein.

1. Reitittimen puhtaus

Reitittimet (ci-feature.yml, ci-main.yml) eivät sisällä run:-steppejä. Ne koostuvat vain:

uses:
needs:
if:
secrets: inherit
with:
  env_json:
  <parametrit>:

Jokainen job vastaa yhtä loogista testiä tai operaatiota. Reititin on orkestraattori — kaikki suorittava logiikka on omassa workflow_call-tiedostossaan.

Esimerkki:

jobs:
  load-config:
    uses: <owner>/gitea-ci-library/.gitea/workflows/config-provider.yml@v1
    secrets: inherit

  <test-1>:
    needs: [load-config]
    uses: ./.gitea/workflows/<component>.<test-1>.yml
    secrets: inherit
    with:
      env_json: ${{ needs.load-config.outputs.env_json }}

  <test-2>:
    needs: [load-config]
    uses: ./.gitea/workflows/<component>.<test-2>.yml
    secrets: inherit
    with:
      env_json: ${{ needs.load-config.outputs.env_json }}

  report-summary:
    needs: [load-config, <test-1>, <test-2>]
    if: always()
    uses: <owner>/gitea-ci-library/.gitea/workflows/report-summary.yml@v1
    with:
      env_json: ${{ needs.load-config.outputs.env_json }}
      suites: <suite-1> <suite-2>

2. Yksi asia per tiedosto

Ei monoliittista ci-tests.yml. Jokainen testityyppi tai operaatio on oma workflow_call-tiedostonsa.

Miksi:

  • Testit ajetaan rinnakkain (ei keinotekoisia riippuvuuksia)
  • Yhden testin fail ei estä muita
  • Testattavissa itsenäisesti workflow_dispatch:llä
  • Diff näyttää heti mitä testiä muutettiin

3. Exit-koodin käsittely

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.

- name: Run tests
  shell: bash
  run: |
    <testikomento> > results.txt 2>&1

Miksi ei pipeä (| tee):

# VÄÄRIN — pipe syö exit-koodin
<komento> | tee results.txt

# OIKEIN — redirect tiedostoon
<komento> > results.txt 2>&1

set -e ei pelasta pipe-tilanteessa — | syö exit-koodin kuten ennenkin. Redirectillä exit-koodi välittyy luonnollisesti.

4. Konttipolitiikka

  1. Julkiset registry-kontit kiinteällä versiollaalpine/helm:3.19.0, node:22, maven:3.9-eclipse-temurin-21. Toistettavuus ja turvallisuus eivät saa riippua ulkoisesta latest:sta
  2. Projektin omat CI-kontit latest-tägillä — buildattu ci-container-build-<kontti>.yml:llä. Kontin build-pipeline päivittää latest:n automaattisesti. Rebuild = käyttöönotto kaikissa pipelineissa ilman versioviittauksien päivittelyä. 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

CI-kontin build-workflow'n template: skills/ci-container-build/SKILL.md — sisältää valmiin ci-container-build-<kontti>.yml-pohjan jossa workflow_dispatch-tuki manuaaliajoon.

4.1 CI-kontin ajaminen jobissa

Ainoa sallittu tapa on container:-direktiivi. docker run komennolla kontin käynnistäminen stepin sisällä on anti-pattern.

jobs:
  <työkalu>:
    runs-on: ubuntu-latest
    container:
      image: ${{ inputs.<image-name> }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/checkout@v4
        with:
          repository: <owner>/gitea-ci-library
          path: .ci

      - name: Run <työkalu>
        shell: bash
        run: |
          mkdir -p "reports/<suite>"
          <komento> > "reports/<suite>/results.txt" 2>&1

      - name: Post-process reports
        if: always()
        run: |
          <mahdollinen_raporttien_jälkikäsittely>

      - name: Report
        if: always()
        run: bash .ci/scripts/ci-report.sh "<kuvaus>" <context> <suite>

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.

Mallit:

  • example-cucumber-tests.yml — ei post-processia
  • example-bats-tests.yml — post-process coverage + report

5. Raporttitasot

Testi tuottaa raportin reports/<suite>/-hakemistoon. Yksi ci-report.sh-kutsu hoitaa sekä julkaisun että commit-statuksen — erillistä Publish + Report Status -kaksivaiheisuutta ei tarvita.

Taso 1: Ei jälkikäsittelyä

Kun testi tuottaa raportit suoraan (kuten pytest --html tai cucumber-js --format html):

- name: Run tests
  shell: bash
  run: |
    mkdir -p "reports/<suite>"
    <testikomento>

- name: Report
  if: always()
  run: bash .ci/scripts/ci-report.sh "<kuvaus>" <context> <suite>

Taso 2: Jälkikäsittely tarvitaan

Kun testi tuottaa raakadataa (stdout, coverage-tiedostot) joka pitää muuntaa tai siirtää reports/<suite>/-hakemistoon, käytetään Post-process-steppiä:

- name: Run tests
  shell: bash
  run: |
    mkdir -p "reports/<suite>"
    <testikomento> > "reports/<suite>/results.txt" 2>&1

- name: Post-process reports
  if: always()
  run: |
    <coverage-extraktio>
    <HTML-generointi raa'asta outputista>

- name: Report
  if: always()
  run: bash .ci/scripts/ci-report.sh "<kuvaus>" <context> <suite>

Malli: example-bats-tests.yml.

Monta raportoitavaa tiedostoa

Kun reports/<suite>/-hakemistossa on useita tiedostoja tai alihakemistoja, ci-report.sh generoi automaattisesti reports/<suite>/index.html jos hakemistossa on enemmän kuin yksi raportoitava item.

reports/<suite>/
├── results.txt         ← testin stdout
├── junit.xml           ← testin JUnit XML -output
└── junit.html          ← generoitu HTML (xsltproc, tms.)

6. Nimeäminen

Tiedostonimet .gitea/workflows/-kansiossa noudattavat yhtenäistä rakennetta, jotta tiedostot löytyvät nopeasti ja niiden rooli on selvillä:

<komponentti>.ci-feature.yml                  ← feature-haaran reititin
<komponentti>.ci-main.yml                     ← main-haaran reititin
<komponentti>.<testityyppi>.yml               ← yksittäinen testi tai operaatio
<komponentti>.ci-container-build-<kontti>.yml ← CI-kontin build-workflow
<komponentti>.gitea-env.conf                  ← komponenttikohtainen konfiguraatio

Single repossa <komponentti> jätetään pois — tiedostot ovat suoraan ci-feature.yml, ci-main.yml, <testityyppi>.yml, ci-container-build-<kontti>.yml.

Monorepossa prefiksi pitää komponentin tiedostot yhdessä: ls <komponentti>.* löytää kaikki kerralla.

7. 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ä.

Ensisijainen ratkaisu: jokainen testi tuottaa tarvitsemansa datan itse. Ei upload-artifact + download-artifact -riippuvuuksia.

# OIKEIN — molemmat testit tuottavat oman datansa
- name: Prepare data
  run: <komento> > /tmp/data
- name: Validate data
  run: <validointikomento> /tmp/data

Miksi:

  • Testit pysyvät itsenäisinä — yhden testin fail ei estä muita
  • Ei "artifact expired" -virheitä myöhemmin
  • Ei pysyviä artifakteja siivoamatta

Konfiguraatiotiedosto (.gitea-env.conf)

Tiedosto on key=value-muotoinen (kuten .env). Kommentit ja tyhjät rivit sallittuja.

Single repo

# .gitea/workflows/gitea-env.conf
GITEA_API_URL=https://gitea.example.com
GIT_PAGES_URL=https://reports.example.com

Docker-artifaktin buildaavat projektit

DOCKER_REGISTRY=gitea.example.com/myorg
DOCKER_IMAGE_NAME=my-service
DOCKER_UI_URL=https://gitea.example.com/myorg/-/packages/container
#DOCKERFILE=Dockerfile.platform   # valinnainen, oletus Dockerfile

DOCKER_UI_URL ei sisällä image-nimeä — se on puhdas container-registryn osoite. Image-nimi lisätään automaattisesti URL:iin docker-build-push.yml:ssä.

Salaisuudet (Gitea Settings → Secrets)

Secret Pakollinen
GITEA_TOKEN Aina (Gitean sisäinen, automaattisesti saatavilla)
GIT_PAGES_PUBLISH_TOKEN Aina
DOCKER_USERNAME Vain jos buildaat kontteja
DOCKER_PASSWORD Vain jos buildaat kontteja

Monorepo

Monorepossa yhdessä repossa asuu useampi julkaistava komponentti. Jokaiselle komponentille oma conf-tiedosto .gitea/workflows/<komponentti>.gitea-env.conf, jossa on kaikki komponenttikohtainen tieto.

Suositus: komponentit omiin juurihakemistoihin

On suositeltavaa sijoittaa jokaisen komponentin koko lähdekoodi omaan juuritason hakemistoonsa (api/, frontend/, shared/). Tämä helpottaa paths:-filtteröintiä, pitää komponentit selkeästi erillään, ja tekee repossa navigoinnista suoraviivaista. Tämä on kuitenkin vain suositus — ei pakottava sääntö.

Ongelmat ja ratkaisut

Ongelma Ratkaisu
Monta komponenttia, yksi repo — mikä triggeröi? paths:-filtteri: push: { paths: ['<komponentti>/**'] }
Jokaisella komponentilla oma versio VERSION_FILE=<komponentti>/package.json confissa
Git-tägit sekaisin ellei nimiavaruutta GIT_TAG_PREFIX=<komponentti>/ confissa → tägi <komponentti>/1.2.3
Eri julkaisutahdit Riippumattomat CI-triggerit, omat versiopolut

Komponenttikohtainen conf

# .gitea/workflows/<komponentti>.gitea-env.conf
GITEA_API_URL=https://gitea.example.com
GIT_PAGES_URL=https://reports.example.com
DOCKER_REGISTRY=gitea.example.com/myorg
DOCKER_IMAGE_NAME=<image-nimi>
DOCKER_UI_URL=https://gitea.example.com/myorg/-/packages/container
GIT_TAG_PREFIX=<komponentti>/
# Jompikumpi — JSON (.version-kenttä) tai plain text:
VERSION_FILE=<komponentti>/package.json
#VERSION_FILE=<komponentti>/VERSION

Monorepo reititin

name: CI <Komponentti> Main
on:
  push:
    branches:
      - main
    paths:
      - '<komponentti>/**'

jobs:
  load-config:
    uses: <owner>/gitea-ci-library/.gitea/workflows/config-provider.yml@v1
    secrets: inherit
    with:
      config_path: .gitea/workflows/<komponentti>.gitea-env.conf

  check-version:
    needs: [load-config]
    uses: <owner>/gitea-ci-library/.gitea/workflows/check-version.yml@v1
    secrets: inherit
    with:
      env_json: ${{ needs.load-config.outputs.env_json }}

  <testit>:
    needs: [load-config, check-version]
    if: needs.check-version.outputs.artifact_exists != 'true'
    uses: ./.gitea/workflows/<komponentti>.<testi>.yml
    secrets: inherit
    with:
      env_json: ${{ needs.load-config.outputs.env_json }}

  build-push:
    needs: [load-config, check-version, <testit>]
    if: needs.check-version.outputs.artifact_exists != 'true'
    uses: <owner>/gitea-ci-library/.gitea/workflows/docker-build-push.yml@v1
    secrets: inherit
    with:
      env_json: ${{ needs.load-config.outputs.env_json }}
      version: ${{ needs.check-version.outputs.version }}

Version elinkaari per komponentti

GIT_TAG_PREFIX takaa että eri komponenttien versiohistoria pysyy erillään. Git-tägi <komponentti>/0.2.3 ei sekoitu toisen komponentin tägeihin.

check-version.yml suodattaa ja laskee seuraavan patchin vain kyseisen komponentin etuliitteellä. Idempotenttius toimii komponenttikohtaisesti: jos commitilla on jo tägi, pipeline skipataan if: artifact_exists != 'true'.

Mitä EI kannata tehdä monorepossa

  • Älä aja kaikkia komponentteja samasta triggeristä — paths: pitää CI:t erillisinä
  • Älä käytä samaa versionhallintatiedostoa usealle komponentille
  • Älä anna monorepo-parametreja pipeline-overrideina — kaikki kuuluu conf-tiedostoon

Versionhallinta

check-version.yml lukee version automaattisesti prioriteettijärjestyksessä:

# Lähde Formaatti
1 VERSION_FILE confissa Määritelty polku
2 VERSION-tiedosto (root) Plain text
3 package.json (root) .version-kenttä
4 pom.xml (root) <version>-elementti

major.minor otetaan tästä. Patch lasketaan automaattisesti git-tageista. Esim. VERSION = 0.2, tagit = 0.2.0, 0.2.1 → seuraava 0.2.2.


Branch protection (PR-gate)

Gitean Settings → Branches → Add Rule:

  • Branch: main
  • Enable Require Status Checks: päälle
  • Status checks: valitse testijobien nimet

Provider-rajapinnat — referenssi

Workflowt

Workflow Käyttötarkoitus
config-provider.yml Lataa + validoi .conf, tuottaa env_json
check-version.yml Tarkistaa onko commit buildattu, laskee version
docker-build-push.yml Buildaa + puskea Docker-imagen, tagittaa commitin
report-summary.yml GITHUB_STEP_SUMMARY-taulukko raporttilinkeillä (Gitea 1.27+)

Skriptit (kutsutaan .ci/scripts/-polun kautta)

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>
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ä)

ADR-yhteenveto — consumerin kannalta oleelliset säännöt

Reititin ei sisällä suorittavaa koodia (ADR 0010)

ci-feature.yml ja ci-main.yml koostuvat vain uses:, needs: ja if:-avainsanoista. Ei run:-komentoja, ei inline-skriptejä, ei actions/checkout.

Yksi steppi = yksi workflow_call-tiedosto

Jokainen job reitittimessä on oma workflow_call-tiedostonsa. Ei kahta eri komentoa samassa workflow'ssa.

Provider-versio on @v1 (ADR 0009)

Kaikki provider-viittaukset käyttävät @v1-tagia. @main on vain providerin oman repon sisäiseen dogfood-käyttöön. Breaking changet kielletty — v1-rajapinta on pysyvä.

Paikalliset uses: eivät käytä refiä

Gitea act runner v1.0.8 muodostaa paikallisista uses: ./.gitea/workflows/*.yml@main-viittauksista epävalidin git-refin main@<sha>, joka aiheuttaa virheen Revision invalid : reference must be defined once at the beginning.

Paikallisista uses:-direktiiveistä EI koskaan käytetä @main- tai muuta ref-päätettä:

  • uses: ./.gitea/workflows/chart.helm-lint.yml ← oikein
  • uses: ./.gitea/workflows/chart.helm-lint.yml@main ← väärin

Ilman refiä runner käyttää workflow'ta triggeröivästä commitista. Ulkoisten repojen viittauksissa (niko/...@v1) pääte pysyy. Nämä resolvoidaan eri reittiä ja toimivat oikein.

Exit-koodi on ainoa onnistumisen mittari (ADR 0008)

Ei pipeä (|) komennon perässä — se syö exit-koodin. Käytä redirectiä (> file 2>&1).

Commit-status vain raporttilinkille (ADR 0007)

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

Providerin scriptit haetaan actions/checkout-stepillä .ci/-polkuun. Consumer ei kopioi eikä muokkaa providerin tiedostoja.