155 lines
10 KiB
Markdown
155 lines
10 KiB
Markdown
# 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 |
|