- Rename build-feature.yml → quality-gate.yml (merge-portti) - Create build_publish-artifact.yml: check → qg → build → push → tag - Add minimal Dockerfile for dogfood container build - Simplify quality-gate.yml cucumber job (remove prepare step, TOOL_OK) - Standardize test scripts in package.json for Docker-based local + CI runs - Update ci.yml: main branch uses build_publish-artifact.yml - Update docs/workflows.md: feature section rewritten with provider model - Add .gitignore entries for coverage/ and reports/
12 KiB
Reusable workflowt
⚠️ POC-vaihe. Toteutettu:
quality-gate.yml. Suunnitteilla:ci-master.yml,deploy.yml,test.yml.
Yhteiset konventiot
Kaikki workflowt:
- Käyttävät
concurrency:-ryhmää estämään saman branchin rinnakkaiset ajot (vastaa JenkinsdisableConcurrentBuilds()) - Lukevat konfiguraation
ci-flow-values.yaml:sta - Raportoivat jokaisen vaiheen Gitea-commitin statukseen
report-status.sh:lla - Käyttävät projektilta saatuja
with:-parametreja konttien määrittelyyn (kirjasto ei pakota konttiversioita)
quality-gate.yml — Merge-portti
Trigger: workflow_call — consumer kutsuu uses:-direktiivillä
Rooli: Laatuportti, joka ajetaan branch protection -sääntönä ennen PR:n
sulkemista mainiin. Pipeline on ajettava (run > 1) eikä yhtään jobia
saa failata.
Provider-Consumer-malli (ADR 0005): Provider tarjoaa orkestroinnin (validointi, raporttien julkaisu, commit-status). Consumer omistaa pipeline-stepit — valitsee testityökalunsa, mahdolliset laatu- ja tietoturva-analyy sit sekä niiden järjestyksen. Alla oleva esimerkki kuvaa tyypillistä Java-mikropalvelua Mavenilla; consumer korvaa nämä omalla tekniikkapinollaan.
Inputs (providerin rajapinta)
| Parametri | Pakollinen | Tyyppi | Kuvaus |
|---|---|---|---|
env_json |
Kyllä | string | JSON-muotoiset ympäristömuuttujat (GITEA_API_URL, GIT_PAGES_URL) |
* |
— | — | Consumer lisää omat parametrinsa (maven-image, docker-image, jne.) |
Secrets
| Secret | Pakollinen | Kuvaus |
|---|---|---|
GITEA_TOKEN |
Kyllä | Gitea API-kutsuihin (commit-status) |
GIT_PAGES_PUBLISH_TOKEN |
Kyllä | Raporttien julkaisuun git-pagesiin |
Steppi-kaavio (Java-esimerkki)
%%{init: {'theme': 'base', 'flowchart': {'arrowheadScale': 2}}}%%
flowchart TD
VAL["validate
provider: tarkista
CI-konfiguraatio"] --> TEST["test
consumer: mvn test
→ testiraportit + coverage"]
VAL --> AI_SCAN["ai-scan \[optional\]
consumer: tietoturva-
tai laatu-skannaus"]
TEST --> SONAR["sonarqube \[optional\]
consumer: mvn sonar:sonar
→ laatupoikkeamat"]
TEST --> PUB["publish-reports
provider: vie raportit
git-pagesiin"]
SONAR --> PUB
AI_SCAN --> PUB
PUB --> STATUS["commit-status
provider: aseta status
linkillä raporttiin"]
FAIL("fail") -. "if: always()" .-> PUB
style VAL fill:#2563eb,color:#ffffff
style TEST fill:#059669,color:#ffffff
style SONAR fill:#7c3aed,color:#ffffff
style AI_SCAN fill:#7c3aed,color:#ffffff
style PUB fill:#0891b2,color:#ffffff
style STATUS fill:#f59e0b,color:#111827
style FAIL fill:#dc2626,color:#ffffff
linkStyle default stroke:#9ca3af,stroke-width:3px
Consumerin omat stepit (test, sonarqube, ai-scan) ovat esimerkki. Vastaava rakenne toimii millä tahansa kielellä tai työkalulla.
Optionaaliset laatu- ja tietoturvaskannaukset
Consumer voi lisätä pipelineen omia skannaussteppejä testien rinnalle.
Nämä ajetaan rinnakkain validate-vaiheen jälkeen ja syöttävät
raporttinsa providerin publish-reports-palveluun. Jokainen skannaus
on oma Gitea Actions -jobinsa.
%%{init: {'theme': 'base', 'flowchart': {'arrowheadScale': 2}}}%%
flowchart LR
VAL["validate"] --> SAST["sast
semgrep / codeql"]
VAL --> SCA["sca
snyk / owasp dc"]
VAL --> SECRETS["secret-scan
gitleaks"]
VAL --> LICENSE["license
fossa / scancode"]
VAL --> AI_REVIEW["ai-review
code quality"]
SAST --> PUB
SCA --> PUB
SECRETS --> PUB
LICENSE --> PUB
AI_REVIEW --> PUB
PUB["publish-reports + commit-status"]
style VAL fill:#2563eb,color:#ffffff
style SAST fill:#7c3aed,color:#ffffff
style SCA fill:#7c3aed,color:#ffffff
style SECRETS fill:#7c3aed,color:#ffffff
style LICENSE fill:#7c3aed,color:#ffffff
style AI_REVIEW fill:#7c3aed,color:#ffffff
style PUB fill:#0891b2,color:#ffffff
linkStyle default stroke:#9ca3af,stroke-width:3px
| Kategoria | Esimerkki | Kuvaus |
|---|---|---|
| SAST | Semgrep, CodeQL | Staattinen analyysi — bugit ja haavoittuvuudet koodista |
| SCA | Snyk, OWASP Dependency-Check | Riippuvuuksien tunnetut haavoittuvuudet |
| Secret scan | Gitleaks, TruffleHog | API-avaimet, tokenit ja salasanat repossa |
| Lisenssit | FOSSA, ScanCode | Riippuvuuksien lisenssien yhteensopivuus |
| AI review | — | Automaattinen koodikatselmointi |
Error handling
Providerin julkaisu- ja status-stepit käyttävät if: always()-ehtoa,
jotta raportit ja commit-status päivittyvät myös failaavista ajoista.
Consumerin omat stepit voivat vapaasti päättää continue-on-error- tai
if: failure()-logiikastaan. Provider ei määrittele virheidenkäsittelyä
consumerin pipelineen.
Merge-portti
Branch protection -säännössä Giteassa vaaditaan ennen PR:n sulkemista:
- Pipeline on ajettu (
run > 1, ei "never run" -tila) - Kaikki commit-statukset vihreitä — validate, testit, laatuportit
- Jos joku steppi failaa, status asettuu
failure-tilaan ja PR:n sulkeminen estyy
Optionaalinen PR-ympäristö (preview app)
Consumer voi halutessaan buildata kontin ja deployata sen väliaikaiseen PR-ympäristöön. Tämä on optionaalinen continuation-haara, joka aktivoituu ehdolla:
- PR:ssä on tietty label (esim.
preview) - Commit message sisältää triggerisanan (esim.
[preview])
Elinkaari:
%%{init: {'theme': 'base', 'flowchart': {'arrowheadScale': 2}}}%%
flowchart LR
QG["quality-gate
testit + skannaukset
ok"] --> BUILD["build-container
tag: pr-42"]
BUILD --> DEPLOY["deploy-pr-env
väliaikainen ympäristö"]
DEPLOY --> STATUS["commit-status
linkki PR-ympäristöön"]
PR_CLOSE["PR merged / closed"] --> CLEANUP["cleanup-pr-env
tuhoa ympäristö"]
style QG fill:#059669,color:#ffffff
style BUILD fill:#0891b2,color:#ffffff
style DEPLOY fill:#7c3aed,color:#ffffff
style STATUS fill:#f59e0b,color:#111827
style PR_CLOSE fill:#dc2626,color:#ffffff
style CLEANUP fill:#dc2626,color:#ffffff
linkStyle default stroke:#9ca3af,stroke-width:3px
- Quality-gate läpäisty (testit + skannaukset ok)
- Buildaa kontti, tagi sisältää PR-numeron (
pr-42) - Deployaa PR-ympäristöön (preview/review app)
- Asettaa commit-statuksen linkillä ympäristöön
- PR:n sulkeutuessa (merge/close): cleanup-job tuhoaa ympäristön
Tämä on consumerin vastuulla — provider tarjoaa tarvittavat
skriptit (publish-git-pages.sh, report-status.sh), mutta
trigger-ehto, kontin buildaus ja ympäristön hallinta kuuluvat
consumerin pipelineen.
ci-master.yml — Main-branch build
Trigger: workflow_call — kutsutaan main-branchiin pushattaessa
Rooli: Buildaa artifaktin (kontti, JAR, npm-paketti tms.) ja julkaisee sen rekisteriin. Jos sama commit on jo buildattu (version tag on olemassa), build skipataan ja siirrytään suoraan test flow'hun.
Provider-Consumer-malli (ADR 0005): Provider orkestroi idempotent
build-logiikan (isArtifactBuilt-tarkistus), mutta consumer omistaa
build-stepit — valitsee työkalut ja artifaktityypin.
isArtifactBuilt-check
Ennen buildia tarkistetaan, onko tälle commitille jo olemassa versiotagi:
TAG=$(git tag --points-at HEAD | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -1)
if [ -n "$TAG" ]; then
echo "artifact_already_built=true" >> $GITHUB_ENV
echo "artifact_version=$TAG" >> $GITHUB_ENV
fi
Jos tagi löytyy, build- ja push-stepit skipataan. Committia vastaan on jo olemassa artifakti rekisterissä — uudelleenbuildaus aiheuttaisi versiokonflikteja ja tuhlaisi CI-aikaa.
Steppi-kaavio
%%{init: {'theme': 'base', 'flowchart': {'arrowheadScale': 2}}}%%
flowchart TD
CHECK{"isArtifactBuilt?
git tag --points-at HEAD"}
CHECK -- "ei" --> QG["quality-gate
testit + skannaukset"]
QG --> BUILD["build-artifact
consumer: docker build /
mvn package / npm build"]
BUILD --> PUSH["push registry
gitea packages /
docker registry"]
PUSH --> TAG["tag-commit
tagittaa commitin
versiolla (esim. 1.2.3.${RUN})"]
CHECK -- "kyllä" --> K8S["continueToTestFlow
(future: K8s-testit
test plan -mukaan)"]
TAG --> K8S
FAIL("fail") -. "quality-gate
ei läpäisty" .-> END
K8S --> END(["end
commit-status"])
style CHECK fill:#f59e0b,color:#111827
style QG fill:#059669,color:#ffffff
style BUILD fill:#0891b2,color:#ffffff
style PUSH fill:#dc2626,color:#ffffff
style TAG fill:#f59e0b,color:#111827
style K8S fill:#7c3aed,color:#ffffff
style FAIL fill:#dc2626,color:#ffffff
style END fill:#2563eb,color:#ffffff
linkStyle default stroke:#9ca3af,stroke-width:3px
Elinkaari
- isArtifactBuilt? — tarkista onko tagi olemassa
- quality-gate — jos ei tagia, aja
quality-gate.yml(testit, skannaukset) - build-artifact — jos quality-gate läpäisty, buildaa artifakti
- push registry — julkaise rekisteriin (Gitea Packages, Docker registry, jne.)
- tag-commit — tagittaa commitin versiolla (esim.
1.2.3.<run_number>) - continueToTestFlow — (future) aja K8s-testit test plan -mukaan
- commit-status — aseta lopullinen status
Concurrency
concurrency:
group: master-${{ github.repository }}
cancel-in-progress: false
Vain yksi master-build kerrallaan per repo. Ei cancel-in-progress — käynnissä olevan buildin annetaan valmistua.
deploy.yml — GitOps-deployment
Trigger: workflow_dispatch (aina dispatchataan toisesta workflow'sta)
Elinkaari:
start → read-yaml → update-value → commit → push → report-cross-repo → end
Inputs (dispatch-parametrit)
| Parametri | Kuvaus |
|---|---|
environment |
Ympäristön nimi (korvaa {.environment}) |
version |
Uusi konttiversio |
root_commit |
Mikropalvelun commit josta deploy käynnistyi |
root_repo |
Mikropalvelun repo |
root_build_url |
URL mikropalvelun buildiin |
Mitä deploy tekee
- Lukee
{projectFolder}/{fileName}YAML-tiedoston (korvaa{.environment}→environment) - Päivittää
{property}-avaimen arvoksi{version} git add,git commit -m "deploy {version} to {environment}"git push origin HEAD:master- Raportoi statuksen:
- Helm-repon committiin: "from {root_commit}", URL → root-build
- Mikropalvelun committiin (
root_commit): "deployed to {environment}", URL → Helm-commit
- Palauttaa Helm-commitin hashin (
outputs.commit)
Concurrency
concurrency:
group: deploy-${{ github.repository }}-${{ inputs.environment }}
cancel-in-progress: false
test.yml — Test flow -steppi
Trigger: workflow_dispatch (dispatchataan deploy-workflow'n jälkeen)
Elinkaari:
start → version-check → run-tests → push-reports → report-cross-repo → end
Inputs (dispatch-parametrit)
| Parametri | Kuvaus |
|---|---|
environment |
Testiympäristö |
version |
Testattava konttiversio |
tags |
Cucumber-tagit |
versionApiUrl |
URL version tarkistukseen |
versionCheckScript |
Polku version check -skriptiin |
root_commit |
Mikropalvelun commit |
root_repo |
Mikropalvelun repo |
deploy_commit |
Helm-repon commit (deployattu versio) |
deploy_repo |
Helm-repo |
Version check
Ennen testejä varmistetaan, että ympäristössä pyörii oikea versio:
- name: Check deployed version
if: inputs.versionCheckScript || inputs.versionApiUrl
run: |
if [ -n "${{ inputs.versionCheckScript }}" ]; then
bash "${{ inputs.versionCheckScript }}" "${{ inputs.versionApiUrl }}" "${{ inputs.version }}"
fi
Version check -skripti pollaa Fibonacci-backoffilla — ks. config-model.md.
Cross-repo-raportointi
Testien jälkeen raportoidaan kolmeen committiin:
- Testi-repon oma commit: testin status
- Mikropalvelun commit (
root_commit): "testit OK/epäonnistui" - Helm-repon commit (
deploy_commit): "testattu v{version}"
Concurrency
concurrency:
group: test-${{ inputs.environment }}
cancel-in-progress: false