# Konfiguraatiomalli — `ci-flow-values.yaml` > ⚠️ **POC-vaihe.** Tämä dokumentti on peritty Jenkins-versiosta ja sisältää > Docker-spesifistä legacyä (isContainerBuild, Docker-labelit). POC osoitti, > että provider on agnostinen consumerin build-ekosysteemille. > > Uusi ajattelu: `isContainerBuild()` → `isArtifactBuild()`. Provider ei > tiedä eikä tarvitse tietää, buildaako consumer kontin, JARin, npm-paketin > vai mitään muuta. Dokumentti odottaa uudelleenkirjoitusta. > > Normatiivinen lähde: `docs/design-rationale.md`, ADR 0005. --- ## Miksi redesign Jenkins-version `ci-flow-values.yaml` oli rakennettu Jenkinsin ympäristömuuttuja- ja credential-mallin ympärille. Gitea Actionsissa konfiguraatio luetaan suoraan YAML:sta workflow'n sisällä — ei tarvita env-muuttujien kautta kierrättämistä. Lisäksi: - `creditentials`-viittaukset korvautuvat Gitea org secrets/variables -mekanismilla - `test-flow`-syntaksi yksinkertaistuu (ei enää JSON-serialisointia env-muuttujiin) - Docker/NPM-rekisterit MVP:ssä vain Gitea Packages — factory/adapter-pattern valmiina laajennukselle - `sonarqube`-konfiguraatio pysyy samankaltaisena --- ## Skeema ```yaml # ci-flow-values.yaml — projektin juuressa # # Pakolliset osiot: docker (jos master-branch buildaa kontin), test-flow (jos ketjutetaan) # Vapaaehtoiset: sonarqube, deployment docker: registry: gitea # gitea | artifactory | nexus (MVP: vain gitea) imageName: temperature-store # kontin nimi, pakollinen sonarqube: url: https://sonar.example.com projectKey: temperature-store deployment: jobName: deploy # deploy-workflown nimi (vakio) projectFolder: microservices # polku Helm-repossa fileName: values-{.environment}.yaml property: container.version test-flow: - deploy: development # 1. deploy development-ympäristöön wait: true # odota deployn valmistumista - test: name: "integration fast" environment: integration repo: tests/integration # testi-repo (owner/repo) workflow: test.yml # workflow-tiedosto testi-repossa ref: main # branch tags: "@temperature and not @slow" - deploy: staging wait: true - test: name: e2e environment: staging repo: tests/e2e workflow: test.yml ref: main tags: "@e2e and not @slow" ``` ### Kenttäkuvaukset #### `docker` | Kenttä | Pakollinen | Kuvaus | |--------|------------|--------| | `registry` | Ei (oletus `gitea`) | Rekisterityyppi. MVP: `gitea`. Factory/adapter-pattern avaa `artifactory`, `nexus` myöhemmin | | `imageName` | Kyllä | Kontin nimi. Lopullinen tagi: `{gitea_host}/{owner}/{imageName}:{version}.{run_number}` | #### `sonarqube` | Kenttä | Pakollinen | Kuvaus | |--------|------------|--------| | `url` | Kyllä | SonarQube-palvelimen URL | | `projectKey` | Kyllä | SonarQube-projektin avain | SonarQube-token tulee Gitea org secretsista (`SONAR_TOKEN`). Ei `creditentials`-viittausta. #### `deployment` | Kenttä | Pakollinen | Kuvaus | |--------|------------|--------| | `jobName` | Ei (oletus `deploy`) | Deploy-workflown tiedostonimi ilman `.yml`-päätettä | | `projectFolder` | Kyllä | Polku mikropalvelun kansioon Helm-repossa | | `fileName` | Kyllä | YAML-tiedoston nimi. `{.environment}` korvataan ympäristön nimellä | | `property` | Kyllä | Päivitettävä avain (piste-eroteltu polku, esim. `container.version`) | Deploy-token (kirjoitusoikeus Helm-repoon) tulee Gitea org secretsista (`DEPLOY_TOKEN`). #### `test-flow` Array testi-steppejä. Jokainen steppi on joko `deploy` tai `test`. **`deploy`-steppi:** | Kenttä | Pakollinen | Kuvaus | |--------|------------|--------| | `deploy` | Kyllä | Ympäristön nimi (esim. `development`, `staging`) | | `wait` | Ei (oletus `true`) | Odotetaanko deployn valmistumista ennen seuraavaa steppiä | **`test`-steppi:** | Kenttä | Pakollinen | Kuvaus | |--------|------------|--------| | `name` | Kyllä | Testivaiheen nimi (näkyy statusviestissä) | | `environment` | Kyllä | Ympäristö jota vasten testataan | | `repo` | Kyllä | Testi-repo muodossa `owner/repo` | | `workflow` | Kyllä | Workflow-tiedosto testi-repossa | | `ref` | Kyllä | Branch (esim. `main`) | | `tags` | Ei | Cucumber-tagit (esim. `"@smoke and not @slow"`) | | `versionApiUrl` | Ei | URL deployed-version tarkistukseen | | `versionCheckScript` | Ei | Polku version check -skriptiin (repossa tai kontissa) | --- ## `isArtifactBuild()`-mekanismi (POC: suunniteltu, ei toteutettu) > **Jenkins-legacy:** Jenkins-versiossa tämä oli `isContainerBuild()`. POC > osoitti, että provider ei tiedä eikä tarvitse tietää, buildaako consumer > kontin, JARin vai npm-paketin. Siksi `isContainerBuild()` → > `isArtifactBuild()`. **Ongelma:** Samaa committia vasten voidaan ajaa master-workflow useita kertoja. On mieletöntä buildata artifakti uudestaan, koska commit on jo tagätty versiolla ja artifakti on olemassa rekisterissä. Uudelleenbuildaus aiheuttaa versiokonflikteja ja tuhlaa CI-aikaa. **Ratkaisu:** Workflow'n alussa tarkistetaan, onko tälle commitille jo olemassa versiotagi. ```bash # is-container-built.sh TAG=$(git tag --points-at HEAD | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -1) if [ -n "$TAG" ]; then echo "container_already_built=true" >> $GITHUB_ENV echo "container_version=$TAG" >> $GITHUB_ENV else echo "container_already_built=false" >> $GITHUB_ENV fi ``` Workflow käyttää tätä ehtona: ```yaml jobs: build-container: if: env.container_already_built != 'true' steps: - run: docker build ... test-flow: if: always() needs: [build-container] steps: - run: dispatch-workflow.sh ... ``` **Mitä `isContainerBuild() == true` tarkoittaa käytännössä:** - Kontti on jo buildattu ja pushattu rekisteriin - Commit on tagätty versiolla (esim. `1.2.3.42`) - Build-steppi skipataan → siirrytään suoraan test flow'hun - Sama versio deployataan ja testataan — ei uutta konttia **Miksi tämä on välttämätöntä:** - Estää versiokonfliktit: `1.2.3.42` ei voi olla kahdesti - Säästää CI-aikaa: artifaktin buildaus on hitain vaihe - Pitää commitin ja artifaktin välisen suhteen yksiselitteisenä: `git tag` kertoo suoraan mikä versio vastaa tätä committia --- ## Version check (Fibonacci-backoff) Ennen kuin testit ajetaan, pitää varmistua että haluttu konttiversio on oikeasti deployattu ympäristöön. Muuten testataan väärää versiota. **Malli:** Skripti, joka pollaa deployatun version API:a Fibonacci-backoffilla: ```bash #!/bin/bash # check-version.sh # Palauttaa 0 jos versiot täsmäävät, 1 muuten. URL=$1 EXPECTED=$2 MAX_RETRIES=10 # Fibonacci-sekvenssi: 1 2 3 5 8 13 21 34 55 89 FIB=(1 2 3 5 8 13 21 34 55 89) for i in $(seq 1 $MAX_RETRIES); do ACTUAL=$(curl -s "$URL" | jq -r '.version // empty') if [ "$ACTUAL" = "$EXPECTED" ]; then echo "Version match: $ACTUAL" exit 0 fi echo "Attempt $i/$MAX_RETRIES: $ACTUAL != $EXPECTED, waiting ${FIB[$i-1]}s..." sleep ${FIB[$i-1]} done echo "Version mismatch after $MAX_RETRIES attempts" exit 1 ``` **Miksi Fibonacci:** Uusi deploy käynnistyy nopeasti (ensimmäiset pollaukset tiheään). Jos kontin pullaus tai podin käynnistys kestää, pollausväli kasvaa — ei turhaan kuormiteta API:a. Maksimiaika: ~231 sekuntia (summa 1..89). Version check -skripti joko: - Asuu testi-repossa (projektin oma toteutus) → `versionCheckScript`-kenttä - Tai käyttää geneeristä API:a → `versionApiUrl`-kenttä, skripti on osa kirjastoa --- ## `doNotDowngrade` Jenkinsin deploy-jobissa oli `doNotDowngrade`-parametri, joka esti vanhemman version deployaamisen uudemman päälle. Gitea Actions -versiossa: - **Ei MVP:ssä.** Deploy tekee sen mitä käsketään. `doNotDowngrade` on lisäturva, joka voidaan lisätä deploy-workflow'hun myöhemmin. - **Mekanismi:** Ennen YAML:n muokkausta tarkistetaan nykyinen versio. Jos `new < current`, skipataan ja raportoidaan. - **Toteutus:** Yksi `if`-ehto deploy-workflow'n alussa, ei vaadi muutoksia muualle. --- ## UX-esimerkki: projektin `.gitea/workflows/ci.yml` Näin mikropalvelun kehittäjä käyttää kirjastoa: ```yaml # .gitea/workflows/ci.yml — projektin juuressa name: CI on: push: branches: ["**"] workflow_dispatch: jobs: feature: if: github.ref != 'refs/heads/master' uses: org/gitea-ci-library/.gitea/workflows/ci-feature.yml@v1 secrets: inherit with: config-file: ci-flow-values.yaml maven-image: maven:3.9-eclipse-temurin-21 master: if: github.ref == 'refs/heads/master' uses: org/gitea-ci-library/.gitea/workflows/ci-master.yml@v1 secrets: inherit with: config-file: ci-flow-values.yaml maven-image: maven:3.9-eclipse-temurin-21 docker-image: docker:26-dind ``` Kehittäjä määrittelee: - Millä kontilla buildataan (`maven-image` — koska kirjasto ei tiedä projektin Java-versiota) - Mistä konfiguraatio luetaan (`config-file`) - Millä docker-versiolla kontit rakennetaan (`docker-image`) Kaikki Git-, raportointi-, SonarQube- ja deploy-konfiguraatio on `ci-flow-values.yaml`:ssa.