From 23874f59b6180f61e46bd7e1851926a5f4d57a55 Mon Sep 17 00:00:00 2001 From: moilanik Date: Sun, 14 Jun 2026 05:43:15 +0300 Subject: [PATCH] feat: implement quality-gate and publish-artifact pipelines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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/ --- .gitea/workflows/build_publish-artifact.yml | 124 ++++++++ .gitea/workflows/ci.yml | 2 +- .gitea/workflows/quality-gate.yml | 46 +-- .gitignore | 3 + Dockerfile | 1 + docs/workflows.md | 305 ++++++++++++++------ package.json | 49 ++-- 7 files changed, 389 insertions(+), 141 deletions(-) create mode 100644 .gitea/workflows/build_publish-artifact.yml create mode 100644 Dockerfile diff --git a/.gitea/workflows/build_publish-artifact.yml b/.gitea/workflows/build_publish-artifact.yml new file mode 100644 index 0000000..e0b0928 --- /dev/null +++ b/.gitea/workflows/build_publish-artifact.yml @@ -0,0 +1,124 @@ +name: Build & Publish Artifact +on: + workflow_call: + inputs: + env_json: + required: true + type: string + bats-image: + required: true + type: string + cucumber-node-image: + required: true + type: string + secrets: + GITEA_TOKEN: + required: true + GIT_PAGES_PUBLISH_TOKEN: + required: true + +env: + GITEA_API_URL: ${{ fromJson(inputs.env_json).GITEA_API_URL }} + GIT_PAGES_URL: ${{ fromJson(inputs.env_json).GIT_PAGES_URL }} + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + GIT_PAGES_PUBLISH_TOKEN: ${{ secrets.GIT_PAGES_PUBLISH_TOKEN }} + +jobs: + check: + runs-on: ubuntu-latest + outputs: + artifact_exists: ${{ steps.check.outputs.artifact_exists }} + version: ${{ steps.check.outputs.version }} + steps: + - uses: actions/checkout@v4 + + - name: Check existing artifact + id: check + run: | + VERSION=$(jq -r '.version' package.json) + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + + TAG=$(curl -s "$GITEA_API_URL/api/v1/repos/$GITHUB_REPOSITORY/tags" | \ + jq -r '.[] | select(.commit.sha == "'"$GITHUB_SHA"'") | .name' | head -1) + if [ -n "$TAG" ]; then + echo "artifact_exists=true" >> "$GITHUB_OUTPUT" + echo "Commit already tagged as $TAG, skipping build" + else + echo "artifact_exists=false" >> "$GITHUB_OUTPUT" + fi + + quality-gate: + needs: [check] + if: needs.check.outputs.artifact_exists == 'false' + uses: niko/gitea-ci-library/.gitea/workflows/quality-gate.yml@feture/docker-kyky + secrets: inherit + with: + env_json: ${{ inputs.env_json }} + bats-image: ${{ inputs.bats-image }} + cucumber-node-image: ${{ inputs.cucumber-node-image }} + + build: + needs: [check, quality-gate] + if: needs.check.outputs.artifact_exists == 'false' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build container + run: | + docker build -t "minimal:${{ needs.check.outputs.version }}" . + mkdir -p /tmp/image + docker save "minimal:${{ needs.check.outputs.version }}" -o /tmp/image/artifact.tar + + - name: Save Docker image for next job + uses: actions/upload-artifact@v4 + with: + name: docker-image + path: /tmp/image/artifact.tar + + push: + needs: [check, build] + runs-on: ubuntu-latest + steps: + - name: Load saved Docker image + uses: actions/download-artifact@v4 + with: + name: docker-image + path: /tmp/image + + - name: Push to Gitea Packages + run: | + VERSION="${{ needs.check.outputs.version }}" + docker load -i /tmp/image/artifact.tar + REGISTRY=$(echo "$GITEA_API_URL" | sed 's|https://||') + IMAGE="$REGISTRY/niko/gitea-ci-library/minimal:$VERSION" + docker tag "minimal:$VERSION" "$IMAGE" + docker login "$REGISTRY" -u niko -p "$GITEA_TOKEN" + docker push "$IMAGE" + docker logout "$REGISTRY" + + tag-commit: + needs: [check, push] + runs-on: ubuntu-latest + steps: + - name: Create git tag + run: | + VERSION="${{ needs.check.outputs.version }}" + HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \ + "$GITEA_API_URL/api/v1/repos/$GITHUB_REPOSITORY/tags" \ + -H "Authorization: token $GITEA_TOKEN" \ + -H "Content-Type: application/json" \ + -d "{ + \"tag_name\": \"$VERSION\", + \"message\": \"Build #$GITHUB_RUN_NUMBER\", + \"target\": \"$GITHUB_SHA\" + }") + + if [ "$HTTP_CODE" = "201" ]; then + echo "Tag $VERSION created" + elif [ "$HTTP_CODE" = "409" ]; then + echo "Tag $VERSION already exists (parallel build won), skipping" + else + echo "Failed to create tag: HTTP $HTTP_CODE" + exit 1 + fi diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 16e6939..601b0f4 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: main: if: github.ref == 'refs/heads/main' needs: [load-config] - uses: niko/gitea-ci-library/.gitea/workflows/quality-gate.yml@main + uses: niko/gitea-ci-library/.gitea/workflows/build_publish-artifact.yml@feture/docker-kyky secrets: inherit with: env_json: ${{ needs.load-config.outputs.env_json }} diff --git a/.gitea/workflows/quality-gate.yml b/.gitea/workflows/quality-gate.yml index aaaacab..c335ddc 100644 --- a/.gitea/workflows/quality-gate.yml +++ b/.gitea/workflows/quality-gate.yml @@ -49,20 +49,22 @@ jobs: id: bats-tests shell: bash run: | - docker volume create bats-workspace - tar c . | docker run --rm -i -v bats-workspace:/data alpine tar x -C /data mkdir -p "reports/${GITHUB_SHA:0:8}/bats" + docker volume create bats-cov set +e docker run --rm \ - -v bats-workspace:/data \ + -v "$(pwd):/repo:ro" \ + -v bats-cov:/coverage \ + -v "$(pwd)/reports/${GITHUB_SHA:0:8}/bats:/reports" \ + -w /repo \ + -e COVERAGE_DIR=/coverage \ --entrypoint bash ${{ inputs.bats-image }} \ - -c 'apk add -q lsof python3 jq curl ruby && cd /data && \ + -c 'apk add -q lsof python3 jq curl ruby && \ gem install bashcov -v 3.3.0 2>&1 | tail -1 && \ - bashcov -- bats tests/' \ - > "reports/${GITHUB_SHA:0:8}/bats/results.txt" 2>&1 + bashcov -- bats tests/ | tee /reports/results.txt' BATS_EXIT=$? - bash .ci/.gitea/scripts/bats-coverage.sh bats-workspace "reports/${GITHUB_SHA:0:8}/bats" - docker volume rm bats-workspace > /dev/null 2>&1 + bash .ci/.gitea/scripts/bats-coverage.sh bats-cov "reports/${GITHUB_SHA:0:8}/bats" + docker volume rm bats-cov > /dev/null 2>&1 bash .ci/.gitea/scripts/bats-report.sh "reports/${GITHUB_SHA:0:8}/bats" echo "BATS_EXIT=${BATS_EXIT}" >> "${GITHUB_ENV}" exit ${BATS_EXIT} @@ -91,27 +93,12 @@ jobs: repository: niko/gitea-ci-library path: .ci - - name: Prepare cucumber - id: prepare-cucumber - shell: bash - run: | - apt-get update -qq && apt-get install -y -qq --no-install-recommends lsof jq - if npm install @cucumber/cucumber > /dev/null 2>&1 && \ - npx --package @cucumber/cucumber cucumber-js --dry-run tests/features/ > /dev/null 2>&1; then - echo "TOOL_OK=true" >> "${GITHUB_ENV}" - else - echo "TOOL_OK=false" >> "${GITHUB_ENV}" - fi - - name: Run cucumber tests - if: always() id: cucumber-tests shell: bash run: | - if [ "${TOOL_OK}" != "true" ]; then - echo "CUCUMBER_EXIT=1" >> "${GITHUB_ENV}" - exit 0 - fi + apt-get update -qq && apt-get install -y -qq --no-install-recommends lsof jq + npm install @cucumber/cucumber > /dev/null 2>&1 mkdir -p "reports/${GITHUB_SHA:0:8}/cucumber" set +e npx cucumber-js \ @@ -123,17 +110,12 @@ jobs: - name: Publish cucumber reports if: always() - run: | - if [ "${TOOL_OK}" = "true" ]; then - bash .ci/scripts/publish-git-pages.sh cucumber - fi + run: bash .ci/scripts/publish-git-pages.sh cucumber - name: Set cucumber commit status if: always() run: | - if [ "${TOOL_OK}" != "true" ]; then - bash .ci/scripts/report-status.sh failure "Cucumber tool unavailable" ci-cucumber - elif [ "${CUCUMBER_EXIT}" = "0" ]; then + if [ "${CUCUMBER_EXIT}" = "0" ]; then bash .ci/scripts/report-status.sh success "Cucumber tests passed" ci-cucumber cucumber else bash .ci/scripts/report-status.sh failure "Cucumber tests FAILED" ci-cucumber cucumber diff --git a/.gitignore b/.gitignore index 7de0cc5..ab0d526 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ AGENTS.md .ai node_modules/ tmp/ +coverage/ +.DS_Store +reports/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b09b037 --- /dev/null +++ b/Dockerfile @@ -0,0 +1 @@ +FROM alpine:latest diff --git a/docs/workflows.md b/docs/workflows.md index 1544372..5d64830 100644 --- a/docs/workflows.md +++ b/docs/workflows.md @@ -1,8 +1,7 @@ # Reusable workflowt -> ⚠️ **POC-vaihe.** Tämä dokumentti kuvaa suunniteltuja workflow'ta -> (ci-feature, ci-master, deploy, test). POCissa on toteutettu -> `build-feature.yml`. Uudelleenkirjoitus odottaa. +> ⚠️ **POC-vaihe.** Toteutettu: `quality-gate.yml`. Suunnitteilla: +> `ci-master.yml`, `deploy.yml`, `test.yml`. --- @@ -16,136 +15,271 @@ Kaikki workflowt: --- -## `ci-feature.yml` — Feature-branch +## `quality-gate.yml` — Merge-portti -**Trigger:** `push` mihin tahansa branchiin paitsi `master` +**Trigger:** `workflow_call` — consumer kutsuu `uses:`-direktiivillä -**Elinkaari:** +**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. -``` -start → unit-test → code-coverage → html-reports → end -``` +**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 +### Inputs (providerin rajapinta) -| Parametri | Pakollinen | Kuvaus | -|-----------|------------|--------| -| `config-file` | Kyllä | Polku `ci-flow-values.yaml`:aan (yleensä `ci-flow-values.yaml`) | -| `containers` | Ei | Kuvaus konteista: avain = nimi, arvo = image. Steppi valitsee missä kontissa ajaa. | +| 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.) | -### Steppi-kaavio +### 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) ```mermaid %%{init: {'theme': 'base', 'flowchart': {'arrowheadScale': 2}}}%% flowchart TD - START(["checkout + start - POST INPROGRESS"]) --> UNIT["unit-test - aja testit, generoi raportit"] - UNIT --> COV["code-coverage - jacoco / vastaava"] - COV --> HTML["publish-reports - vie raportit git-pagesiin"] - HTML --> END(["end - POST lopullinen status"]) + VAL["validate + provider: tarkista + CI-konfiguraatio"] --> TEST["test + consumer: mvn test + → testiraportit + coverage"] - FAIL("fail") -. "catch" .-> END + VAL --> AI_SCAN["ai-scan \[optional\] + consumer: tietoturva- + tai laatu-skannaus"] - style START fill:#2563eb,color:#ffffff - style UNIT fill:#059669,color:#ffffff - style COV fill:#059669,color:#ffffff - style HTML fill:#7c3aed,color:#ffffff - style END fill:#2563eb,color:#ffffff + 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. + +```mermaid +%%{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 -Workflow käyttää Gitea Actionsin natiivia `jobs..continue-on-error` ja `if: failure()` -ehtoja. Ei erillistä `fail(e)`-kutsua kuten Jenkinsissä. Epäonnistunut steppi asettaa statuksen `failure` ja jatkaa `end`-steppiin, joka raportoi lopullisen statuksen. +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 -## `ci-master.yml` — Master / release-branch +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 -**Trigger:** `push` `master`-branchiin tai `workflow_dispatch` +### 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:** -``` -start → isContainerBuilt? ──kyllä──→ continueToTestFlow - │ - ei - ↓ -unit-test → quality-gate → build-jar → build-docker → push-docker → tag-commit → continueToTestFlow → end +```mermaid +%%{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 ``` -### Inputs +1. Quality-gate läpäisty (testit + skannaukset ok) +2. Buildaa kontti, tagi sisältää PR-numeron (`pr-42`) +3. Deployaa PR-ympäristöön (preview/review app) +4. Asettaa commit-statuksen linkillä ympäristöön +5. **PR:n sulkeutuessa** (merge/close): cleanup-job tuhoaa ympäristön -| Parametri | Pakollinen | Kuvaus | -|-----------|------------|--------| -| `config-file` | Kyllä | Polku `ci-flow-values.yaml`:aan | -| `containers` | Ei | Kuvaus konteista: avain = nimi, arvo = image | +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. -### isContainerBuilt-check +--- -```yaml -- name: Check if container already built - run: | - 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 - fi +## `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: + +```bash +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 `container_already_built == true`, build- ja push-steppit skipataan. Siirrytään suoraan `continueToTestFlow`:hun. +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 ```mermaid %%{init: {'theme': 'base', 'flowchart': {'arrowheadScale': 2}}}%% flowchart TD - START(["start"]) --> CHECK{"isContainerBuilt? + CHECK{"isArtifactBuilt? git tag --points-at HEAD"} - - CHECK -- "ei" --> UNIT["unit-test"] - UNIT --> SONAR["quality-gate - SonarQube"] - SONAR --> JAR["build-jar - ArtifactType.JAR"] - JAR --> DOCKER["build-docker - ArtifactType.DOCKER - + Docker-labelit"] - DOCKER --> PUSH["push-docker - ArtifactType.DOCKER"] + + 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"] - - CHECK -- "kyllä" --> CTF["continueToTestFlow"] - TAG --> CTF - CTF --> HTML["publish-reports - vie raportit git-pagesiin"] - HTML --> END(["end - lopullinen status"]) + versiolla (esim. 1.2.3.${RUN})"] - FAIL("fail") -. "catch" .-> END + 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 START fill:#2563eb,color:#ffffff style CHECK fill:#f59e0b,color:#111827 - style UNIT fill:#059669,color:#ffffff - style SONAR fill:#7c3aed,color:#ffffff - style JAR fill:#0891b2,color:#ffffff - style DOCKER fill:#0891b2,color:#ffffff + 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 CTF fill:#f59e0b,color:#111827 - style HTML fill:#7c3aed,color:#ffffff - style END fill:#2563eb,color:#ffffff + 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 + +1. **isArtifactBuilt?** — tarkista onko tagi olemassa +2. **quality-gate** — jos ei tagia, aja `quality-gate.yml` (testit, skannaukset) +3. **build-artifact** — jos quality-gate läpäisty, buildaa artifakti +4. **push registry** — julkaise rekisteriin (Gitea Packages, Docker registry, jne.) +5. **tag-commit** — tagittaa commitin versiolla (esim. `1.2.3.`) +6. **continueToTestFlow** — *(future)* aja K8s-testit test plan -mukaan +7. **commit-status** — aseta lopullinen status + ### Concurrency ```yaml @@ -154,7 +288,8 @@ concurrency: cancel-in-progress: false ``` -Vain yksi master-build kerrallaan per repo. Ei cancel-in-progress — käynnissä olevan buildin annetaan valmistua. +Vain yksi master-build kerrallaan per repo. Ei cancel-in-progress — +käynnissä olevan buildin annetaan valmistua. --- diff --git a/package.json b/package.json index 10809ed..ad2f5b8 100644 --- a/package.json +++ b/package.json @@ -1,24 +1,27 @@ { - "name": "gitea-ci-library", - "version": "1.0.0", - "description": "", - "main": "cucumber.js", - "directories": { - "doc": "docs", - "test": "tests" - }, - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "repository": { - "type": "git", - "url": "ssh://git@gitea.app.keskikuja.site:30009/niko/gitea-ci-library.git" - }, - "keywords": [], - "author": "", - "license": "ISC", - "type": "commonjs", - "devDependencies": { - "@cucumber/cucumber": "^13.0.0" - } -} + "name": "gitea-ci-library", + "version": "0.1.0", + "description": "", + "main": "cucumber.js", + "directories": { + "doc": "docs", + "test": "tests" + }, + "scripts": { + "test": "npm run test:bats && npm run test:cucumber", + "test:bats": "mkdir -p reports && docker run --rm -v \"$(pwd):/repo:ro\" -v \"$(pwd)/reports:/repo/reports\" -w /repo --entrypoint bash bats/bats:latest -c 'apk add -q python3 curl jq lsof ruby && gem install bashcov -q > /dev/null 2>&1; bats tests/'", + "test:bats:coverage": "mkdir -p reports && docker run --rm -v \"$(pwd):/repo\" -v \"$(pwd)/reports:/repo/reports\" -w /repo --entrypoint bash bats/bats:latest -c 'apk add -q python3 curl jq lsof ruby && gem install bashcov -q > /dev/null 2>&1; bashcov -- bats tests/'", + "test:cucumber": "docker run --rm -v \"$(pwd):/repo:ro\" -v \"$(pwd)/node_modules:/repo/node_modules\" -w /repo --entrypoint bash node:22 -c 'apt-get update -qq && apt-get install -y -qq jq lsof && npm ci && npx cucumber-js tests/features/ --tags @mock and ~@wip'" + }, + "repository": { + "type": "git", + "url": "ssh://git@gitea.app.keskikuja.site:30009/niko/gitea-ci-library.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "commonjs", + "devDependencies": { + "@cucumber/cucumber": "^13.0.0" + } +} \ No newline at end of file