consumer project käyttöönotossa tulleitea muutoksia
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

This commit is contained in:
moilanik
2026-06-16 04:31:05 +03:00
parent f7b2353eb9
commit 504462b21e
10 changed files with 830 additions and 627 deletions
+160 -107
View File
@@ -1,150 +1,195 @@
# Design Rationale — Gitea Actions CI -kirjasto
> Miksi kirjasto on rakennettu näin. Arvot, periaatteet ja reunaehdot, joiden varaan arkkitehtuuri nojaa.
> 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.
> 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.
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.
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.
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. Hyödynnä natiivia
### 1. Palikka-arkkitehtuuri: pieniä, vaihdettavia, yhden vastuun workflow'ta
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.
Jokainen provider-workflow tekee yhden asian:
**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.
| 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 |
**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
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ä.
### 2. Git-commit on universaali statusnäkymä
**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.
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.
### 2. Gitea ensin — hyödynnä alustaa, älä taistele sitä vastaan
**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.
Gitea Actions tarjoaa kolme asiaa ilmaiseksi:
**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.
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.
### 3. Reusable workflow — ei omaa runtimea
Kirjasto käyttää näitä kaikkia. Ei omaa tilakonetta, ei custom
action -runtimea, ei ulkoista orkestraattoria.
Kirjasto jaetaan Gitea Actionsin reusable workflow -mekanismilla. Ei Docker-pohjaisia custom actioneita, ei erillistä ajonaikaista palvelinta.
**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ä.
**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.
### 3. Status näkyy siellä missä työ tehdään — Git-commitissa
**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ä.
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.
### 4. Konfiguraatio kuuluu repoon
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.
Projektikohtainen konfiguraatio (`ci-flow-values.yaml`-tyyppinen tiedosto) asuu mikropalvelun omassa repossa. Reusable workflow lukee sen, ei toisinpäin.
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.
**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.
### 4. Exit-koodi on ainoa totuus
**Poikkeus:** Infra-tason asetukset (git-pages host, Gitea-instanssin URL)
ovat organisaatiotasolla Gitean organization secrets/variables
-mekanismissa. Ne eivät ole repokohtaisia.
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.
### 5. Deterministinen testigraafi, vaiheittainen suoritus
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.
Test flow on tunnettu ennen buildin alkua, ja testit ajetaan yksi kerrallaan. Jos steppi epäonnistuu, koko flow pysähtyy.
**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.
**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.
### 5. Pienin mahdollinen pinta-ala
**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.
Jokainen ylimääräinen riippuvuus on ylimääräinen vikaantumispiste.
Kirjaston ainoat riippuvuudet:
### 6. Raporttien hallinta erillisellä palvelulla
- Gitea Actions (alusta)
- `bash`, `curl`, `jq` (ubuntu-latest runnerissa valmiina)
- Docker (runnerissa valmiina)
- git-pages (raporttien hostaus, erillinen palvelu)
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.
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.
**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.
### 6. Konfiguraatio repoon, salaisuudet Giteaan
### 7. Yksi CI-alusta, yksi integraatiopiste
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.
Kirjasto tukee vain Giteaa. Ei GitLab-, BitBucket- tai GitHub-abstraktioita.
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.
**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.
Poikkeus: infra-tason asetukset (`GIT_PAGES_URL`, `GITEA_API_URL`)
ovat Gitean organization secrets/variables -mekanismissa. Ne eivät
ole repokohtaisia.
**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. Consumer omistaa orkestroinnin, provider tarjoaa palikat
### 8. Cross-repo commit traceability
Tämä on kirjaston tärkein arkkitehtuurinen päätös (ADR 0005).
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.
Provider (`gitea-ci-library`) ei tiedä mitä testejä ajetaan, missä
järjestyksessä, tai millä branchilla. Se tarjoaa kolme reusable
workflow'ta ja joukon skriptejä.
**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**.
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)
**Mekanismi:**
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ä.
```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
### 8. Branch-kohtainen reititys, ei yhtä kaikille
Note over MR: commit abc123
Note over MR: build kontti v1.2.3
Eri brancheilla on eri tavoite:
MR->>GA: POST dispatch deploy-workflow
GA->>HR: workflow käyntiin
Note over HR: commit def456
Note over HR: container.version = 1.2.3
- **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).
HR->>GA: POST status "deployed by abc123"
GA->>MR: Status: deployed to staging
Note right of MR: URL → def456
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ä.
HR->>GA: POST status "from abc123"
GA->>HR: Status: from abc123
Note right of HR: URL → abc123
### 9. Raportit erillisellä palvelulla, linkit commitissa
MR->>GA: POST dispatch integraatiotestit
GA->>TR: workflow käyntiin
Note over TR: commit ghi789
Gitea Actionsin artifact-järjestelmä on binääriarkisto — ZIP-lataus,
ei HTML-selailtavuutta. Testiraportit (Cucumber HTML, Bats-coverage)
on voitava avata selaimessa yhdellä klikkauksella.
TR->>GA: POST status "integration OK"
GA->>MR: Status: integration OK
Note right of MR: URL → ghi789
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.
TR->>GA: POST status "tested v1.2.3"
GA->>HR: Status: tested v1.2.3
Note right of HR: URL → def456
Tulevaisuudessa `GITHUB_STEP_SUMMARY` (Gitea 1.27+) tarjoaa
vaihtoehtoisen kanavan: jobin Summary-välilehdelle renderöityvä
Markdown-taulukko kaikista raporttilinkeistä.
TR->>GA: POST status "tested abc123"
GA->>MR: Status: tested abc123 (root)
Note right of MR: URL → abc123
```
### 10. Vain Gitea — ei monialustatukea ilman tarvetta
**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.
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.
---
@@ -152,23 +197,31 @@ sequenceDiagram
### 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.
- **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
## 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 |
|---|---|
| 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 |