10 KiB
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. Gitea Actionsin ja Gitean natiiveja ominaisuuksia hyödynnetään aina kun mahdollista — uutta kilpailevaa toteutusta ei kirjoiteta, jos toimiva ratkaisu on jo olemassa.
Suunnitteluperiaatteet
1. Hyödynnä natiivia
Gitea Actionsin ja Gitean natiiveja ominaisuuksia käytetään aina kun ne riittävät. Uutta kilpailevaa toteutusta ei kirjoiteta, jos toimiva ratkaisu on jo olemassa.
Miksi: Oma toteutus on aina ylläpidettävä, testattava ja dokumentoitava. Natiivi ominaisuus tulee ilmaiseksi, kehittyy alustan mukana ja on käyttäjälle tuttu.
Esimerkkejä:
- Gitea Actions näyttää jobien statuksen automaattisesti — omaa commit-status API -kutsua ei tarvita jokaiselle vaiheelle
- Gitea organization secrets/variables korvaa erillisen credential-hallinnan
- Reusable workflow -mekanismi korvaa custom action -runtimen
2. 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ä: Gitea Actions näyttää jobien tilan
(checkmark/risti/spinner) commit-näkymässä automaattisesti. API:a
(/api/v1/repos/{owner}/{repo}/statuses/{sha}) käytetään vain
custom-raporttilinkin välittämiseen. ADR 0004.
3. 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ä.
4. 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 (git-pages host, Gitea-instanssin URL) ovat organisaatiotasolla Gitean organization secrets/variables -mekanismissa. Ne eivät ole repokohtaisia.
5. 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.
6. Raporttien hallinta erillisellä palvelulla
Raporttien selailtavuudesta ja elinkaaresta vastaa erillinen palvelu, joka asennetaan git-pages Helm-chartilla. Raportit ovat julkisia URL:lla (osoite tunnettava). URL linkitetään Git-committiin.
Miksi: Jenkins-versiossa linkki Cucumber-raporttiin oli kriittinen feature. Gitea Actionsin artifact-järjestelmä ei tue HTML-selailtavuutta (vain ZIP-lataus). Erillinen palvelu mahdollistaa hallitun retention ja pääsyn ilman CI-alustan rajoitteita.
7. 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.
8. 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:
%%{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.
Mitä tietoisesti hylättiin
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 |