504462b21e
CI Feature / Load example-gitea-env.conf to pipeline env (push) Successful in 27s
unit-tests Link to Bats reports
CI Feature / Bats tests (push) Successful in 1m40s
acc-tests Link to Cucumber reports
CI Feature / Cucumber tests (push) Successful in 1m7s
CI Feature / Report Summary (push) Successful in 5s
228 lines
10 KiB
Markdown
228 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
|
|
|
|
Mikropalveluarkkitehtuurissa jokainen palvelu tarvitsee CI-putken: testit,
|
|
laatutarkistukset, buildin, kontituksen ja julkaisun. Ilman jaettua
|
|
kirjastoa jokainen tiimi kopioi saman YAML-boilerplaten, tekee omat
|
|
virheensä ja ylläpitää omaa versiotaan. Ajan myötä putket ajautuvat erilleen
|
|
— toisessa on `shell: bash`, toisessa ei; toinen käyttää `set -o pipefail`,
|
|
toinen kadottaa exit-koodin `tee`:hen.
|
|
|
|
Tämä kirjasto on se mitä kopioidaan. Se tarjoaa valmiit, testatut,
|
|
dokumentoidut rakennuspalikat joista jokainen tiimi kokoaa oman putkensa.
|
|
Palikat ovat Gitea Actionsin `uses:`-direktiivillä kutsuttavia reusable
|
|
workflow'ta — ei asennusta, ei runtime-riippuvuutta, ei versiopäivityksiä
|
|
projekteihin.
|
|
|
|
---
|
|
|
|
## Suunnitteluperiaatteet
|
|
|
|
### 1. Palikka-arkkitehtuuri: pieniä, vaihdettavia, yhden vastuun workflow'ta
|
|
|
|
Jokainen provider-workflow tekee yhden asian:
|
|
|
|
| Workflow | Vastuu |
|
|
|---|---|
|
|
| `config-provider.yml` | Lataa ja validoi konfiguraatio |
|
|
| `check-version.yml` | Tarkistaa onko commit buildattu, laskee version |
|
|
| `docker-build-push.yml` | Buildaa, puskea ja tagittaa kontin |
|
|
|
|
Mikään workflow ei kutsu toista provider-workflowta. Consumer
|
|
— siis mikropalvelun oma pipeline-tiedosto — on ainoa paikka joka
|
|
tietää mitä palikoita tarvitaan ja missä järjestyksessä.
|
|
|
|
**Miksi:** Tämä on sama periaate kuin Unix-putkissa tai mikropalveluissa:
|
|
pieniä, itsenäisiä komponentteja jotka tekevät yhden asian hyvin.
|
|
Consumer voi vaihtaa yhden palikan toiseen — esimerkiksi Docker-buildin
|
|
tilalle Maven-paketoinnin — ilman että muut palikat muuttuvat.
|
|
Ratkaisu ei ole se että kaikki ajetaan, vaan se että jokainen tiimi
|
|
valitsee mitä tarvitsee. Monoliittinen "kaikki yhdessä" -workflow
|
|
pakottaisi jokaisen tiimin ajamaan tarpeettomia vaiheita.
|
|
|
|
### 2. Gitea ensin — hyödynnä alustaa, älä taistele sitä vastaan
|
|
|
|
Gitea Actions tarjoaa kolme asiaa ilmaiseksi:
|
|
|
|
1. **Jobien visuaalinen status** — jokainen jobi näkyy automaattisesti
|
|
commit-näkymässä checkmarkilla, spinnerillä tai ristillä.
|
|
2. **Cross-job riippuvuudet** — `needs` hoitaa virheiden propagointin:
|
|
jos edeltävä jobi feilaa, riippuvat jobit skipataan.
|
|
3. **Reusable workflow -jakelu** — `uses: org/repo/.gitea/workflows/file.yml@v1`
|
|
on natiivisti versioitu, skopattu ja välimuistitettu.
|
|
|
|
Kirjasto käyttää näitä kaikkia. Ei omaa tilakonetta, ei custom
|
|
action -runtimea, ei ulkoista orkestraattoria.
|
|
|
|
**Esimerkki:** Tool-jobit eivät kutsu commit-status API:a lainkaan.
|
|
Gitean oma job-status riittää — `success`/`failure`/`running` näkyy
|
|
automaattisesti. API:a käytetään vain kun tarvitaan **custom-linkki**
|
|
(testiraporttiin tai Docker registryyn), jota natiivistaatus ei tarjoa.
|
|
Tämä linjaus on dokumentoitu ADR 0004 ja 0007:ssä.
|
|
|
|
### 3. Status näkyy siellä missä työ tehdään — Git-commitissa
|
|
|
|
Kehittäjä työskentelee Gitissä. `git log`, `git blame`, PR-näkymä —
|
|
nämä ovat päivittäiset työkalut. CI-statuksen kuuluu näkyä siellä,
|
|
ei erillisessä dashboardissa.
|
|
|
|
Gitea Actionsin natiivi job-status tekee tämän automaattisesti:
|
|
jokainen commit näyttää välittömästi mitkä jobit on ajettu ja millä
|
|
tuloksella. Testiraportteihin pääsee yhdellä klikkauksella commitin
|
|
status-kuvakkeesta — koska `report-status.sh` asettaa `target_url`:n
|
|
osoittamaan suoraan HTML-raporttiin git-pagesissa.
|
|
|
|
Tämä ei ole kosmeettinen yksityiskohta. Se on devops-käytännön
|
|
ydin: palautesilmukka on lyhin mahdollinen. Commit → build → status
|
|
näkyy samassa näkymässä jossa kehittäjä jo on.
|
|
|
|
### 4. Exit-koodi on ainoa totuus
|
|
|
|
CI-putken jokaisen `run`-stepin onnistuminen määräytyy **vain ja
|
|
ainoastaan** exit-koodin perusteella. Ei tiedoston olemassaolon, ei
|
|
stdout-tulosteen, ei arvauksen. `0` = ok, kaikki muu = ei ok.
|
|
|
|
Tämä kuulostaa itsestään selvältä, mutta YAML-pipelineissa se rikkoutuu
|
|
helposti. Pipe (`|`) `tee`:hen syö exit-koodin. Tiedoston olemassaolon
|
|
tarkistus (`[ -f results.xml ]`) ei kerro testien läpimenosta.
|
|
|
|
**Käytännössä:** Jokainen `run`-steppi ottaa exit-koodin talteen
|
|
`$?`-muuttujaan ennen kuin mikään muu komento ehtii muuttaa sitä,
|
|
ja stepin viimeinen rivi on `exit ${EXIT}`. Pipeä ei käytetä
|
|
työvaiheen viimeisenä komentona. Ks. ADR 0008.
|
|
|
|
### 5. Pienin mahdollinen pinta-ala
|
|
|
|
Jokainen ylimääräinen riippuvuus on ylimääräinen vikaantumispiste.
|
|
Kirjaston ainoat riippuvuudet:
|
|
|
|
- Gitea Actions (alusta)
|
|
- `bash`, `curl`, `jq` (ubuntu-latest runnerissa valmiina)
|
|
- Docker (runnerissa valmiina)
|
|
- git-pages (raporttien hostaus, erillinen palvelu)
|
|
|
|
Ei Pythonia, ei Node.js:ää ajonaikaisesti (testit omissa konteissaan).
|
|
Ei tietokantaa. Ei ulkoista tilanhallintaa. Kirjasto on joukko
|
|
YAML-tiedostoja ja shell-skriptejä — samat työkalut jotka jokainen
|
|
devops-ihminen jo osaa.
|
|
|
|
### 6. Konfiguraatio repoon, salaisuudet Giteaan
|
|
|
|
Projektikohtainen konfiguraatio (`.gitea/workflows/gitea-env.conf`)
|
|
asuu mikropalvelun omassa repossa. Kehittäjä omistaa sen — hän tietää
|
|
mikä on Docker-imagen nimi, mihin registryyn puskea, mikä on
|
|
testiympäristön URL.
|
|
|
|
Salaisuudet (tokenit, salasanat) elävät Gitean secrets-mekanismissa,
|
|
eivät repon tiedostoissa. `secrets: inherit` välittää ne providerin
|
|
workflow'hun ilman että consumerin tarvitsee tietää mitä salaisuuksia
|
|
mikäkin provider tarvitsee.
|
|
|
|
Poikkeus: infra-tason asetukset (`GIT_PAGES_URL`, `GITEA_API_URL`)
|
|
ovat Gitean organization secrets/variables -mekanismissa. Ne eivät
|
|
ole repokohtaisia.
|
|
|
|
### 7. Consumer omistaa orkestroinnin, provider tarjoaa palikat
|
|
|
|
Tämä on kirjaston tärkein arkkitehtuurinen päätös (ADR 0005).
|
|
|
|
Provider (`gitea-ci-library`) ei tiedä mitä testejä ajetaan, missä
|
|
järjestyksessä, tai millä branchilla. Se tarjoaa kolme reusable
|
|
workflow'ta ja joukon skriptejä.
|
|
|
|
Consumer (mikropalvelun `example-feature.yml` / `example-main.yml`)
|
|
päättää:
|
|
- Mitkä palikat kutsutaan
|
|
- Missä järjestyksessä (`needs`)
|
|
- Millä branch-ehdoilla (`if`)
|
|
- Mitkä testikontit käytetään (input-parametrit)
|
|
|
|
Tämä on tarkoituksellinen vallanjako. Provider ei voi tietää jokaisen
|
|
tiimin tarpeita — eikä sen pidäkään. Consumer ei voi muuttaa providerin
|
|
sisäistä toteutusta — eikä sen pidäkään. Rajapinta on `workflow_call` ja
|
|
se on molemmille osapuolille selvä.
|
|
|
|
### 8. Branch-kohtainen reititys, ei yhtä kaikille
|
|
|
|
Eri brancheilla on eri tavoite:
|
|
|
|
- **Feature-haara:** Onko koodi laadukasta? → testit, validointi
|
|
- **Main-haara:** Onko tästä versiosta jo artifakti? Jos ei →
|
|
testit + build + push + tag. Jos on → ei tehdä mitään (tai
|
|
jatketaan klusteritesteihin).
|
|
|
|
Tämä logiikka elää consumerin pipeline-tiedostossa, ei providerissa.
|
|
Se on puhdasta `if`-ehtoa ja `needs`-ketjutusta — ei skriptausta,
|
|
ei monimutkaisia ehtoja providerin sisällä.
|
|
|
|
### 9. Raportit erillisellä palvelulla, linkit commitissa
|
|
|
|
Gitea Actionsin artifact-järjestelmä on binääriarkisto — ZIP-lataus,
|
|
ei HTML-selailtavuutta. Testiraportit (Cucumber HTML, Bats-coverage)
|
|
on voitava avata selaimessa yhdellä klikkauksella.
|
|
|
|
Ratkaisu: git-pages Helm-chartti, joka tarjoaa staattista
|
|
tiedostohostingia HTTP:llä. `publish-git-pages.sh` vie raportit
|
|
sinne; `report-status.sh` linkittää commit-statuksen suoraan
|
|
raporttiin. Retention hoitaa git-pagesin sidecar automaattisesti.
|
|
|
|
Tulevaisuudessa `GITHUB_STEP_SUMMARY` (Gitea 1.27+) tarjoaa
|
|
vaihtoehtoisen kanavan: jobin Summary-välilehdelle renderöityvä
|
|
Markdown-taulukko kaikista raporttilinkeistä.
|
|
|
|
### 10. Vain Gitea — ei monialustatukea ilman tarvetta
|
|
|
|
Yhden alustan tukeminen kunnolla on vaikeampaa kuin kolmen tukeminen
|
|
huonosti. Gitea Actionsin `uses:`-mekanismi, `needs`-semantiikka,
|
|
`secrets: inherit`, `gitea`-konteksti — nämä ovat alustakohtaisia
|
|
ominaisuuksia joita abstraktiokerros vain haittaisi.
|
|
|
|
Jos toinen alusta tulee ajankohtaiseksi, sille kirjoitetaan oma
|
|
toteutus. Siihen asti yksi alusta riittää. Ennenaikainen yleistys
|
|
on devopsissa yhtä haitallista kuin ohjelmistosuunnittelussa.
|
|
|
|
---
|
|
|
|
## Arkkitehtuuriset rajoitteet
|
|
|
|
### Mitä kirjasto EI tee
|
|
|
|
- **Ei ulkoista orkestraattoria.** Pipeline-ohjaus on Gitea Actionsin
|
|
`needs`-ketjuissa ja consumerin `if`-ehdoissa.
|
|
- **Ei custom actioneita.** Reusable workflow on kevyempi, versioitu
|
|
ja jaeltu Gitean oman mekanismin kautta.
|
|
- **Ei asennusta projekteihin.** Consumer viittaa `uses:`-direktiivillä
|
|
suoraan tämän repon workflow-tiedostoihin. Ei npm-pakettia, ei
|
|
git-submodulea, ei kopioitavia tiedostoja.
|
|
- **Ei runtime-riippuvuuksia.** Provider-skriptit käyttävät vain
|
|
työkaluja jotka ovat Gitea Actionsin `ubuntu-latest` runnerissa
|
|
valmiina: `bash`, `curl`, `jq`.
|
|
- **Ei monorepo-konfiguraatiota.** Jokainen mikropalvelu omistaa
|
|
oman pipeline-tiedostonsa ja konfiguraationsa.
|
|
|
|
---
|
|
|
|
## Mitä tietoisesti hylättiin
|
|
|
|
| Hylätty | Syy |
|
|
|---|---|
|
|
| Monoliittinen "kaikki yhdessä" -workflow | Pakottaa kaikille samat vaiheet. Palikka-arkkitehtuuri antaa jokaiselle tiimille vain mitä se tarvitsee |
|
|
| Oma orkestraattoripalvelin | Ylimääräinen ylläpidettävä. Gitean `needs` ja `if` riittävät |
|
|
| Docker-pohjaiset custom actionit | Tuovat riippuvuuden Docker-rekisteriin. Reusable workflow on natiivimpi |
|
|
| Commit-status API jokaiselle vaiheelle | Duplikointia — Gitea näyttää job-statuksen automaattisesti. API vain custom-linkeille |
|
|
| `tee`-putki debug-näkyvyyteen | Syö exit-koodin. stdout ohjataan tiedostoon `>` ilman pipeä |
|
|
| Multi-Git-platform-tuki | Ennenaikaista optimointia ilman tarvetta |
|
|
| Gitea Packages raporttien hostingiin | Ei HTML-selailtavuutta — vain binäärilataus |
|
|
| Gitea Pages + reports-branch | Race condition rinnakkaisten pushien kanssa |
|
|
| `repository_dispatch` ketjutukseen | Lisää konfiguraatiota vastaanottaviin repoihin. Suora API-kutsu eksplisiittisempi |
|