Co-authored-by: moilanik <niko.moilanen@tietoevry.com> Reviewed-on: #44
20 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
- Julkiset registry-kontit kiinteällä versiolla —
alpine/helm:3.19.0,node:22,maven:3.9-eclipse-temurin-21. Toistettavuus ja turvallisuus eivät saa riippua ulkoisestalatest:sta. - Projektin omat CI-kontit
latest-tägillä — buildattuci-container-build-<kontti>.yml:llä. Kontin build-pipeline päivittäälatest:n automaattisesti. Rebuild = käyttöönotto kaikissa pipelineissa ilman versioviittauksien päivittelyä. - Ei koskaan
curl-latauksia CI-ajon sisällä — työkalujen asennus CI-stepeissä hidastaa, epäluotettavaa, ja vaikeuttaa toistettavuutta. - 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-cachataandocker build-vaiheessa. Ainoa sallittu lataushetki ondocker build.
Esimerkkejä rikkomuksista:
apk add,apt-get install,npm install,go mod download,pip installpipeline-stepissäcurl <url> | tar xzruntime-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
.dockerignoreolisi kattava (unohtunut ignore-rivi, uusi työkalu joka luo tiedostoja build-kontekstiin) - Luettavuus:
COPY . .ei kerro mitä kontti todella sisältää - Kontin koko: eksplisiittinen
COPYpitää 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
.helmignorepuuttuu,helm packagepaketoi 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.shjulkaisee 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 rivinrun:-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 failannutsuites: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← oikeinuses: ./.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 # versionlähde, chart_path määrää chart-hakemiston
Inputit:
| Parametri | Pakollinen | Kuvaus |
|---|---|---|
env_json |
Kyllä | Konffi gitea-env.conf:stä |
version |
Kyllä | Version string (check-version output) |
chart_path |
Kyllä | Polku Chart.yaml-hakemistoon (esim. platform-helm) |
extra_dependency_paths |
Ei | Pilkulla erotellut polut subcharttien dependeinceille |
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_path: platform-helm
# extra_dependency_paths: subchart-a,subchart-b # tarvittaessa
chart_path on eksplisiittinen polku chart-hakemistoon (esim. platform-helm).
VERSION_FILE määrää version lähteen (Chart.yaml:n version-kenttä) —
nämä voivat olla eri polkuja, mutta tyypillisesti molemmat osoittavat samaan
chart-hakemistoon.
extra_dependency_paths: Jos chartilla on alikarttoja (subchartteja) jotka
vaativat helm dependency update -ajon ennen päächartin buildia, anna niiden
polut pilkulla eroteltuna. Provider ajaa helm dependency update jokaiselle
polulle ennen päächartin buildia.
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.confvs<komponentti>.helm-gitea-env.conf <komponentti>.helm--prefiksi erottaa Helm-artefaktin tiedostotGIT_TAG_PREFIXpitää tagit erillään:platform-helm/1.2.3vschart/1.2.3- Molemmat reitittimet voivat triggeröityä samasta commitista