# 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:** ```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. --- ## 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 |