aloitus dokumentaatio

This commit is contained in:
moilanik
2026-06-08 06:04:49 +03:00
parent 92479ebb9c
commit 66e1c98a8c
9 changed files with 1547 additions and 0 deletions
+215
View File
@@ -0,0 +1,215 @@
# Architecture — Gitea Actions CI -kirjasto
> Hub-dokumentti. Komponentit, niiden roolit ja rajapinnat. Yksityiskohtaiset kuvaukset linkitetyissä detail-dokumenteissa.
>
> Tämä dokumentti on **normatiivinen** — se määrittelee mikä on rakennettava. `design-rationale.md` kertoo miksi.
---
## Yleiskuvaus
Kirjasto on kokoelma **Gitea Actions reusable workflow** -tiedostoja, jotka orkestroivat mikropalveluiden build-, testaus-, raportointi-, deployment- ja test flow -prosessit. Projekti käyttää kirjastoa `uses:`-direktiivillä `.gitea/workflows/*.yml`-tiedostossaan ja määrittelee konfigurationsa `ci-flow-values.yaml`-tiedostossa.
Kirjasto on Gitea-spesifi. Se hyödyntää Gitean REST API:a commit-statusraportointiin, workflow-dispatchiin ja run-pollaukseen. Raportit tallennetaan MinIO:hon, josta ne ovat selailtavissa HTML-muodossa.
---
## Komponentit
### Reusable workflowt (4 kpl)
| Workflow | Tiedosto | Rooli |
|----------|----------|-------|
| **Feature flow** | `ci-feature.yml` | Testaa feature-branchin, generoi raportit, raportoi statuksen committiin. Ei buildaa konttia. |
| **Master flow** | `ci-master.yml` | Testaa, buildaa kontin, pushaa rekisteriin, tagittaa commitin, ketjuttaa test flow'n. |
| **Deployment flow** | `deploy.yml` | GitOps-deployment: päivittää YAML-arvoa, committaa, pushaa, raportoi cross-repo-statuksen. |
| **Test flow** | `test.yml` | Vastaanottaa dispatchin, ajaa testit, generoi raportit, raportoi statuksen. |
> Yksityiskohtaiset kuvaukset: [workflows.md](workflows.md)
### Jaetut skriptit
| Skripti | Rooli |
|---------|-------|
| **`report-status.sh`** | POSTaa build-statuksen Gitea `/api/v1/repos/{owner}/{repo}/statuses/{sha}` |
| **`dispatch-workflow.sh`** | Dispatchaa workflow'n toisessa repossa ja pollaa sen valmistumista |
| **`push-reports.sh`** | Puskaa testiraportit MinIO:hon ja generoi URL:n |
| **`tag-commit.sh`** | Tagittaa commitin versiolla Gitea REST API:n kautta |
> Yksityiskohtaiset kuvaukset: [shared-scripts.md](shared-scripts.md)
### Konfiguraatio
| Artefakti | Sijainti | Rooli |
|-----------|----------|-------|
| **`ci-flow-values.yaml`** | Projektin repo | Projektikohtainen konfiguraatio (docker, sonar, deployment, test-flow) |
| **Gitea org secrets** | Gitea organization | Tokenit ja salasanat |
| **Gitea org variables** | Gitea organization | Infra-tason asetukset (MinIO URL, SonarQube URL) |
> Yksityiskohtaiset kuvaukset: [config-model.md](config-model.md)
### Ulkoiset palvelut
| Palvelu | Rooli |
|---------|-------|
| **Gitea REST API** | Commit-statusraportointi, workflow-dispatch, run-pollaus, taggaus |
| **Gitea Packages** | Docker-imagen ja NPM-paketin säilytys |
| **MinIO** | Testiraporttien tallennus ja staattinen web-hosting |
| **SonarQube** | Koodin laadun analyysi ja quality gate |
---
## Järjestelmäkaavio
```mermaid
%%{init: {'theme': 'base', 'flowchart': {'arrowheadScale': 2}}}%%
flowchart TB
subgraph PROJ["Projektin repo"]
WF[".gitea/workflows/ci.yml
uses: gitea-ci-library/ci-master@v1"]
CONF["ci-flow-values.yaml"]
end
subgraph LIB["gitea-ci-library (reusable workflowt)"]
FEATURE["ci-feature.yml"]
MASTER["ci-master.yml"]
DEPLOY["deploy.yml"]
TEST["test.yml"]
end
subgraph SCRIPTS["Jaetut skriptit"]
REPORT["report-status.sh"]
DISPATCH["dispatch-workflow.sh"]
PUSHREP["push-reports.sh"]
TAG["tag-commit.sh"]
end
subgraph EXT["Ulkoiset palvelut"]
GITEA["Gitea API
+ Packages"]
MINIO["MinIO
(S3 + static web)"]
SONAR["SonarQube"]
end
subgraph HELM["Helm-repo"]
VALUES["values-{env}.yaml"]
end
subgraph TESTREPO["Testi-repo"]
TESTWF[".gitea/workflows/test.yml"]
end
WF -- "kutsuu" --> MASTER
WF -- "lukee" --> CONF
MASTER -- "käyttää" --> SCRIPTS
DEPLOY -- "käyttää" --> SCRIPTS
TEST -- "käyttää" --> SCRIPTS
REPORT -- "POST status" --> GITEA
DISPATCH -- "dispatch + poll" --> GITEA
PUSHREP -- "S3 upload" --> MINIO
TAG -- "POST tag" --> GITEA
MASTER -- "quality gate" --> SONAR
DEPLOY -- "muokkaa" --> VALUES
DEPLOY -- "commit + push" --> HELM
DISPATCH -- "dispatch" --> TESTWF
TESTWF -- "raportoi" --> GITEA
MINIO -- "URL commit-statusviestiin" --> GITEA
style PROJ fill:#1e3a5f,color:#f9fafb,stroke:#64748b
style LIB fill:#1f2937,color:#f9fafb,stroke:#64748b
style SCRIPTS fill:#064e3b,color:#f9fafb,stroke:#64748b
style EXT fill:#5c1a1a,color:#f9fafb,stroke:#64748b
style HELM fill:#4a1a6b,color:#f9fafb,stroke:#64748b
style TESTREPO fill:#4a1a6b,color:#f9fafb,stroke:#64748b
style WF fill:#2563eb,color:#ffffff
style CONF fill:#f59e0b,color:#111827
style FEATURE fill:#2563eb,color:#ffffff
style MASTER fill:#2563eb,color:#ffffff
style DEPLOY fill:#2563eb,color:#ffffff
style TEST fill:#2563eb,color:#ffffff
style REPORT fill:#059669,color:#ffffff
style DISPATCH fill:#059669,color:#ffffff
style PUSHREP fill:#059669,color:#ffffff
style TAG fill:#059669,color:#ffffff
style GITEA fill:#dc2626,color:#ffffff
style MINIO fill:#dc2626,color:#ffffff
style SONAR fill:#dc2626,color:#ffffff
style VALUES fill:#9333ea,color:#ffffff
style TESTWF fill:#9333ea,color:#ffffff
linkStyle default stroke:#9ca3af,stroke-width:3px
```
---
## Tietovuot
### 1. Commit-statusraportointi
```
Workflow-steppi → report-status.sh → POST Gitea API → commitin status päivittyy
↘ URL → raporttiin / buildiin
```
Jokainen vaihe (test, build, push) POSTaa oman statusviestinsä uniikilla `key`-arvolla. Samaan committiin kertyy useita rinnakkaisia statuksia.
### 2. Cross-repo traceability
```
Mikropalvelu (root-build) → Helm (deployment) → Testi (integraatio)
↓ ↓ ↓
Status omaan committiin Status omaan committiin Status omaan committiin
↑ ↑ ↑
Status root-committiin ← Status root-committiin ← Status root-committiin
(deployattu, testattu) (mistä kontti tuli) (mitä testattiin)
```
Root-build-viite kulkee `workflow_dispatch`in `inputs`-parametrina koko ketjun läpi.
### 3. Raporttien URL-generointi
```
push-reports.sh → mc cp ./reports/ minio/bucket/{repo}/{commit_short}/{report}/
→ URL = {MINIO_BASE}/{repo}/{commit_short}/{report}/index.html
→ report-status.sh POSTaa URL:n commit-statusviestiin
```
### 4. Test flow -ketjutus
```
ci-master.yml → test-flow-taulukko (ci-flow-values.yaml)
→ for each step:
dispatch-workflow.sh {test-repo} {inputs}
poll Gitea API run status
success? → next step
failure? → stop
```
---
## Laajennuspisteet
| Piste | Mekanismi | Tila |
|-------|-----------|------|
| **Docker-rekisterit** | Factory/adapter — `ci-flow-values.yaml``docker.type` → valitsee pusherin | MVP: Gitea Packages. Artifactory, Nexus myöhemmin |
| **Testikehykset** | `push-reports.sh` tukee mitä tahansa hakemistoa → MinIO | Cucumber, JUnit, JaCoCo, Maven Site, custom |
| **Build-ekosysteemit** | Workflow'n `container:` määrittelee projektin itse | Maven, Gradle, npm, mikä tahansa |
| **SonarQube** | Rajapinta vaihdettavissa — parempi kuin pollaus tutkitaan | Quality gate -tarkistus |
---
## Top-level rajoitteet
- Kaikki integraatio Gitea REST API:n kautta — ei suoria tietokantakytkentöjä, ei jaettua filesysteemiä
- Workflowt eivät jaa tilaa keskenään paitsi `workflow_dispatch`in `inputs`-parametrien kautta
- Raporttien URL on deterministinen: `{MINIO_BASE}/{repo_slug}/{commit_short}/{report}/`
- Cross-repo-statusraportoinnissa root-build on aina se mikropalvelun commit, josta ketju käynnistyi
## Repo-jako
| Repo | Sisältö |
|------|---------|
| **`gitea-ci-library`** | Reusable workflowt, jaetut skriptit, `report-service/`-moduuli (raporttiskriptit, retention CronJob, index.html-generointi) |
| **Deployment / infra -repo** (olemassa oleva) | MinIO Kubernetes-manifestit, Traefik OIDC middleware, ConfigMap, ingress |
`gitea-ci-library/report-service/` on oma moduulinsa samassa repossa — ei erillistä repositoriota, mutta selkeä sisäinen raja workflow-skriptien ja raporttipalvelun koodin välillä. Moduuli sisältää `docs/`-hakemiston deploy-esimerkeillä, mutta varsinainen deployment hoidetaan GitOps/Helm-repon kautta kuten muutkin palvelut.
+278
View File
@@ -0,0 +1,278 @@
# Konfiguraatiomalli — `ci-flow-values.yaml`
> Kuuluu arkkitehtuuriin: [architecture.md](architecture.md). Tämä dokumentti määrittelee projektikohtaisen konfiguraation skeeman, `isContainerBuild()`-mekanismin ja version check -skriptin.
---
## Miksi redesign
Jenkins-version `ci-flow-values.yaml` oli rakennettu Jenkinsin ympäristömuuttuja- ja credential-mallin ympärille. Gitea Actionsissa konfiguraatio luetaan suoraan YAML:sta workflow'n sisällä — ei tarvita env-muuttujien kautta kierrättämistä. Lisäksi:
- `creditentials`-viittaukset korvautuvat Gitea org secrets/variables -mekanismilla
- `test-flow`-syntaksi yksinkertaistuu (ei enää JSON-serialisointia env-muuttujiin)
- Docker/NPM-rekisterit MVP:ssä vain Gitea Packages — factory/adapter-pattern valmiina laajennukselle
- `sonarqube`-konfiguraatio pysyy samankaltaisena
---
## Skeema
```yaml
# ci-flow-values.yaml — projektin juuressa
#
# Pakolliset osiot: docker (jos master-branch buildaa kontin), test-flow (jos ketjutetaan)
# Vapaaehtoiset: sonarqube, deployment
docker:
registry: gitea # gitea | artifactory | nexus (MVP: vain gitea)
imageName: temperature-store # kontin nimi, pakollinen
sonarqube:
url: https://sonar.example.com
projectKey: temperature-store
deployment:
jobName: deploy # deploy-workflown nimi (vakio)
projectFolder: microservices # polku Helm-repossa
fileName: values-{.environment}.yaml
property: container.version
test-flow:
- deploy: development # 1. deploy development-ympäristöön
wait: true # odota deployn valmistumista
- test:
name: "integration fast"
environment: integration
repo: tests/integration # testi-repo (owner/repo)
workflow: test.yml # workflow-tiedosto testi-repossa
ref: main # branch
tags: "@temperature and not @slow"
- deploy: staging
wait: true
- test:
name: e2e
environment: staging
repo: tests/e2e
workflow: test.yml
ref: main
tags: "@e2e and not @slow"
```
### Kenttäkuvaukset
#### `docker`
| Kenttä | Pakollinen | Kuvaus |
|--------|------------|--------|
| `registry` | Ei (oletus `gitea`) | Rekisterityyppi. MVP: `gitea`. Factory/adapter-pattern avaa `artifactory`, `nexus` myöhemmin |
| `imageName` | Kyllä | Kontin nimi. Lopullinen tagi: `{gitea_host}/{owner}/{imageName}:{version}.{run_number}` |
#### `sonarqube`
| Kenttä | Pakollinen | Kuvaus |
|--------|------------|--------|
| `url` | Kyllä | SonarQube-palvelimen URL |
| `projectKey` | Kyllä | SonarQube-projektin avain |
SonarQube-token tulee Gitea org secretsista (`SONAR_TOKEN`). Ei `creditentials`-viittausta.
#### `deployment`
| Kenttä | Pakollinen | Kuvaus |
|--------|------------|--------|
| `jobName` | Ei (oletus `deploy`) | Deploy-workflown tiedostonimi ilman `.yml`-päätettä |
| `projectFolder` | Kyllä | Polku mikropalvelun kansioon Helm-repossa |
| `fileName` | Kyllä | YAML-tiedoston nimi. `{.environment}` korvataan ympäristön nimellä |
| `property` | Kyllä | Päivitettävä avain (piste-eroteltu polku, esim. `container.version`) |
Deploy-token (kirjoitusoikeus Helm-repoon) tulee Gitea org secretsista (`DEPLOY_TOKEN`).
#### `test-flow`
Array testi-steppejä. Jokainen steppi on joko `deploy` tai `test`.
**`deploy`-steppi:**
| Kenttä | Pakollinen | Kuvaus |
|--------|------------|--------|
| `deploy` | Kyllä | Ympäristön nimi (esim. `development`, `staging`) |
| `wait` | Ei (oletus `true`) | Odotetaanko deployn valmistumista ennen seuraavaa steppiä |
**`test`-steppi:**
| Kenttä | Pakollinen | Kuvaus |
|--------|------------|--------|
| `name` | Kyllä | Testivaiheen nimi (näkyy statusviestissä) |
| `environment` | Kyllä | Ympäristö jota vasten testataan |
| `repo` | Kyllä | Testi-repo muodossa `owner/repo` |
| `workflow` | Kyllä | Workflow-tiedosto testi-repossa |
| `ref` | Kyllä | Branch (esim. `main`) |
| `tags` | Ei | Cucumber-tagit (esim. `"@smoke and not @slow"`) |
| `versionApiUrl` | Ei | URL deployed-version tarkistukseen |
| `versionCheckScript` | Ei | Polku version check -skriptiin (repossa tai kontissa) |
---
## `isContainerBuild()`-mekanismi
**Ongelma:** Samaa committia vasten voidaan ajaa master-workflow useita kertoja. On mieletöntä buildata kontti uudestaan, koska commit on jo tagätty versiolla ja kontti on olemassa rekisterissä. Uudelleenbuildaus aiheuttaa versiokonflikteja ja tuhlaa CI-aikaa.
**Ratkaisu:** Workflow'n alussa tarkistetaan, onko tälle commitille jo olemassa versiotagi:
```bash
# is-container-built.sh
TAG=$(git tag --points-at HEAD | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -1)
if [ -n "$TAG" ]; then
echo "container_already_built=true" >> $GITHUB_ENV
echo "container_version=$TAG" >> $GITHUB_ENV
else
echo "container_already_built=false" >> $GITHUB_ENV
fi
```
Workflow käyttää tätä ehtona:
```yaml
jobs:
build-container:
if: env.container_already_built != 'true'
steps:
- run: docker build ...
test-flow:
if: always()
needs: [build-container]
steps:
- run: dispatch-workflow.sh ...
```
**Mitä `isContainerBuild() == true` tarkoittaa käytännössä:**
- Kontti on jo buildattu ja pushattu rekisteriin
- Commit on tagätty versiolla (esim. `1.2.3.42`)
- Build-steppi skipataan → siirrytään suoraan test flow'hun
- Sama versio deployataan ja testataan — ei uutta konttia
**Miksi tämä on välttämätöntä:**
- Estää versiokonfliktit: `1.2.3.42` ei voi olla kahdesti
- Säästää CI-aikaa: kontin buildaus on hitain vaihe
- Pitää commitin ja kontin välisen suhteen yksiselitteisenä: `git tag` kertoo suoraan mikä versio vastaa tätä committia
---
## Docker-labelit
Jenkins-versiossa konttiin injektoitiin metadataa Docker-labelien kautta. Sama käytäntö jatkuu:
```bash
docker build \
--label "git.commit=${GITHUB_SHA::8}" \
--label "git.commitBy=${GITHUB_ACTOR}" \
--label "build.date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \
--label "build.run=${GITHUB_RUN_NUMBER}" \
--label "version=${DOCKER_VERSION}" \
-t ${DOCKER_TAG} .
```
| Label | Arvo | Lähde |
|-------|------|-------|
| `git.commit` | 8-merkkinen hash | `GITHUB_SHA::8` |
| `git.commitBy` | Ajon laukaisija | `GITHUB_ACTOR` |
| `build.date` | ISO 8601 UTC | `date -u` |
| `build.run` | Ajon järjestysnumero | `GITHUB_RUN_NUMBER` |
| `version` | Kontin versio | `1.2.3.42` |
Näillä labeleilla kontista näkee suoraan: kuka buildasi, milloin, mistä commitista, millä versiolla. Vianjäljitys kontista koodiin on suora.
---
## Version check (Fibonacci-backoff)
Ennen kuin testit ajetaan, pitää varmistua että haluttu konttiversio on oikeasti deployattu ympäristöön. Muuten testataan väärää versiota.
**Malli:** Skripti, joka pollaa deployatun version API:a Fibonacci-backoffilla:
```bash
#!/bin/bash
# check-version.sh <version_api_url> <expected_version>
# Palauttaa 0 jos versiot täsmäävät, 1 muuten.
URL=$1
EXPECTED=$2
MAX_RETRIES=10
# Fibonacci-sekvenssi: 1 2 3 5 8 13 21 34 55 89
FIB=(1 2 3 5 8 13 21 34 55 89)
for i in $(seq 1 $MAX_RETRIES); do
ACTUAL=$(curl -s "$URL" | jq -r '.version // empty')
if [ "$ACTUAL" = "$EXPECTED" ]; then
echo "Version match: $ACTUAL"
exit 0
fi
echo "Attempt $i/$MAX_RETRIES: $ACTUAL != $EXPECTED, waiting ${FIB[$i-1]}s..."
sleep ${FIB[$i-1]}
done
echo "Version mismatch after $MAX_RETRIES attempts"
exit 1
```
**Miksi Fibonacci:** Uusi deploy käynnistyy nopeasti (ensimmäiset pollaukset tiheään). Jos kontin pullaus tai podin käynnistys kestää, pollausväli kasvaa — ei turhaan kuormiteta API:a. Maksimiaika: ~231 sekuntia (summa 1..89).
Version check -skripti joko:
- Asuu testi-repossa (projektin oma toteutus) → `versionCheckScript`-kenttä
- Tai käyttää geneeristä API:a → `versionApiUrl`-kenttä, skripti on osa kirjastoa
---
## `doNotDowngrade`
Jenkinsin deploy-jobissa oli `doNotDowngrade`-parametri, joka esti vanhemman version deployaamisen uudemman päälle. Gitea Actions -versiossa:
- **Ei MVP:ssä.** Deploy tekee sen mitä käsketään. `doNotDowngrade` on lisäturva, joka voidaan lisätä deploy-workflow'hun myöhemmin.
- **Mekanismi:** Ennen YAML:n muokkausta tarkistetaan nykyinen versio. Jos `new < current`, skipataan ja raportoidaan.
- **Toteutus:** Yksi `if`-ehto deploy-workflow'n alussa, ei vaadi muutoksia muualle.
---
## UX-esimerkki: projektin `.gitea/workflows/ci.yml`
Näin mikropalvelun kehittäjä käyttää kirjastoa:
```yaml
# .gitea/workflows/ci.yml — projektin juuressa
name: CI
on:
push:
branches: ["**"]
workflow_dispatch:
jobs:
feature:
if: github.ref != 'refs/heads/master'
uses: org/gitea-ci-library/.gitea/workflows/ci-feature.yml@v1
secrets: inherit
with:
config-file: ci-flow-values.yaml
maven-image: maven:3.9-eclipse-temurin-21
master:
if: github.ref == 'refs/heads/master'
uses: org/gitea-ci-library/.gitea/workflows/ci-master.yml@v1
secrets: inherit
with:
config-file: ci-flow-values.yaml
maven-image: maven:3.9-eclipse-temurin-21
docker-image: docker:26-dind
```
Kehittäjä määrittelee:
- Millä kontilla buildataan (`maven-image` — koska kirjasto ei tiedä projektin Java-versiota)
- Mistä konfiguraatio luetaan (`config-file`)
- Millä docker-versiolla kontit rakennetaan (`docker-image`)
Kaikki Git-, raportointi-, SonarQube- ja deploy-konfiguraatio on `ci-flow-values.yaml`:ssa.
+154
View File
@@ -0,0 +1,154 @@
# Design Rationale — Gitea Actions CI -kirjasto
> Miksi kirjasto on rakennettu näin. Arvot, periaatteet ja reunaehdot, joiden varaan arkkitehtuuri nojaa.
>
> Tämä dokumentti on **normatiivinen** — arkkitehtuurin on noudatettava näitä periaatteita. Jos ehdotettu muutos on ristiriidassa rationalen kanssa, rationalen on muututtava ensin.
---
## Miksi tämä projekti on olemassa
Organisaatiolla on tuotannossa Jenkins-pohjainen CI-järjestelmä (`ci-jenkins-library`, 53 lähdetiedostoa, 21 Cucumber-featurea), joka on osoittautunut toimivaksi vuosien ajan. Se integroi Git-commitit, testiraportoinnin, Docker-buildit, deploymentin ja test flow'n yhtenäiseksi putkeksi, jossa jokainen vaihe raportoi tilansa suoraan Git-committiin.
Jenkins on kuitenkin raskas ylläpitää Kubernetesissa, ja organisaatio on siirtymässä Giteaan. Tavoitteena on **sama toiminnallisuus, pienemmällä ylläpitotaakalla**, hyödyntäen Gitea Actionsin natiiveja ominaisuuksia.
Kirjasto ei ole Jenkins-migraatiotyökalu. Se on Gitea Actions -natiivi uudelleensuunnittelu, joka säilyttää Jenkins-version todistetut patternit mutta hylkää ne osat, jotka olivat sidottuja Jenkinsin arkkitehtuuriin.
---
## Suunnitteluperiaatteet
### 1. Git-commit on universaali statusnäkymä
Buildin jokainen vaihe raportoi tilansa Git-committiin. Kehittäjä näkee yhdellä silmäyksellä, missä vaiheessa build on — ei tarvitse navigoida CI-järjestelmän UI:hun.
**Miksi:** Jenkins-versio osoitti, että commit-statusviestit poistavat tarpeen CI-dashboardille. Kehittäjä työskentelee Gitissä, joten status kuuluu Gitiin. Statusviestien `url`-kenttä linkittää suoraan raportteihin — Cucumber-tulokset, SonarQube-tulokset, Docker-rekisteri — ilman että URL tarvitsee etsiä erikseen.
**Mitä tarkoittaa käytännössä:** Jokainen `testBegin/End`, `buildBegin/End`, `pushBegin/End`-vaihe POSTaa Gitean REST APIin (`/api/v1/repos/{owner}/{repo}/statuses/{sha}`). Uniikki `key` per vaihe estää duplikaatit ja mahdollistaa rinnakkaiset statukset samassa commitissa.
### 2. Reusable workflow — ei omaa runtimea
Kirjasto jaetaan Gitea Actionsin reusable workflow -mekanismilla. Ei Docker-pohjaisia custom actioneita, ei erillistä ajonaikaista palvelinta.
**Miksi:** Reusable workflow on Gitea Actionsin natiivein tapa jakaa CI-logiikkaa. Se on kevein (ei ylimääräistä runtimea), läpinäkyvin (workflow-tiedosto on luettavissa sellaisenaan) ja teknisesti kestävin (Gitea huolehtii versioinnista ja jakelusta). Custom actionit otetaan käyttöön vain jos reusable workflow'n rajat tulevat vastaan.
**Mitä tämä ei ole:** Tämä ei ole monorepo-työkalu, joka asennetaan projekteihin. Tämä on joukko `.gitea/workflows/`-tiedostoja, joihin mikropalvelut viittaavat `uses:`-direktiivillä.
### 3. Konfiguraatio kuuluu repoon
Projektikohtainen konfiguraatio (`ci-flow-values.yaml`-tyyppinen tiedosto) asuu mikropalvelun omassa repossa. Reusable workflow lukee sen, ei toisinpäin.
**Miksi:** Mikropalvelun kehittäjä omistaa buildinsa. Hän tietää mitä Dockefileä käytetään, mitä SonarQube-projektia, mitä testi-steppejä tarvitaan. Jos konfiguraatio hajautetaan useaan repoon, muutokset vaativat koordinaatiota, ja yhden totuuden lähteen periaate rikkoutuu.
**Poikkeus:** Infra-tason asetukset (MinIO-URL, Gitea-instanssin URL) ovat organisaatiotasolla Gitean organization secrets/variables -mekanismissa. Ne eivät ole repokohtaisia, koska DNS voi osoittaa eri paikkaan kuin repo, ja usean repossa toistuva sama arvo on ylläpitoriski.
### 4. Deterministinen testigraafi, vaiheittainen suoritus
Test flow on tunnettu ennen buildin alkua, ja testit ajetaan yksi kerrallaan. Jos steppi epäonnistuu, koko flow pysähtyy.
**Miksi:** Rinnakkainen suoritus aiheuttaa resurssikilpailua (erityisesti suorituskykytestit) ja piilottaa virheitä. Kun integraatiotesti epäonnistuu, e2e-testien ajaminen on turhaa — konttia ei viedä tuotantoon, eikä kukaan lue niitä tuloksia. Vaiheittainen suoritus on deterministinen, debuggattava ja säästää CI-minuutteja.
**Miten:** Orkestroiva workflow käyttää Gitea REST API:a workflow-dispatchiin ja pollaa ajettavan workflow'n tilaa synkronisesti (`GET /api/v1/repos/{owner}/{repo}/actions/runs/{id}`). Tämä vastaa Jenkinsin `buildJob()`-kutsun semantiikkaa, mutta toteutetaan curl + pollaus -silmukalla.
### 5. Raportit ovat selailtavia URL:n takana
Testiraportit (Cucumber HTML, Jacoco HTML, JUnit XML) viedään MinIO:hon, jonka staattinen web-hosting renderöi ne selaimessa. URL linkitetään Git-committiin.
**Miksi:** Jenkins-versiossa linkki Cucumber-raporttiin oli kriittinen feature — kehittäjä klikkasi commitin statusviestistä ja näki heti mitkä testit epäonnistuivat. Gitea Actionsin sisäänrakennettu artifact-järjestelmä ei tue HTML-selailtavuutta (vain ZIP-lataus). MinIO täyttää tämän aukon: se on kevyt, Kubernetes-natiivi, ja sen S3 API on standardi. URL-rakenne `{BASE}/{repo_slug}/{commit_short}/{report_type}/` on ennustettavissa ilman erillistä URL-generaattoria.
### 6. Yksi CI-alusta, yksi integraatiopiste
Kirjasto tukee vain Giteaa. Ei GitLab-, BitBucket- tai GitHub-abstraktioita.
**Miksi:** Jenkins-versio tuki neljää Git-alustaa, koska Jenkins itsessään ei tarjonnut commit-statusraportointia. Gitea Actionsissa tilanne on päinvastainen — Gitea on sekä CI-että Git-alusta. Multi-platform-tuesta tulisi pelkkää ylimääräistä abstraktiota ilman konkreettista tarvetta.
**Mitä tarkoittaa tulevaisuudessa:** Jos toinen alusta tulee ajankohtaiseksi, Gitea-versiota käytetään joko pohjana redesignille tai mallina erilliselle toteutukselle. Rajapintoja ei suunnitella etukäteen alustariippumattomiksi — se on ennenaikaista optimointia.
### 7. Cross-repo commit traceability
Kun build-ketju ylittää reporajat (mikropalvelu → deployment → integraatiotestit → e2e-testit), jokainen vaihe raportoi kahteen suuntaan: omaan committiinsa ja takaisin root-committiin, josta ketju käynnistyi.
**Miksi:** Kehittäjän ei pidä arvailla mikä versio on missäkin ympäristössä. Kun mikropalvelun commitista näkee koko ketjun — buildattu, deployattu stagingiin, integraatiotestit ajettu, e2e hyväksytty — virheenjäljitys on suora polku commitista ympäristöön. Vastaavasti Helm-repon commit kertoo mikä konttiversio sinne deployattiin ja kenen mikropalvelu-commitista se tuli. Tämä on Jenkins-version **eniten arvoa tuottanut ominaisuus**.
**Mekanismi:**
```mermaid
%%{init: {'theme': 'base'}}%%
sequenceDiagram
participant MR as Mikropalvelu-repo
participant HR as Helm-repo
participant TR as Testi-repo
participant GA as Gitea API
Note over MR: commit abc123
Note over MR: build kontti v1.2.3
MR->>GA: POST dispatch deploy-workflow
GA->>HR: workflow käyntiin
Note over HR: commit def456
Note over HR: container.version = 1.2.3
HR->>GA: POST status "deployed by abc123"
GA->>MR: Status: deployed to staging
Note right of MR: URL → def456
HR->>GA: POST status "from abc123"
GA->>HR: Status: from abc123
Note right of HR: URL → abc123
MR->>GA: POST dispatch integraatiotestit
GA->>TR: workflow käyntiin
Note over TR: commit ghi789
TR->>GA: POST status "integration OK"
GA->>MR: Status: integration OK
Note right of MR: URL → ghi789
TR->>GA: POST status "tested v1.2.3"
GA->>HR: Status: tested v1.2.3
Note right of HR: URL → def456
TR->>GA: POST status "tested abc123"
GA->>MR: Status: tested abc123 (root)
Note right of MR: URL → abc123
```
**Mitä tarkoittaa käytännössä:** Jokaisella workflow'lla on kaksi build-referenssiä: `current` (oma commit) ja `root` (mikropalvelun commit, josta ketju alkoi). Molempiin POSTataan statusviestit. Root-build kulkee workflow-dispatchin `inputs`-parametrina koko ketjun läpi. Deployment-job raportoi sekä Helm-repon committiin ("from abc123") että mikropalvelun committiin ("deployed to staging → def456"). Testi-job raportoi omaan committiinsa, mikropalvelun committiin ja Helm-repon committiin.
---
## Arkkitehtuuriset rajoitteet
### Mitä kirjasto EI tee
- **Ei ulkoista orkestraattoria.** Test flow -ketjutus perustuu Gitean REST APIin ja workflowhin itseensä. Ei erillistä palvelinta, joka hallinnoi tilaa.
- **Ei Jenkins-migraatiota.** Vanhaa Jenkinsfileä ei voi ajaa Gitea Actionsissa. Tämä on uusi kirjasto uudella konfiguraatioformaatilla.
- **Ei reaaliaikaista build-seurantaa.** Commit-statusviestit ovat pollattavia, eivät push-pohjaisia. Gitean UI hoitaa reaaliaikaisuuden.
- **Ei multi-repo-monorepo-konfiguraatiota.** Jokainen mikropalvelu omistaa oman `ci-flow-values.yaml`:nsa. Jaettua konfiguraatiota ei ole projektitasolla.
---
## Teknologiavalinnat (seurauksina ylläolevista periaatteista)
| Valinta | Miksi |
|---------|------|
| **Gitea Actions reusable workflows** | Periaate 2: natiivein tapa jakaa CI-logiikkaa ilman omaa runtimea |
| **Gitea REST API** (`/api/v1/...`) | Periaate 1: commit-statusraportointi. Periaate 4: workflow-dispatch ja status-pollaus. Periaate 7: cross-repo statusraportointi useaan committiin |
| **MinIO** (S3-yhteensopiva) | Periaate 5: HTML-selailtavat raportit ilman ulkoista palvelinta. Kubernetes-natiivi, yksi binääri |
| **YAML** konfiguraatioformaattina | Periaate 3: repo omistaa konffinsa. YAML on luettava, versioitava ja tuttu Jenkins-versiosta |
| **curl + jq + bash** integraatiokerroksena | Periaate 2: ei custom action -runtimea. Gitea REST API:a kutsutaan suoraan workflow-stepistä |
| **Gitea organization secrets/variables** | Periaate 3: infra-tason asetukset (MinIO-URL, tokenit) eivät kuulu reposuuteen |
---
## Mitä tietoisesti hylättiin
| Hylätty | Syy |
|---------|-----|
| Multi-Git-platform-tuki (GitLab, BitBucket) | Vain Gitea on relevantti. Abstraktointi ilman tarvetta on turhaa kompleksisuutta |
| Gitea Packages raporttien hostingiin | Ei tue HTML-selailtavuutta — vain binääriartefaktien lataus |
| Gitea Releases raporttien hostingiin | Saastuttaa release-historian. Satoja CI-raportteja oikeiden julkaisujen seassa |
| Gitea Pages + reports-branch | Race condition rinnakkaisten buildien pushissa samaan branchiin |
| Ulkoinen orkestraattoripalvelin | Ylimääräinen ylläpidettävä. Gitean oma API riittää |
| Docker-pohjaiset custom actionit | Tuovat riippuvuuden Docker-rekisteriin ja monimutkaistavat jakelua. Otetaan käyttöön vain pakon edessä |
| `repository_dispatch` (webhook) test flow -ketjutukseen | Lisää konfiguraatiota vastaanottaviin repoihin. Suora REST API -kutsu on eksplisiittisempi ja debuggattavampi |
+199
View File
@@ -0,0 +1,199 @@
# Raporttivarasto — MinIO
> Kuuluu arkkitehtuuriin: [architecture.md](architecture.md). Tämä dokumentti määrittelee testiraporttien tallennuksen, URL-rakenteen, autentikoinnin ja retention policyn.
---
## Miksi MinIO
Gitea Actionsin sisäänrakennettu artifact-järjestelmä ei tue HTML-selailtavuutta (vain ZIP-lataus), ja artifactien retentio on aikapohjainen (oletus 90 vrk). Jenkins-versiossa raportit olivat selailtavissa suoraan buildista ja pysyivät build-historian mukana.
MinIO täyttää tämän aukon:
- **S3-yhteensopiva** — standardi API, laaja työkalutuki (`mc`, `s3cmd`, AWS SDK)
- **Staattinen web-hosting** — HTML-raportit renderöityvät selaimessa suoraan bucketista
- **Kubernetes-natiivi** — yksi binääri, helppo deployata samaan klusteriin
- **Ei per-repo-konfiguraatiota** — yksi bucket palvelee kaikkia projekteja
- **Ennustettava URL** — polku rakentuu deterministisesti reposta ja commitista
## URL-rakenne
```
{MINIO_BASE}/{repo_slug}/{commit_short}/{report_type}/index.html
```
| Osa | Lähde | Esimerkki |
|-----|-------|-----------|
| `MINIO_BASE` | Gitea org variable `MINIO_BASE_URL` | `https://reports.smith.keskikuja.site` |
| `repo_slug` | `GITHUB_REPOSITORY` → slug | `temperature-store` |
| `commit_short` | `GITHUB_SHA` → 8 merkkiä | `abc12345` |
| `report_type` | Raportin tyyppi | `cucumber`, `jacoco`, `junit`, `site` |
URL rakennetaan `push-reports.sh`-skriptissä ja POSTataan Gitea-commitin statusviestiin `url`-kenttään.
## Staattinen web-hosting
MinIO-bucket konfiguroidaan staattiseksi web-sivustoksi:
```bash
mc anonymous set download minio/reports
mc website create minio/reports --region us-east-1
```
Bucketin rakenne:
```
reports/
├── temperature-store/
│ ├── abc12345/
│ │ ├── cucumber/
│ │ │ └── overview-features.html
│ │ ├── jacoco/
│ │ │ └── index.html
│ │ └── site/
│ │ └── index.html
│ └── def67890/
│ └── ...
├── user-service/
│ └── ...
```
Jokaisella buildilla on oma `{commit_short}`-hakemistonsa — ei race conditionia rinnakkaisten buildien välillä.
## Autentikointi: OIDC + Traefik middleware
Raporttien tulee olla katseltavissa ilman erillistä kirjautumista (muuten commitin statusviestin URL-linkki ei toimi suoraan). Samalla julkinen bucket halutaan suojata.
**Ratkaisu:** MinIO asetetaan Traefik reverse-proxyn taakse. Traefik middleware hoitaa OIDC-autentikoinnin, jossa:
1. Käyttäjä klikkaa raportin URL:ää commitin statusviestistä
2. Traefik ohjaa OIDC-kirjautumiseen (Gitea OAuth2 provider)
3. Onnistuneen kirjautumisen jälkeen käyttäjä ohjataan raporttiin
4. Session säilyy — ei tarvitse kirjautua jokaista raporttia varten
```
Selain ──→ Traefik ──→ OIDC middleware ──→ Gitea OAuth2
└──→ MinIO (bucket reports, static web)
```
**CI-pusku ohittaa OIDC:n:** Workflow'n `push-reports.sh` käyttää MinIO:n S3 API:a suoraan access key + secret key -parilla (Gitea org secrets). CI-liikenne ei kulje julkisen ingressin kautta — `mc`-työkalu puhuu suoraan MinIO-palvelulle klusterin sisällä.
## Retention policy
Pelkkä aikaperustainen retentio ("poista yli 90 vrk vanhat") ei riitä. Retention policyn pitää huomioida:
| Kriteeri | Kuvaus |
|----------|--------|
| **Aika** | Raportti säilyy X päivää buildin jälkeen |
| **Branch** | `master`-branchin raportit säilyvät pidempään kuin feature-branchien |
| **Tagi** | Version kanssa tagitun commitin raportteja ei poisteta koskaan |
| **Viimeisin N** | Jokaisesta branchista säilytetään vähintään N uusinta raporttia |
**Toteutus:** Retention policy konfiguroidaan **ConfigMap:lla**, jonka siivousskripti lukee. ConfigMap on osa MinIO-deploymentin Kubernetes-manifestia.
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: minio-report-retention
data:
retention.yaml: |
rules:
- branch: "master"
maxAgeDays: 365
keepMin: 20
- branch: "feature/*"
maxAgeDays: 90
keepMin: 5
- tagged: true
maxAgeDays: -1 # ei koskaan poisteta
keepMin: -1
- default:
maxAgeDays: 90
keepMin: 3
```
Siivoussripti ajetaan CronJobina (esim. kerran päivässä):
1. Listaa kaikki bucketin objektit
2. Parsii polusta `repo_slug` ja `commit_short`
3. Hakee Gitea API:sta commitin metadata (branch, onko tagattu)
4. Soveltaa ConfigMapin retention-sääntöjä
5. Poistaa vanhentuneet objektit `mc rm`:llä
## Raporttien pushaus workflow'sta
`push-reports.sh`:
```bash
#!/bin/bash
# Käyttö: push-reports.sh <report_type> <source_dir>
# Esim: push-reports.sh cucumber target/cucumber-report/
REPORT_TYPE=$1
SOURCE_DIR=$2
TARGET="minio/reports/${GITHUB_REPOSITORY}/${GITHUB_SHA::8}/${REPORT_TYPE}/"
mc cp --recursive "$SOURCE_DIR" "$TARGET"
echo "${MINIO_BASE_URL}/${GITHUB_REPOSITORY}/${GITHUB_SHA::8}/${REPORT_TYPE}/index.html"
```
Skripti palauttaa URL:n, joka syötetään `report-status.sh`:lle commit-statusviestin `url`-kenttään.
## Konfiguraatio Giteassa
| Secret / Variable | Tyyppi | Sisältö |
|---|---|---|
| `MINIO_ACCESS_KEY` | Org secret | MinIO access key |
| `MINIO_SECRET_KEY` | Org secret | MinIO secret key |
| `MINIO_BASE_URL` | Org variable | `https://reports.smith.keskikuja.site` |
Workflow lukee nämä automaattisesti — projekti ei määrittele niitä `ci-flow-values.yaml`:ssa.
## MinIO-deployment (viitteellinen)
Minimalistinen Kubernetes-deployment samassa klusterissa:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: minio-reports
spec:
replicas: 1
template:
spec:
containers:
- name: minio
image: minio/minio:latest
args: ["server", "/data", "--console-address", ":9001"]
env:
- name: MINIO_ROOT_USER
valueFrom:
secretKeyRef:
name: minio-secrets
key: access-key
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: minio-secrets
key: secret-key
ports:
- containerPort: 9000 # S3 API
- containerPort: 9001 # Console UI
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: minio-reports-pvc
```
## Huomioitavaa
- **Bucketin luonti ja web-hostingin aktivointi** tehdään kerran deploymentin yhteydessä. Ei per build.
- **URL on deterministinen** — raportin URL voidaan generoida jo ennen kuin raportti on pushattu. Jos raporttihakemistoa ei ole (esim. testit skipattiin), linkki johtaa 404:ään.
- **Indeksitiedoston nimi** riippuu raporttityypistä: Cucumber → `overview-features.html`, JaCoCo → `index.html`, Maven Site → `index.html`. `push-reports.sh`:n vastuulla varmistaa, että indeksitiedosto löytyy.
+142
View File
@@ -0,0 +1,142 @@
# Vaatimukset — Gitea Actions CI -kirjasto
> Funktionaaliset vaatimukset käyttäjän näkökulmasta. Muoto: käyttötapaukset (use cases).
>
> Linkittyy: [design-rationale.md](design-rationale.md), [architecture.md](architecture.md), [report-hosting.md](report-hosting.md)
---
## UC1: Kehittäjä näkee commitin build-statuksen
**Actor:** Kehittäjä
**Precondition:** Workflow on käynnissä tai päättynyt
**Main success:**
- Kehittäjä avaa commitin Giteassa
- Näkee statusviestit: "Building...", "Unit tests OK", "Docker build OK", "Docker pushed"
- Jokainen statusviesti on klikattavissa → vie buildin sivuun tai raporttiin
- Epäonnistunut steppi näkyy punaisella — kehittäjä klikkaa ja näkee mikä meni vikaan
**Poikkeukset:**
- Statusviesti puuttuu (workflow kaatui ennen raportointia) → commitissa näkyy timeout/error
- Useampi workflow samalle commitille → statukset erottuvat `key`-arvolla
---
## UC2: Kehittäjä lukee testiraportteja selaimessa
**Actor:** Kehittäjä
**Precondition:** Build on valmistunut, raportit pushattu Minioon
**Main success:**
- Kehittäjä klikkaa commitin statusviestin URL:ää ("Unit tests OK" → URL)
- Selain avautuu, OIDC-kirjautuminen (Gitea-tunnuksilla)
- Cucumber-raportti renderöityy HTML:nä selaimessa
- Raportissa näkyy: mitkä testit menivät läpi, mitkä epäonnistuivat, stack tracet
- Yläreunassa linkki "← Back to build" → palaa buildin raportti-indeksiin
**Poikkeukset:**
- Raporttia ei ole (testit skipattiin, workflow kaatui ennen pushausta) → 404
- OIDC-sessio vanhentunut → uudelleenohjaus kirjautumiseen
---
## UC3: Kehittäjä selaa projektin build-historiaa
**Actor:** Kehittäjä
**Precondition:** Projektilla on vähintään yksi build
**Main success:**
- Kehittäjä menee `{MINIO_BASE}/{repo_slug}/index.html`
- Näkee listan kaikista buildeista aikajärjestyksessä (uusin ensin)
- Jokaisella buildilla: commitin 8-merkkinen hash, päivämäärä, branch, status (✅/❌)
- Klikkaa buildia → siirtyy `{commit_short}/index.html` — buildin raporttilistaukseen
- Buildin sivulla: lista kaikista raporteista (Cucumber, JaCoCo, Maven Site) linkkeinä
- "← Back to builds" → palaa projektin build-indeksiin
**Poikkeukset:**
- Projekti poistettu / siivottu retention policyn mukaan → 404
- Indeksitiedosto puuttuu (ensimmäinen build kesken) → 404, generoituu seuraavalla pushauksella
---
## UC4: Kehittäjä jäljittää kontin koko ketjun commitista
**Actor:** Kehittäjä
**Precondition:** Mikropalvelun commitista on ajettu vähintään deployment
**Main success:**
- Kehittäjä avaa mikropalvelun commitin abc123
- Näkee statusviestit: "Build OK", "Deployed to staging → def456", "Integration tests OK → ghi789"
- Klikkaa "Deployed to staging → def456" → siirtyy Helm-repon committiin def456
- Helm-repon commitissa näkyy: "from abc123", "tested v1.2.3", "tested abc123"
- Klikkaa "tested abc123" → palaa mikropalvelun committiin
- Koko ketju on navigoitavissa edestakaisin commit-statuslinkkien kautta
**Poikkeukset:**
- Välivaiheen commit siivottu → statusviesti jää, mutta linkki vie 404:ään
- Deploytty versio ei vastaa odotettua → statusviestissä näkyy ristiriita
---
## UC5: Kehittäjä näkee deployatun version ympäristössä
**Actor:** Kehittäjä
**Precondition:** Deployment on suoritettu, Helm-repon commit tehty
**Main success:**
- Kehittäjä avaa Helm-repon commitin def456
- Näkee: "container.version = 1.2.3", "Deployed by abc123"
- Tietää heti mikä konttiversio on missäkin ympäristössä
- Voi verrata mikropalvelun uusimpaan commitin — onko ympäristö ajan tasalla?
**Poikkeukset:**
- `doNotDowngrade` esti deploymentin → statusviesti "Skipped: newer version already deployed"
---
## UC6: Testi-insinööri näkee mitä konttia testattiin
**Actor:** Testi-insinööri
**Precondition:** Integraatio- tai e2e-testit on ajettu
**Main success:**
- Avaa testi-repon commitin ghi789
- Näkee: "Tested v1.2.3" (mikä kontti), "Tested abc123" (mikä mikropalvelun commit)
- Klikkaa testiraporttiin → näkee tulokset
- Näkee myös mitkä tagit olivat käytössä (`@smoke and not @slow`)
- Voi todentaa että testattiin oikeaa versiota
**Poikkeukset:**
- Version check epäonnistui (haluttu versio ei ollut ympäristössä) → status: "Version mismatch"
- Testit keskeytyivät timeoutiin → status: timeout, osittaiset tulokset raportissa
---
## UC7: Kehittäjä vertailee kahden buildin raportteja
**Actor:** Kehittäjä
**Precondition:** Projektilla on vähintään kaksi buildia
**Main success:**
- Kehittäjä avaa projektin build-indeksin `{MINIO_BASE}/{repo}/index.html`
- Näkee viimeisimmät buildit vierekkäin
- Avaa kaksi buildia eri välilehtiin
- Voi verrata Cucumber-tuloksia: "build #42 vs #41 — mikä testi meni rikki?"
**Poikkeukset:**
- Vanha build siivottu → ei näy indeksissä
---
## Ei-toiminnalliset vaatimukset
| Vaatimus | Toteutus |
|----------|----------|
| Raportit selailtavissa HTML:nä | MinIO static web hosting |
| Linkki commitista suoraan raporttiin | Statusviestin `url`-kenttä |
| Build-indeksi per projekti | Generoitu `index.html` Minioon |
| Navigaatio raporttien välillä | "Back to build" / "Back to builds" — linkit indeksisivuilla |
| Cross-repo-navigaatio | Statusviestit linkittävät repoja ristiin |
| Raporttien pysyvyys | ConfigMap-pohjainen retention policy |
| Autentikointi | OIDC (Traefik middleware, Gitea OAuth2) |
+190
View File
@@ -0,0 +1,190 @@
# Jaetut skriptit
> Kuuluu arkkitehtuuriin: [architecture.md](architecture.md). Tämä dokumentti määrittelee reusable workflow'sta kutsuttavien bash-skriptien rajapinnat, parametrit ja vastuut.
Skriptit asuvat `gitea-ci-library/scripts/`-hakemistossa. Workflowt lataavat ne checkout-stepin jälkeen.
---
## `report-status.sh`
POSTaa build-statuksen Gitea-commitin REST APIin.
### Rajapinta
```bash
report-status.sh <state> <description> <url> [key] [root_commit] [root_repo]
```
| Parametri | Pakollinen | Kuvaus |
|-----------|------------|--------|
| `state` | Kyllä | `pending`, `success`, `failure`, `error` |
| `description` | Kyllä | Ihmisluettava kuvaus (esim. "Unit tests passed") |
| `url` | Kyllä | Linkki buildiin tai raporttiin |
| `key` | Ei | Uniikki avain. Oletus: `commit-{sha_short}` |
| `root_commit` | Ei | Root-buildin commit-hash (cross-repo-raportointia varten) |
| `root_repo` | Ei | Root-buildin repo (cross-repo-raportointia varten) |
### Kutsuesimerkkejä
```bash
# Buildin aloitus
report-status.sh pending "Building..." "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
# Testivaihe valmis, linkki raporttiin
report-status.sh success "Unit tests OK" "$MINIO_BASE_URL/$GITHUB_REPOSITORY/${GITHUB_SHA::8}/cucumber/overview-features.html" "unit-test"
# Deployment valmis, cross-repo: raportoi takaisin mikropalvelun committiin
report-status.sh success "Deployed to staging" "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/commit/$GITHUB_SHA" "deploy-staging" "$ROOT_COMMIT" "$ROOT_REPO"
```
### Gitea API -kutsu
```bash
curl -X POST "$GITEA_API_URL/api/v1/repos/$REPO/statuses/$COMMIT" \
-H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"state\": \"$STATE\",
\"target_url\": \"$URL\",
\"description\": \"$DESCRIPTION\",
\"context\": \"$KEY\"
}"
```
Status-arvot mapataan Gitean skeemaan: `pending` (INPROGRESS), `success` (SUCCESS), `failure` (FAILURE), `error` (STOPPED).
---
## `dispatch-workflow.sh`
Dispatchaa workflow'n toisessa repossa ja pollaa sen valmistumista synkronisesti.
### Rajapinta
```bash
dispatch-workflow.sh <target_repo> <workflow_file> <ref> <inputs_json> [timeout_minutes]
```
| Parametri | Pakollinen | Kuvaus |
|-----------|------------|--------|
| `target_repo` | Kyllä | `owner/repo` |
| `workflow_file` | Kyllä | Workflow-tiedoston nimi (esim. `test.yml`) |
| `ref` | Kyllä | Branch |
| `inputs_json` | Kyllä | JSON-objekti input-parametreina |
| `timeout_minutes` | Ei | Oletus: 360 (6 tuntia) |
### Toiminta
1. **Dispatch:** `POST /api/v1/repos/{target_repo}/actions/workflows/{workflow_file}/dispatches`
2. **Etsi run:** `GET /api/v1/repos/{target_repo}/actions/runs?status=running` → etsi uusin (aikaleimasta)
3. **Poll:** `GET /api/v1/repos/{target_repo}/actions/runs/{run_id}` 10s välein
4. **Lopeta:** Kun `status == "completed"` → palauta `conclusion` (`success`/`failure`/`cancelled`)
5. **Timeout:** Jos kestää yli `timeout_minutes` → palauta `timeout`
### Kutsuesimerkki
```bash
dispatch-workflow.sh "tests/integration" "test.yml" "main" \
'{"version":"1.2.3","tags":"@smoke","root_commit":"abc123","root_repo":"services/temperature-store"}'
```
---
## `push-reports.sh`
Puskaa raporttihakemiston MinIO:hon ja päivittää indeksisivut.
### Rajapinta
```bash
push-reports.sh <report_type> <source_dir> [index_title]
```
| Parametri | Pakollinen | Kuvaus |
|-----------|------------|--------|
| `report_type` | Kyllä | Raportin tyyppi (`cucumber`, `jacoco`, `junit`, `site`) |
| `source_dir` | Kyllä | Paikallinen hakemisto, jossa raporttitiedostot |
| `index_title` | Ei | Näkyvä nimi indeksisivulla (esim. "Cucumber Reports") |
### Toiminta
1. Kopioi raportit: `mc cp --recursive {source_dir} minio/reports/{repo}/{commit_short}/{report_type}/`
2. Päivitä `/reports/{repo}/{commit_short}/index.html` — lisää linkki tähän raporttiin
3. Päivitä `/reports/{repo}/index.html` — varmista että tämä build on listalla
4. Palauta URL: `{MINIO_BASE_URL}/{repo}/{commit_short}/{report_type}/index.html`
### Indeksisivut
**Projektin build-indeksi** (`/reports/{repo}/index.html`):
- Lista buildeista aikajärjestyksessä (uusin ensin)
- Jokainen rivi: commit hash (linkki), päivämäärä, status (✅/❌), branch
**Buildin raportti-indeksi** (`/reports/{repo}/{commit_short}/index.html`):
- Lista raporteista linkkeinä
- Linkki "← Back to builds" → projektin build-indeksiin
Molemmat generoidaan uudestaan jokaisen pushauksen yhteydessä. Staattinen HTML, ei vaadi palvelinpuolen logiikkaa.
### Kutsuesimerkki
```bash
push-reports.sh cucumber target/cucumber-report "Cucumber Reports"
# → https://reports.example.com/temperature-store/abc12345/cucumber/overview-features.html
push-reports.sh jacoco target/jacoco-report "JaCoCo Coverage"
# → https://reports.example.com/temperature-store/abc12345/jacoco/index.html
```
---
## `tag-commit.sh`
Tagittaa commitin versiolla Gitea REST API:n kautta.
### Rajapinta
```bash
tag-commit.sh <version>
```
### Toiminta
```bash
curl -X POST "$GITEA_API_URL/api/v1/repos/$GITHUB_REPOSITORY/tags" \
-H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"tag_name\": \"$VERSION\",
\"message\": \"Build #$GITHUB_RUN_NUMBER\",
\"target\": \"$GITHUB_SHA\"
}"
```
### Kutsu
```bash
tag-commit.sh "1.2.3.$GITHUB_RUN_NUMBER"
```
Tagataan vain onnistuneen buildin ja pushin jälkeen. Tämän jälkeen `isContainerBuilt()` palauttaa `true` samalle commitille.
---
## Muuttujat, joita skriptit olettavat
Skriptit lukevat nämä Gitea Actionsin ympäristömuuttujat:
| Muuttuja | Lähde | Käyttäjä |
|----------|-------|----------|
| `GITEA_API_URL` | Org variable | Kaikki skriptit |
| `GITEA_TOKEN` | Org secret | `report-status.sh`, `dispatch-workflow.sh`, `tag-commit.sh` |
| `MINIO_BASE_URL` | Org variable | `push-reports.sh` |
| `MINIO_ACCESS_KEY` | Org secret | `push-reports.sh` |
| `MINIO_SECRET_KEY` | Org secret | `push-reports.sh` |
| `GITHUB_REPOSITORY` | Automaattinen | Kaikki skriptit |
| `GITHUB_SHA` | Automaattinen | Kaikki skriptit |
| `GITHUB_SERVER_URL` | Automaattinen | `report-status.sh` |
| `GITHUB_RUN_ID` | Automaattinen | `report-status.sh`, `tag-commit.sh` |
| `GITHUB_RUN_NUMBER` | Automaattinen | `tag-commit.sh` |
| `GITHUB_ACTOR` | Automaattinen | Docker-labelit |
+109
View File
@@ -0,0 +1,109 @@
# Tech Stack — Gitea Actions CI -kirjasto
> Absoluuttinen lähde sille, mitä teknologioita kirjasto käyttää ja tukee. Tämä dokumentti laaditaan `design-rationale.md`:n pohjalta. Mitään tässä listaamatonta teknologiaa ei oleteta olevan käytössä.
---
## Kirjaston oma runtime
Kirjasto itsessään on kokoelma **Gitea Actions reusable workflow** -tiedostoja (`.gitea/workflows/*.yml`). Ajonaikaiset stepit käyttävät:
| Teknologia | Versio / minimi | Käyttötarkoitus |
|---|---|---|
| **Gitea Actions** | 1.21+ | CI-alusta, workflow-moottori |
| **Gitea act runner** | 0.2+ | Workflow'n suoritus |
| **Bash** | 4.0+ | Integraatioskriptit workflow-stepeissä |
| **curl** | 7.0+ | Gitea REST API -kutsut (statusraportointi, dispatch, pollaus) |
| **jq** | 1.6+ | JSON-vastausten jäsennys REST API -kutsuista |
| **git** | 2.30+ | SCM-operaatiot (checkout, tag, push) |
| **MinIO client (mc)** | latest | Raporttien pushaus MinIO:hon ja URL-generointi |
---
## Konfiguraatio
| Teknologia | Käyttötarkoitus |
|---|---|
| **YAML** | Projektikohtainen konfiguraatio (`ci-flow-values.yaml`) |
| **Gitea organization secrets** | Tokenit ja salasanat (Gitea API -token, MinIO credentials) |
| **Gitea organization variables** | Infra-tason asetukset (MinIO base URL, SonarQube URL) |
---
## Tuetut ulkoiset palvelut
Kirjasto integroituu näihin ulkoisiin palveluihin workflow-stepeistä käsin. Palvelut eivät ole osa kirjastoa.
| Palvelu | Rajapinta | Käyttötarkoitus |
|---|---|---|
| **Gitea REST API** | `/api/v1/` | Commit-statusraportointi, workflow-dispatch, run-status-pollaus, taggaus |
| **MinIO** | S3 API + staattinen web-hosting | Testiraporttien tallennus ja selailu |
| **SonarQube** | REST API (`/api/`) | Quality gate -pollaus, dashboard-linkitys |
| **Gitea Packages** | Container registry API | Docker-imagen push ja taggaus |
---
## Tuetut build-ekosysteemit
Kirjasto tukee näitä käyttäjäprojektien build-työkaluja. Työkalut asennetaan workflow'n ajonaikaiseen konttiin (projektin itse määrittelemään).
| Ekosysteemi | Työkalut | Artifact-tyypit |
|---|---|---|
| **Java / Maven** | `mvn`, `java` | JAR, Docker |
| **Java / Gradle** | `gradle`, `java` | JAR, Docker |
| **Node.js / npm** | `npm`, `node` | npm-paketti, Docker |
| **Docker** | `docker`, `docker buildx` | Docker-image |
---
## Tuetut testikehykset
Kirjasto generoi ja julkaisee raportit näistä testikehyksistä. Itse testikehysten ajurit ovat käyttäjäprojektissa.
| Testikehys | Raporttiformaatti | MinIO-kohde |
|---|---|---|
| **Cucumber** | HTML (Cucumber Reports) | `/{commit_short}/cucumber/` |
| **JUnit** | XML | `/{commit_short}/junit/` |
| **JaCoCo** | HTML | `/{commit_short}/jacoco/` |
| **Maven Site** | HTML | `/{commit_short}/site/` |
| **Mukautettu HTML** | HTML | `/{commit_short}/{report_name}/` |
---
## Tuetut deployment-työkalut
| Työkalu | Käyttötarkoitus |
|---|---|
| **Helm v3** | Kubernetes-deployment (arvot `values-{environment}.yaml`) |
| **Kubernetes** | Ajonaikainen ympäristö (testiympäristöt, tuotanto) |
---
## Mitä EI tueta (verrattuna Jenkins-versioon)
Nämä olivat Jenkins-kirjastossa, mutta on tietoisesti jätetty pois Gitea Actions -versiosta:
| Teknologia | Syy |
|---|---|
| **GitLab REST API** | Ei multi-platform-tukea (periaate 6) |
| **BitBucket Server REST API** | Ei multi-platform-tukea |
| **BitBucket Cloud REST API** | Ei multi-platform-tukea |
| **Jenkins** (shared library, cucumber plugin, publishHTML, jacoco plugin, buildJob) | Ei Jenkins-riippuvuutta — Gitea Actions korvaa |
| **Artifactory** (Docker registry) | MVP:ssä ei. Factory/adapter-patternilla lisättävissä myöhemmin |
| **Nexus** (Docker registry) | MVP:ssä ei. Factory/adapter-patternilla lisättävissä myöhemmin |
| **Artifactory** (npm registry) | MVP:ssä ei. Factory/adapter-patternilla lisättävissä myöhemmin |
| **Groovy** | Jenkins-spesifi. Korvautuu Bashilla ja YAML:lla |
---
## Huomautus: Docker-rekisterit
MVP:ssä tuetaan vain **Gitea Packages** (Container registry). Arkkitehtuuriin suunnitellaan factory/adapter-pattern, jolla Artifactory ja Nexus voidaan lisätä myöhemmin ilman workflow-muutoksia. Rekisteri konfiguroidaan `ci-flow-values.yaml`:n `docker`-osiossa `type`-kentällä (vrt. Jenkins `ArtifactRepoType`-enum).
## Huomautus: SonarQube-integraatio
Jenkins-versio pollasi quality gatea: `GET /api/project_analyses/search` → etsi uusin analyysi → `GET /api/qualitygates/project_status?analysisId=X`. SonarQubessa on tätä parempi rajapinta. Tutkitaan arkkitehtuurivaiheessa.
## Huomautus: Docker-in-Docker
Gitea Actions tukee Docker-in-Dockeria natiivisti `services:`-määrittelyllä workflow-tiedostossa. Tämä vastaa Jenkinsin `podTemplate`-konttia `docker:19.03.1-dind` + `docker:19.03.1` sidecar-mallia. Projektin workflow määrittelee tarvittavat kontit itse — reusable workflow ei pakota tiettyä konttivalikoimaa.
+257
View File
@@ -0,0 +1,257 @@
# Reusable workflowt
> Kuuluu arkkitehtuuriin: [architecture.md](architecture.md). Tämä dokumentti määrittelee jokaisen reusable workflow'n elinkaaren ja rajapinnan.
---
## Yhteiset konventiot
Kaikki workflowt:
- Käyttävät `concurrency:`-ryhmää estämään saman branchin rinnakkaiset ajot (vastaa Jenkins `disableConcurrentBuilds()`)
- Lukevat konfiguraation `ci-flow-values.yaml`:sta
- Raportoivat jokaisen vaiheen Gitea-commitin statukseen `report-status.sh`:lla
- Käyttävät projektilta saatuja `with:`-parametreja konttien määrittelyyn (kirjasto ei pakota konttiversioita)
---
## `ci-feature.yml` — Feature-branch
**Trigger:** `push` mihin tahansa branchiin paitsi `master`
**Elinkaari:**
```
start → unit-test → code-coverage → html-reports → end
```
### Inputs
| Parametri | Pakollinen | Kuvaus |
|-----------|------------|--------|
| `config-file` | Kyllä | Polku `ci-flow-values.yaml`:aan (yleensä `ci-flow-values.yaml`) |
| `maven-image` | Ei | Maven-kontin image (esim. `maven:3.9-eclipse-temurin-21`) |
| `node-image` | Ei | Node-kontin image (jos npm-projekti) |
### Steppi-kaavio
```mermaid
%%{init: {'theme': 'base', 'flowchart': {'arrowheadScale': 2}}}%%
flowchart TD
START(["checkout + start
POST INPROGRESS"]) --> UNIT["unit-test
aja testit, generoi raportit"]
UNIT --> COV["code-coverage
jacoco / vastaava"]
COV --> HTML["publish-html
pushaa raportit MinIO:hon
generoi index.html"]
HTML --> END(["end
POST lopullinen status"])
FAIL("fail") -. "catch" .-> END
style START fill:#2563eb,color:#ffffff
style UNIT fill:#059669,color:#ffffff
style COV fill:#059669,color:#ffffff
style HTML fill:#7c3aed,color:#ffffff
style END fill:#2563eb,color:#ffffff
style FAIL fill:#dc2626,color:#ffffff
linkStyle default stroke:#9ca3af,stroke-width:3px
```
### Error handling
Workflow käyttää Gitea Actionsin natiivia `jobs.<id>.continue-on-error` ja `if: failure()` -ehtoja. Ei erillistä `fail(e)`-kutsua kuten Jenkinsissä. Epäonnistunut steppi asettaa statuksen `failure` ja jatkaa `end`-steppiin, joka raportoi lopullisen statuksen.
---
## `ci-master.yml` — Master / release-branch
**Trigger:** `push` `master`-branchiin tai `workflow_dispatch`
**Elinkaari:**
```
start → isContainerBuilt? ──kyllä──→ continueToTestFlow
ei
unit-test → quality-gate → build-jar → build-docker → push-docker → tag-commit → continueToTestFlow → end
```
### Inputs
| Parametri | Pakollinen | Kuvaus |
|-----------|------------|--------|
| `config-file` | Kyllä | Polku `ci-flow-values.yaml`:aan |
| `maven-image` | Ei | Maven-kontti |
| `docker-image` | Ei | Docker-in-Docker -image (esim. `docker:26-dind`) |
### isContainerBuilt-check
```yaml
- name: Check if container already built
run: |
TAG=$(git tag --points-at HEAD | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -1)
if [ -n "$TAG" ]; then
echo "container_already_built=true" >> $GITHUB_ENV
echo "container_version=$TAG" >> $GITHUB_ENV
fi
```
Jos `container_already_built == true`, build- ja push-steppit skipataan. Siirrytään suoraan `continueToTestFlow`:hun.
### Steppi-kaavio
```mermaid
%%{init: {'theme': 'base', 'flowchart': {'arrowheadScale': 2}}}%%
flowchart TD
START(["start"]) --> CHECK{"isContainerBuilt?
git tag --points-at HEAD"}
CHECK -- "ei" --> UNIT["unit-test"]
UNIT --> SONAR["quality-gate
SonarQube"]
SONAR --> JAR["build-jar
ArtifactType.JAR"]
JAR --> DOCKER["build-docker
ArtifactType.DOCKER
+ Docker-labelit"]
DOCKER --> PUSH["push-docker
ArtifactType.DOCKER"]
PUSH --> TAG["tag-commit
tagittaa commitin
versiolla"]
CHECK -- "kyllä" --> CTF["continueToTestFlow"]
TAG --> CTF
CTF --> HTML["publish-html
pushaa Maven Site
MinIO:hon"]
HTML --> END(["end
lopullinen status"])
FAIL("fail") -. "catch" .-> END
style START fill:#2563eb,color:#ffffff
style CHECK fill:#f59e0b,color:#111827
style UNIT fill:#059669,color:#ffffff
style SONAR fill:#7c3aed,color:#ffffff
style JAR fill:#0891b2,color:#ffffff
style DOCKER fill:#0891b2,color:#ffffff
style PUSH fill:#dc2626,color:#ffffff
style TAG fill:#f59e0b,color:#111827
style CTF fill:#f59e0b,color:#111827
style HTML fill:#7c3aed,color:#ffffff
style END fill:#2563eb,color:#ffffff
style FAIL fill:#dc2626,color:#ffffff
linkStyle default stroke:#9ca3af,stroke-width:3px
```
### Concurrency
```yaml
concurrency:
group: master-${{ github.repository }}
cancel-in-progress: false
```
Vain yksi master-build kerrallaan per repo. Ei cancel-in-progress — käynnissä olevan buildin annetaan valmistua.
---
## `deploy.yml` — GitOps-deployment
**Trigger:** `workflow_dispatch` (aina dispatchataan toisesta workflow'sta)
**Elinkaari:**
```
start → read-yaml → update-value → commit → push → report-cross-repo → end
```
### Inputs (dispatch-parametrit)
| Parametri | Kuvaus |
|-----------|--------|
| `environment` | Ympäristön nimi (korvaa `{.environment}`) |
| `version` | Uusi konttiversio |
| `root_commit` | Mikropalvelun commit josta deploy käynnistyi |
| `root_repo` | Mikropalvelun repo |
| `root_build_url` | URL mikropalvelun buildiin |
### Mitä deploy tekee
1. Lukee `{projectFolder}/{fileName}` YAML-tiedoston (korvaa `{.environment}``environment`)
2. Päivittää `{property}`-avaimen arvoksi `{version}`
3. `git add`, `git commit -m "deploy {version} to {environment}"`
4. `git push origin HEAD:master`
5. Raportoi statuksen:
- Helm-repon committiin: **"from {root_commit}"**, URL → root-build
- Mikropalvelun committiin (`root_commit`): **"deployed to {environment}"**, URL → Helm-commit
6. Palauttaa Helm-commitin hashin (`outputs.commit`)
### Concurrency
```yaml
concurrency:
group: deploy-${{ github.repository }}-${{ inputs.environment }}
cancel-in-progress: false
```
---
## `test.yml` — Test flow -steppi
**Trigger:** `workflow_dispatch` (dispatchataan deploy-workflow'n jälkeen)
**Elinkaari:**
```
start → version-check → run-tests → push-reports → report-cross-repo → end
```
### Inputs (dispatch-parametrit)
| Parametri | Kuvaus |
|-----------|--------|
| `environment` | Testiympäristö |
| `version` | Testattava konttiversio |
| `tags` | Cucumber-tagit |
| `versionApiUrl` | URL version tarkistukseen |
| `versionCheckScript` | Polku version check -skriptiin |
| `root_commit` | Mikropalvelun commit |
| `root_repo` | Mikropalvelun repo |
| `deploy_commit` | Helm-repon commit (deployattu versio) |
| `deploy_repo` | Helm-repo |
### Version check
Ennen testejä varmistetaan, että ympäristössä pyörii oikea versio:
```yaml
- name: Check deployed version
if: inputs.versionCheckScript || inputs.versionApiUrl
run: |
if [ -n "${{ inputs.versionCheckScript }}" ]; then
bash "${{ inputs.versionCheckScript }}" "${{ inputs.versionApiUrl }}" "${{ inputs.version }}"
fi
```
Version check -skripti pollaa Fibonacci-backoffilla — ks. [config-model.md](config-model.md).
### Cross-repo-raportointi
Testien jälkeen raportoidaan kolmeen committiin:
1. Testi-repon oma commit: testin status
2. Mikropalvelun commit (`root_commit`): "testit OK/epäonnistui"
3. Helm-repon commit (`deploy_commit`): "testattu v{version}"
### Concurrency
```yaml
concurrency:
group: test-${{ inputs.environment }}
cancel-in-progress: false
```