Files
niko a5947551d4
CI Main / Load example-gitea-env.conf to pipeline env (push) Successful in 22s
CI Main / Check existing artifact (push) Successful in 20s
CI Git-Pages Main / Load git-pages.gitea-env.conf to pipeline env (push) Successful in 45s
CI Git-Pages Main / Check existing artifact (push) Successful in 31s
ci-helm-build-push Helm push 0.1.4
CI Main / Cucumber tests (push) Successful in 1m10s
CI Git-Pages Main / Build & Push Helm chart (push) Successful in 49s
CI Git-Pages Main / Report Summary (push) Successful in 5s
CI Main / Bats tests (push) Successful in 1m34s
ci-docker-build-push Docker push 0.2.21
CI Main / Build & Push Docker (push) Successful in 48s
CI Main / Report Summary (push) Successful in 6s
CI Main / Move provider version tag (push) Successful in 14s
CI Feature / Load example-gitea-env.conf to pipeline env (push) Successful in 33s
acc-tests Cucumber test report
CI Feature / Cucumber tests (push) Successful in 1m23s
unit-tests Bats test report
CI Feature / Bats tests (push) Successful in 1m34s
CI Feature / Report Summary (push) Successful in 5s
Fix/gitea commit status naming (#36)
Co-authored-by: moilanik <niko.moilanen@tietoevry.com>
Reviewed-on: #36
2026-06-21 08:43:32 +03:00

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

Katso tarkat mallipohjat ja esimerkit REFERENCE.md:stä.

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.

Katso täydellinen esimerkki REFERENCE.md:stä.

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): | syö exit-koodin. Käytä redirectiä >.

Yksi asia per step: Älä koskaan niputa useaa komentoa samaan run:-blockiin. bash -e pysäyttää koko stepin ensimmäisellä failaavalla komennolla, ja loput jäävät ajamatta. Sama pätee post-process-steppeihin.

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

4.1 Offline Container -vaatimus (DoD)

CI-kontin (ja kaikkien pipeline-konttien) on oltava täysin itseriittoisia:

Kontti ei lataa mitään pipeline-vaiheessa (workflow run -stepit) eikä kontin runtime-prosessissa (container: / docker run). Kaikki riippuvuudet pre-cachataan docker build -vaiheessa. Ainoa sallittu lataushetki on docker build.

Esimerkkejä rikkomuksista:

  • apk add, apt-get install, npm install, go mod download, pip install pipeline-stepissä
  • curl <url> | tar xz runtime-vaiheessa
  • Node.js-konttikuva ilman nodea (joudutaan asentamaan lennossa)

4.2 Kielikohtainen pre-cache

Kun kontissa testataan kielikohtaista koodia, kaikki riippuvuudet on pre-cachattava Dockerfilessä, ei pipeline-stepissä:

Kieli Pre-cache Dockerfilessä
Go COPY go.mod go.sum ./RUN go mod download
Java/Maven COPY pom.xml ./RUN mvn dependency:go-offline
Node COPY package.json package-lock.json ./RUN npm ci --omit=dev
Python COPY requirements.txt ./RUN pip install -r requirements.txt

Katso tarkat Dockerfile-esimerkit REFERENCE.md:stä.

4.3 CI-kontin ajaminen jobissa

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

Katso CI-kontin template REFERENCE.md:stä.

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. Varmista että CI-kontin Dockerfilessä on molemmat — muuten checkout ei toimi ja pipeline failaa.

4.4 Build-konteksti, .dockerignore ja COPY

Build-konteksti on aina tiedoston (Dockerfile, Chart.yaml) oman hakemiston juuri (dirname "${DOCKERFILE}" / dirname "${CHART_FILE}"). Kaikki suhteelliset polut — ignore-tiedosto, COPY, ADD — ovat suhteessa tähän kontekstiin.

Tiedosto Konteksti Ignore-tiedosto Käyttö
Dockerfile . ./.dockerignore docker build / COPY src/ src/
api/Dockerfile api/ api/.dockerignore docker build / COPY src/ src/
Chart.yaml (VERSION_FILE) . ./.helmignore helm package
api/Chart.yaml (VERSION_FILE) api/ api/.helmignore helm package

Helm chartin polku luetaan confin VERSION_FILE-kentästä — sama rivi jota check-version.yml käyttää version lähteenä. Yksi conf-rivi ohjaa molempia: sekä versionlaskentaa että chartin sijaintia.

Mitä ignore-tiedosto sisältää: Kaikki mikä EI ole konttiin tai chart-pakettiin tarkoitettua koodia tai resurssia, ON oltava ignore-tiedostossa:

  • Git- ja CI-historia (.git/, .gitea/, .github/)
  • Testikoodi, testidata, testiraportit (tests/, reports/, coverage/)
  • Dokumentaatio (docs/, guides/, *.md, CHANGELOG, README)
  • Editori- ja työkalukonfiguraatio (.vscode/, .cursor/, .idea/, .DS_Store)
  • Riippuvuudet jotka asennetaan Dockerfilessä (node_modules/)
  • Väliaikaistiedostot (tmp/, *.log)
  • Projektikohtaiset konfiguraatiot (.env, *.conf, CURRENT_PROVIDER_VERSION)

Miksi: Build-kontekstin koko vaikuttaa suoraan docker build -nopeuteen. Raskas konteksti (etenkin .git/ ja node_modules/) hidastaa buildia ja kuluttaa runnerin resursseja turhaan. Ylimääräiset tiedostot kontissa ovat tietoturvariski — tokenit, .env ja sensitiivinen data voivat päätyä kontin layeriin jos .dockerignore ei ole kattava.

4.5 COPY-kuri — kopioi vain tarvittava

COPY . . on kielletty. Jokainen COPY kopioi vain tarvittavat tiedostot tai hakemistot:

# VÄÄRIN
COPY . .

# OIKEIN
COPY package.json package-lock.json ./
COPY src/ src/
COPY public/ public/

Miksi:

  • Layer-cache: COPY . . rikkoo välimuistin — mikä tahansa muutos tiedostossa tyhjentää koko layerin
  • Tietoturva: konttiin voi päätyä ylimääräisiä tiedostoja vaikka .dockerignore olisi kattava (unohtunut ignore-rivi, uusi työkalu joka luo tiedostoja build-kontekstiin)
  • Luettavuus: COPY . . ei kerro mitä kontti todella sisältää
  • Kontin koko: eksplisiittinen COPY pitää image-koon kurissa

4.6 .helmignore — pidä chart-paketti siistinä

helm package käyttää .helmignore-tiedostoa samalla periaatteella kuin docker build käyttää .dockerignorea:

  • Chart-hakemisto luetaan confin VERSION_FILE-kentästä (dirname "${VERSION_FILE}")
  • ignore-tiedosto luetaan chart-hakemiston juuresta (sama konteksti kuin Chart.yaml, ks. 4.4)
  • Kaikki turha (testit, docs, git, CI-konffit, kuvat) on poissuljettava
  • Jos .helmignore puuttuu, helm package paketoi mukaan kaikki chart-hakemiston tiedostot — turhaa bulkkia registryyn

.helmignore on pakollinen jokaiselle chartille. Minimisisältö:

.git/
.gitignore
tests/
docs/
*.md
.DS_Store

5. Raporttitasot

Testi tuottaa raportin reports/<suite>/-hakemistoon. Yksi ci-report.sh-kutsu hoitaa sekä julkaisun että commit-statuksen.

Taso 1: Ei jälkikäsittelyä

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

  • testi kirjoittaa reports/<suite>/-hakemistoon
  • ci-report.sh julkaisee ja asettaa commit-statuksen

Taso 2: Jälkikäsittely tarvitaan

Kun testi tuottaa raakadataa (stdout, coverage-tiedostot) joka pitää muuntaa tai siirtää reports/<suite>/-hakemistoon. Jokainen operaatio omassa stepissään if: always().

Tarkat YAML-mallit molemmista tasoista: REFERENCE.md.

Subdir-sääntö: Alihakemisto näkyy indexissä VAIN jos se sisältää index.html:n.

6. Nimeäminen

Tiedostonimet .gitea/workflows/-kansiossa noudattavat yhtenäistä rakennetta:

<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. Monorepossa prefiksi pitää komponentin tiedostot yhdessä.

6.1 Commit status -nimeäminen

ci-report.sh-kutsun description (2. argumentti) ja context (3. argumentti) noudattavat seuraavaa kaavaa:

Single repo:

context:     <testityyppi>            (esim. unit-tests, acc-tests)
description: <Test type> test report  (esim. Unit test report)

Monorepo:

context:     <komponentti>.<testityyppi>            (esim. library.unit-tests)
description: <Komponentti>: <Test type> test report (esim. Library: Unit test report)

Gitea YAML: run: laita lainausmerkeillä run: |-blockiin — Gitea ei tue lainausmerkkejä yhden rivin run:-komennoissa.

      - name: Report
        if: always()
        run: |
          bash .ci/scripts/ci-report.sh "<Komponentti>: <Test type> test report" <komponentti>.<context> <suite> ${{ job.status }}

Build/push-status (Docker, Helm) on providerin hallussa — consumer ei vaikuta niiden nimeämiseen.

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.

8. Report-Summary — pakollinen jokaisen pipelinen lopuksi

Jokaisen reitittimen (oli se ci-main.yml, ci-feature.yml tai mikä tahansa) viimeinen job on report-summary.

Säännöt:

  • needs: sisältää kaikki edeltävät jobit — summary odottaa että kaikki on valmis (onnistui tai ei)
  • if: always() — ajetaan aina, vaikka pipeline olisi keskeytetty tai joku jobi failannut
  • suites: on välilyönnein eroteltu lista suiten nimistä (esim. bats cucumber). Tyhjä merkkijono sallittu jos testisuiteja ei ole.
  • Provider (report-summary.yml) hoitaa summaryn logiikan — reititin vain kutsuu

Miksi aina:

  • Gitea 1.27+ näyttää GITHUB_STEP_SUMMARY:n Actions UI:ssa. Ilman summarya pipeline näyttää epätäydelliseltä.
  • Summaryyn voidaan myöhemmin lisätä muutakin kuin testilinkkejä (build-artefaktit, deploy-tiedot).
  • Yhtenäinen rakenne jokaisessa pipeline-parissa vähentää kysymyksiä.

YAML-malli: REFERENCE.md.

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

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.

Exit-koodi on ainoa onnistumisen mittari (ADR 0008)

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

Providerin checkout ei kuulu consumerille

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

10. Build & Push -providerit

docker-build-push.yml — Docker image build & push

Buildaa ja pushee Docker-imagen OCI-registryyn. Ajaa suoraan runnerilla (ei container:-direktiiviä), joten actions/checkout toimii natiivisti.

env_json-avaimet (pakolliset):

DOCKER_REGISTRY: gitea.app.keskikuja.site/niko
DOCKER_IMAGE_NAME: my-app

Käyttö reitittimessä:

docker-build-push:
  uses: OWNER/gitea-ci-library/.gitea/workflows/docker-build-push.yml@v1
  needs: [check-version]
  if: needs.check-version.outputs.artifact_exists == 'false'
  secrets: inherit
  with:
    env_json: ${{ needs.load-config.outputs.env_json }}
    version:  ${{ needs.check-version.outputs.version }}

Tarkka input/secret-lista: docs/workflows.md.

helm-build-push.yml — Helm chart build & push

Pakkaa ja pushee Helm-chartin OCI-registryyn. Käyttää alpine/helm-konttia.

env_json-avaimet (pakolliset):

HELM_REGISTRY: gitea.app.keskikuja.site/niko
VERSION_FILE: platform-helm/Chart.yaml  # chart-hakemisto + versionlähde

Käyttö reitittimessä:

helm-build-push:
  uses: OWNER/gitea-ci-library/.gitea/workflows/helm-build-push.yml@v1
  needs: [check-version]
  if: needs.check-version.outputs.artifact_exists == 'false'
  secrets: inherit
  with:
    env_json: ${{ needs.load-config.outputs.env_json }}
    version:  ${{ needs.check-version.outputs.version }}

Chart-hakemisto johdetaan VERSION_FILE-polusta: dirname "${VERSION_FILE}". Jos VERSION_FILE on Chart.yaml, konteksti on juuri. Jos platform-helm/Chart.yaml, konteksti on platform-helm/.

Yksittäisten Helm-UI-linkkien raportointi: HELM_UI_URL on tarkoitettu yleiselle registry UI:lle — provider muodostaa linkin ${HELM_UI_URL}/${CHART_NAME}/${VERSION} automaattisesti.

Tarkka input/secret-lista: docs/workflows.md.

11. Multi-artifact monorepo -komponentti

Yksi monorepo-komponentti voi tuottaa useita artefakteja (esim. Docker image

  • Helm chart). Kukin artefakti on omassa reitittimessään — ei yhtä monoliittista pipelinea. Tämä on tietoinen arkkitehtuurivalinta:
  • Reitittimet ovat itsenäisiä: eri paths:-triggerit, eri tagit, eri confit
  • Yksi commit voi triggeröidä molemmat rinnakkain
  • Yhden artefaktin build tai testi ei estä toista

Esimerkki: platform-helm joka tuottaa Docker-imagen ja Helm chartin

.gitea/workflows/
├── platform-helm.ci-main.yml              # Docker build & push
├── platform-helm.gitea-env.conf           # Docker-konffi
├── platform-helm.helm-ci-main.yml         # Helm build & push
├── platform-helm.helm-gitea-env.conf      # Helm-konffi
├── platform-helm.helm-chart-lint.yml      # Chart-testi
└── platform-helm.ci-container-build-helm.yml  # CI-kontin build

platform-helm.gitea-env.conf (Docker)

DOCKER_REGISTRY=gitea.app.keskikuja.site/niko
DOCKER_IMAGE_NAME=platform-helm
GIT_TAG_PREFIX=platform-helm/

platform-helm.helm-gitea-env.conf (Helm)

HELM_REGISTRY=gitea.app.keskikuja.site/niko
VERSION_FILE=platform-helm/Chart.yaml
GIT_TAG_PREFIX=chart/

Reitittimet

platform-helm.ci-main.yml — Docker-buildi, testit, oma tagi:

name: platform-helm CI Main
on:
  push:
    branches: [main]
    paths:
      - platform-helm/**
      - .gitea/workflows/platform-helm.*

jobs:
  load-config:
    uses: OWNER/gitea-ci-library/.gitea/workflows/config-provider.yml@v1
    secrets: inherit
    with:
      config_path: .gitea/workflows/platform-helm.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 }}

  test:
    needs: [load-config, check-version]
    uses: ./.gitea/workflows/platform-helm.sbom-lint.yml
    secrets: inherit
    with:
      env_json: ${{ needs.load-config.outputs.env_json }}

  build-push:
    needs: [load-config, check-version, test]
    if: needs.check-version.outputs.artifact_exists == 'false'
    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 }}

  report-summary:
    needs: [load-config, test, build-push]
    if: always()
    uses: OWNER/gitea-ci-library/.gitea/workflows/report-summary.yml@v1
    with:
      env_json: ${{ needs.load-config.outputs.env_json }}
      suites: ''

platform-helm.helm-ci-main.yml — Helm-buildi, chart-testi, oma tagi:

name: platform-helm Helm CI Main
on:
  push:
    branches: [main]
    paths:
      - platform-helm/**
      - .gitea/workflows/platform-helm.helm*

jobs:
  load-config:
    uses: OWNER/gitea-ci-library/.gitea/workflows/config-provider.yml@v1
    secrets: inherit
    with:
      config_path: .gitea/workflows/platform-helm.helm-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 }}

  chart-lint:
    needs: [load-config, check-version]
    uses: ./.gitea/workflows/platform-helm.helm-chart-lint.yml
    secrets: inherit
    with:
      env_json: ${{ needs.load-config.outputs.env_json }}

  helm-build-push:
    needs: [load-config, check-version, chart-lint]
    if: needs.check-version.outputs.artifact_exists == 'false'
    uses: OWNER/gitea-ci-library/.gitea/workflows/helm-build-push.yml@v1
    secrets: inherit
    with:
      env_json: ${{ needs.load-config.outputs.env_json }}
      version:  ${{ needs.check-version.outputs.version }}

  report-summary:
    needs: [load-config, chart-lint, helm-build-push]
    if: always()
    uses: OWNER/gitea-ci-library/.gitea/workflows/report-summary.yml@v1
    with:
      env_json: ${{ needs.load-config.outputs.env_json }}
      suites: ''

Säännöt

  • Jokaisella artefaktilla on oma reititin, oma conf, omat testit
  • Conf-tiedoston nimi erottaa artefaktit: <komponentti>.gitea-env.conf vs <komponentti>.helm-gitea-env.conf
  • <komponentti>.helm--prefiksi erottaa Helm-artefaktin tiedostot
  • GIT_TAG_PREFIX pitää tagit erillään: platform-helm/1.2.3 vs chart/1.2.3
  • Molemmat reitittimet voivat triggeröityä samasta commitista