Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 65d385f9b9 | |||
| 2e5a4dca3a | |||
| 29fde14445 |
@@ -12,31 +12,32 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
tag:
|
tag:
|
||||||
required: true
|
required: false
|
||||||
type: string
|
type: string
|
||||||
|
default: 'latest'
|
||||||
secrets:
|
secrets:
|
||||||
DOCKER_USERNAME:
|
DOCKER_USERNAME:
|
||||||
required: false
|
required: false
|
||||||
DOCKER_PASSWORD:
|
DOCKER_PASSWORD:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
env:
|
|
||||||
DOCKER_REGISTRY: ${{ fromJson(inputs.env_json).DOCKER_REGISTRY || '' }}
|
|
||||||
IMAGE_NAME: ${{ inputs.image_name }}
|
|
||||||
TAG: ${{ inputs.tag }}
|
|
||||||
DOCKERFILE: ${{ inputs.dockerfile_path }}
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-push:
|
build-push:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Build and push CI container
|
- name: Build and push container
|
||||||
env:
|
env:
|
||||||
|
DOCKER_REGISTRY: ${{ fromJson(inputs.env_json).DOCKER_REGISTRY || '' }}
|
||||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME || github.actor }}
|
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME || github.actor }}
|
||||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
run: |
|
run: |
|
||||||
|
REGISTRY="${DOCKER_REGISTRY:?DOCKER_REGISTRY not set in conf}"
|
||||||
|
DOCKERFILE="${{ inputs.dockerfile_path }}"
|
||||||
|
IMAGE_NAME="${{ inputs.image_name }}"
|
||||||
|
TAG="${{ inputs.tag }}"
|
||||||
|
|
||||||
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||||
docker build \
|
docker build \
|
||||||
--label "git.commit=${{ github.sha }}" \
|
--label "git.commit=${{ github.sha }}" \
|
||||||
@@ -45,7 +46,6 @@ jobs:
|
|||||||
-f "${DOCKERFILE}" \
|
-f "${DOCKERFILE}" \
|
||||||
-t "${IMAGE_NAME}:${TAG}" .
|
-t "${IMAGE_NAME}:${TAG}" .
|
||||||
|
|
||||||
REGISTRY="${DOCKER_REGISTRY:?DOCKER_REGISTRY not set in env.conf}"
|
|
||||||
REGISTRY_HOST="${REGISTRY%%/*}"
|
REGISTRY_HOST="${REGISTRY%%/*}"
|
||||||
|
|
||||||
FULL_IMAGE="${REGISTRY}/${IMAGE_NAME}:${TAG}"
|
FULL_IMAGE="${REGISTRY}/${IMAGE_NAME}:${TAG}"
|
||||||
|
|||||||
@@ -1,21 +1,41 @@
|
|||||||
name: Build CI Cucumber Container (Manual)
|
name: CI Container Build Cucumber
|
||||||
on: workflow_dispatch
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
config_path:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
default: '.gitea/workflows/example-gitea-env.conf'
|
||||||
|
description: 'Polku .gitea-env.conf-tiedostoon'
|
||||||
|
dockerfile_path:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
default: 'Dockerfile.ci-cucumber'
|
||||||
|
description: 'Polku Dockerfileen'
|
||||||
|
image_name:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
default: 'ci-cucumber'
|
||||||
|
description: 'Kontin nimi ilman registry-polkua'
|
||||||
|
tag:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
default: 'latest'
|
||||||
|
description: 'Image-tägi'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
load-config:
|
load-config:
|
||||||
name: Load config
|
uses: niko/gitea-ci-library/.gitea/workflows/config-provider.yml@v1
|
||||||
uses: niko/gitea-ci-library/.gitea/workflows/config-provider.yml@main
|
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
with:
|
with:
|
||||||
config_path: .gitea/workflows/example-gitea-env.conf
|
config_path: ${{ inputs.config_path }}
|
||||||
|
|
||||||
build-push:
|
build-push:
|
||||||
name: Build & Push
|
|
||||||
needs: [load-config]
|
needs: [load-config]
|
||||||
uses: niko/gitea-ci-library/.gitea/workflows/ci-container-build-push.yml@main
|
uses: niko/gitea-ci-library/.gitea/workflows/ci-container-build-push.yml@v1
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
with:
|
with:
|
||||||
env_json: ${{ needs.load-config.outputs.env_json }}
|
env_json: ${{ needs.load-config.outputs.env_json }}
|
||||||
dockerfile_path: Dockerfile.ci-cucumber
|
dockerfile_path: ${{ inputs.dockerfile_path }}
|
||||||
image_name: ci-cucumber
|
image_name: ${{ inputs.image_name }}
|
||||||
tag: latest
|
tag: ${{ inputs.tag }}
|
||||||
|
|||||||
@@ -7,3 +7,4 @@ tmp/
|
|||||||
coverage/
|
coverage/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
reports/
|
reports/
|
||||||
|
.vscode/
|
||||||
|
|||||||
+4
-1
@@ -26,22 +26,25 @@ kuuluu `git-pages/docs/`-alle, ei juuren `docs/`-kansioon.
|
|||||||
| `.gitea/workflows/config-provider.yml` | Provider: lataa + validoi config-tiedoston, tuottaa `env_json` |
|
| `.gitea/workflows/config-provider.yml` | Provider: lataa + validoi config-tiedoston, tuottaa `env_json` |
|
||||||
| `.gitea/workflows/check-version.yml` | Provider: tarkistaa onko commitille jo artifact, laskee version |
|
| `.gitea/workflows/check-version.yml` | Provider: tarkistaa onko commitille jo artifact, laskee version |
|
||||||
| `.gitea/workflows/docker-build-push.yml` | Provider: buildaa + puskea Docker-imagen, tagittaa commitin |
|
| `.gitea/workflows/docker-build-push.yml` | Provider: buildaa + puskea Docker-imagen, tagittaa commitin |
|
||||||
|
| `.gitea/workflows/ci-container-build-push.yml` | Provider: buildaa + puskea CI-työkalukontin |
|
||||||
| `.gitea/workflows/example-*` | **Consumer-esimerkki**: tämän repon oma CI (dogfood) |
|
| `.gitea/workflows/example-*` | **Consumer-esimerkki**: tämän repon oma CI (dogfood) |
|
||||||
| `scripts/` | Provider-skriptit: `report-status.sh`, `publish-git-pages.sh`, `ci-validate.sh` |
|
| `scripts/` | Provider-skriptit: `report-status.sh`, `publish-git-pages.sh`, `ci-validate.sh` |
|
||||||
| `.gitea/scripts/` | **Consumer-skriptit**: `bats-coverage.sh`, `bats-report.sh` |
|
| `.gitea/scripts/` | **Consumer-skriptit**: `bats-coverage.sh`, `bats-report.sh` |
|
||||||
| `docs/` | Arkkitehtuuri, ADRt (0004–0008) |
|
| `docs/` | Arkkitehtuuri, ADRt (0004–0008) |
|
||||||
| `skills/consumer-pipelines/` | Consumer-pipeline-standardit — AI:n pakottavat säännöt consumer-CI:lle |
|
| `skills/consumer-pipelines/` | Consumer-pipeline-standardit — AI:n pakottavat säännöt consumer-CI:lle |
|
||||||
|
| `skills/ci-container-build/` | CI-kontin build-workflow'n template — `ci-container-build-push.yml` |
|
||||||
| `docs/adr/` | Architecture Decision Records |
|
| `docs/adr/` | Architecture Decision Records |
|
||||||
| `git-pages/` | Raporttien hostaus (Helm-chartti) |
|
| `git-pages/` | Raporttien hostaus (Helm-chartti) |
|
||||||
| `tests/` | Bats-testit skripteille |
|
| `tests/` | Bats-testit skripteille |
|
||||||
|
|
||||||
### Provider workflowt (4 kpl)
|
### Provider workflowt (5 kpl)
|
||||||
|
|
||||||
| Workflow | Input | Output | Kuvaus |
|
| Workflow | Input | Output | Kuvaus |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `config-provider.yml` | `config_path` | `env_json`, `config_path` | Validoi ja jäsentää `.conf` → JSON. Sama kutsu hoitaa validoinnin. |
|
| `config-provider.yml` | `config_path` | `env_json`, `config_path` | Validoi ja jäsentää `.conf` → JSON. Sama kutsu hoitaa validoinnin. |
|
||||||
| `check-version.yml` | `env_json` | `artifact_exists`, `version` | Tarkistaa git-tagit ja `package.json`:n, laskee seuraavan version. Vain main-haarassa. |
|
| `check-version.yml` | `env_json` | `artifact_exists`, `version` | Tarkistaa git-tagit ja `package.json`:n, laskee seuraavan version. Vain main-haarassa. |
|
||||||
| `docker-build-push.yml` | `env_json`, `version` | — | Buildaa Docker-imagen, puskea rekisteriin, tagittaa commitin. |
|
| `docker-build-push.yml` | `env_json`, `version` | — | Buildaa Docker-imagen, puskea rekisteriin, tagittaa commitin. |
|
||||||
|
| `ci-container-build-push.yml` | `env_json`, `dockerfile_path`, `image_name`, `tag` | — | Buildaa CI-työkalukontin, puskea rekisteriin. Ei versiointia eikä git-tägäystä. |
|
||||||
| `report-summary.yml` | `env_json`, `suites` | — | Generoi `GITHUB_STEP_SUMMARY`-taulukon raporttilinkeillä (Gitea 1.27+) |
|
| `report-summary.yml` | `env_json`, `suites` | — | Generoi `GITHUB_STEP_SUMMARY`-taulukon raporttilinkeillä (Gitea 1.27+) |
|
||||||
|
|
||||||
### Example-tiedostot (consumer-referenssi)
|
### Example-tiedostot (consumer-referenssi)
|
||||||
|
|||||||
@@ -0,0 +1,149 @@
|
|||||||
|
---
|
||||||
|
name: ci-container-build
|
||||||
|
description: |
|
||||||
|
Creating or modifying CI container build workflows. Activates when consumer
|
||||||
|
needs to build a custom CI container image (multi-tool image for tests,
|
||||||
|
linting, validation) that is pushed to a container registry for use in
|
||||||
|
other pipeline jobs.
|
||||||
|
activation-gate: |
|
||||||
|
User mentions CI container, custom CI image, ci-container-build, Dockerfile
|
||||||
|
for CI tools, multi-tool container, or needs to build/push a container that
|
||||||
|
other CI jobs will use as their runtime environment.
|
||||||
|
category: ci
|
||||||
|
impact: high
|
||||||
|
---
|
||||||
|
|
||||||
|
# CI Container Build — Template
|
||||||
|
|
||||||
|
Template jolla consumer luo oman CI-kontin build-workflown.
|
||||||
|
Kontti sisältää useamman työkalun yhdistelmän (esim. helm + kubeconform + xsltproc),
|
||||||
|
jota muut jobit käyttävät ajonaikaisena ympäristönä.
|
||||||
|
|
||||||
|
## Rakenne
|
||||||
|
|
||||||
|
Vain `workflow_dispatch` — **ei automaattista buildausta koskaan**. Kontti buildataan
|
||||||
|
manuaalisesti Gitea Actions UI:sta. Tiedoston ilmestyessä main-haaraan workflow näkyy
|
||||||
|
välittömästi Actions-tabissa ajettavana.
|
||||||
|
|
||||||
|
Build-prosessi lataa ensin `config-provider.yml`:llä `DOCKER_REGISTRY`:n
|
||||||
|
conf-tiedostosta, sitten buildaa ja puskaa kontin.
|
||||||
|
|
||||||
|
Kun kontti on pushattu registryyn, se on muiden pipeline-jobien käytettävissä
|
||||||
|
`latest`-tägillä — rebuild = käyttöönotto. Mitään versioviittauksia ei tarvitse
|
||||||
|
päivittää.
|
||||||
|
|
||||||
|
## Nimeäminen
|
||||||
|
|
||||||
|
CI-kontin build-workflow noudattaa samaa nimeämiskonventiota kuin muutkin
|
||||||
|
tiedostot `.gitea/workflows/`-kansiossa:
|
||||||
|
|
||||||
|
```
|
||||||
|
<komponentti>.ci-feature.yml ← feature-haaran reititin
|
||||||
|
<komponentti>.ci-main.yml ← main-haaran reititin
|
||||||
|
<komponentti>.<testityyppi>.yml ← yksittäinen testi tai operaatio
|
||||||
|
<komponentti>.ci-container-build-<kontti>.yml ← CI-kontin build-workflow
|
||||||
|
<komponentti>.gitea-env.conf ← komponenttikohtainen konfiguraatio
|
||||||
|
```
|
||||||
|
|
||||||
|
Single repossa `<komponentti>` jätetään pois — tiedostot ovat suoraan `ci-feature.yml`,
|
||||||
|
`ci-main.yml`, `<testityyppi>.yml`, `ci-container-build-<kontti>.yml`.
|
||||||
|
|
||||||
|
Monorepossa prefiksi pitää komponentin tiedostot yhdessä: `ls <komponentti>.*` löytää kaikki
|
||||||
|
kerralla. **Olemassaolevia prefiksejä ei saa poistaa.**
|
||||||
|
|
||||||
|
Esimerkkejä:
|
||||||
|
```
|
||||||
|
.gitea/workflows/chart.ci-container-build-helm.yml
|
||||||
|
.gitea/workflows/api.ci-container-build-node.yml
|
||||||
|
.gitea/workflows/ci-container-build-bats.yml ← single repo
|
||||||
|
```
|
||||||
|
|
||||||
|
## Template
|
||||||
|
|
||||||
|
> **Korvaa kaikki `__SUURAAKKOSET__`-placeholderit projektin todellisilla arvoilla.**
|
||||||
|
> Ainoastaan `${{ ... }}`-syntaksilla merkityt Gitea Actions -muuttujat ovat ajonaikaisia
|
||||||
|
> eikä niitä korvata.
|
||||||
|
|
||||||
|
Luo `.gitea/workflows/__KOMPONENTTI__.ci-container-build-__KONTTI__.yml`
|
||||||
|
(single repo: `ci-container-build-__KONTTI__.yml`):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: CI Container Build & Push
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
config_path:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
description: 'Polku .gitea-env.conf-tiedostoon (esim. .gitea/workflows/chart.gitea-env.conf)'
|
||||||
|
dockerfile_path:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
description: 'Polku Dockerfileen (esim. ci-helm.Dockerfile)'
|
||||||
|
image_name:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
description: 'Kontin nimi ilman registry-polkua (esim. ci-helm)'
|
||||||
|
tag:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
default: 'latest'
|
||||||
|
description: 'Image-tägi'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
load-config:
|
||||||
|
uses: __OWNER__/gitea-ci-library/.gitea/workflows/config-provider.yml@v1
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
config_path: ${{ inputs.config_path }}
|
||||||
|
|
||||||
|
build-push:
|
||||||
|
needs: [load-config]
|
||||||
|
uses: __OWNER__/gitea-ci-library/.gitea/workflows/ci-container-build-push.yml@v1
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
env_json: ${{ needs.load-config.outputs.env_json }}
|
||||||
|
dockerfile_path: ${{ inputs.dockerfile_path }}
|
||||||
|
image_name: ${{ inputs.image_name }}
|
||||||
|
tag: ${{ inputs.tag }}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Käyttö
|
||||||
|
|
||||||
|
**Gitea Actions UI:sta** (heti kun tiedosto on main-haarassa):
|
||||||
|
|
||||||
|
```
|
||||||
|
Gitea → Actions → CI Container Build & Push → Run workflow
|
||||||
|
|
||||||
|
config_path: .gitea/workflows/__KOMPONENTTI__.gitea-env.conf
|
||||||
|
dockerfile_path: ci-__TYÖKALU__.Dockerfile
|
||||||
|
image_name: ci-__TYÖKALU__
|
||||||
|
tag: latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dockerfile
|
||||||
|
|
||||||
|
Dockerfile yhdistää tarvitut työkalut yhteen konttiin. Molemmat tavat kelpaavat:
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
# Tapa A: COPY --from toisesta imagesta
|
||||||
|
FROM __BASE_IMAGE__:__VERSION__
|
||||||
|
COPY --from=__SOURCE_IMAGE__:__VERSION__ /path/to/binary /usr/local/bin/
|
||||||
|
RUN apk add --no-cache __PAKETIT__ # Ei koskaan git:iä — kloonaus kuuluu pipelinelle
|
||||||
|
|
||||||
|
# Tapa B: curl-lataus (normaali Dockerfilessa)
|
||||||
|
FROM __BASE_IMAGE__:__VERSION__
|
||||||
|
RUN apk add --no-cache curl __PAKETIT__ && \
|
||||||
|
curl -fsSL __URL__/__BINARY__.tar.gz | tar xz -C /usr/local/bin && \
|
||||||
|
apk del curl
|
||||||
|
```
|
||||||
|
|
||||||
|
`COPY --from` on kevyempi (ei curl-asennusta). `curl` on selkeämpi kun binääri
|
||||||
|
tulee suoraan GitHub Releasesista tai vastaavasta.
|
||||||
|
|
||||||
|
## Mitä EI kannata tehdä
|
||||||
|
|
||||||
|
- Älä lisää `workflow_call`-triggariä — CI-konttia ei koskaan buildata automaattisesti
|
||||||
|
- Älä poista `<komponentti>.`-prefiksiä olemassaolevista tiedostoista — ne kuuluvat monorepo-nimeämiskonventioon
|
||||||
|
- Älä sisällytä CI-konttiin mitään sovelluskoodia — vain työkalut
|
||||||
|
- Älä koskaan asenna `git`:iä CI-konttiin — repon kloonaus ja checkout ovat Gitea Actionsin natiiveja operaatioita, eivät kontin vastuulla. Git paisuttaa konttia turhaan ja luo harhan että kontti hallitsee repoa
|
||||||
@@ -46,14 +46,14 @@ jobs:
|
|||||||
|
|
||||||
<test-1>:
|
<test-1>:
|
||||||
needs: [load-config]
|
needs: [load-config]
|
||||||
uses: ./.gitea/workflows/<component>.<test-1>.yml@main
|
uses: ./.gitea/workflows/<component>.<test-1>.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
with:
|
with:
|
||||||
env_json: ${{ needs.load-config.outputs.env_json }}
|
env_json: ${{ needs.load-config.outputs.env_json }}
|
||||||
|
|
||||||
<test-2>:
|
<test-2>:
|
||||||
needs: [load-config]
|
needs: [load-config]
|
||||||
uses: ./.gitea/workflows/<component>.<test-2>.yml@main
|
uses: ./.gitea/workflows/<component>.<test-2>.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
with:
|
with:
|
||||||
env_json: ${{ needs.load-config.outputs.env_json }}
|
env_json: ${{ needs.load-config.outputs.env_json }}
|
||||||
@@ -108,15 +108,89 @@ shellin käyttäytyminen vaihtelee.
|
|||||||
|
|
||||||
1. **Julkiset registry-kontit kiinteällä versiolla** — `alpine/helm:3.19.0`, `node:22`, `maven:3.9-eclipse-temurin-21`.
|
1. **Julkiset registry-kontit kiinteällä versiolla** — `alpine/helm:3.19.0`, `node:22`, `maven:3.9-eclipse-temurin-21`.
|
||||||
Toistettavuus ja turvallisuus eivät saa riippua ulkoisesta `latest`:sta
|
Toistettavuus ja turvallisuus eivät saa riippua ulkoisesta `latest`:sta
|
||||||
2. **Projektin omat CI-kontit `latest`-tägillä** — buildattu `ci-container-build-push.yml`:llä.
|
2. **Projektin omat CI-kontit `latest`-tägillä** — buildattu `ci-container-build-<kontti>.yml`:llä.
|
||||||
Kontin build-pipeline päivittää `latest`:n automaattisesti. Rebuild = käyttöönotto
|
Kontin build-pipeline päivittää `latest`:n automaattisesti. Rebuild = käyttöönotto
|
||||||
kaikissa pipelineissa ilman versioviittauksien päivittelyä.
|
kaikissa pipelineissa ilman versioviittauksien päivittelyä.
|
||||||
`latest` on näille paras käytäntö, ei kompromissi
|
`latest` on näille paras käytäntö, ei kompromissi
|
||||||
3. **Ei koskaan `curl`-latauksia CI-ajon sisällä** — työkalujen asennus CI-stepeissä hidastaa,
|
3. **Ei koskaan `curl`-latauksia CI-ajon sisällä** — työkalujen asennus CI-stepeissä hidastaa,
|
||||||
epäluotettavaa, ja vaikeuttaa toistettavuutta
|
epäluotettavaa, ja vaikeuttaa toistettavuutta
|
||||||
|
|
||||||
Pre-buildattu kontti rakennetaan minimaalisella Dockerfilella, joka kopioi tarvitut binäärit
|
CI-kontin build-workflow'n template: [skills/ci-container-build/SKILL.md](../ci-container-build/SKILL.md) — sisältää
|
||||||
perusimagesta ja asentaa vain välttämättömät paketit.
|
valmiin `ci-container-build-<kontti>.yml`-pohjan jossa `workflow_dispatch`-tuki manuaaliajoon.
|
||||||
|
|
||||||
|
### 4.1 CI-kontin ajaminen jobissa
|
||||||
|
|
||||||
|
CI-kontin voi ajaa joko `container:`-direktiivillä (kaikki stepit kontissa)
|
||||||
|
tai `docker run --rm`:llä stepin sisällä (checkout natiivisti). Molemmat tavat
|
||||||
|
toimivat.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Tapa A: container:-direktiivi
|
||||||
|
jobs:
|
||||||
|
<työkalu>:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ${{ inputs.<image-name> }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: <owner>/gitea-ci-library
|
||||||
|
path: .ci
|
||||||
|
- name: Run <työkalu>
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir -p "reports/${GITHUB_SHA:0:8}/<suite>"
|
||||||
|
<komento> > "reports/${GITHUB_SHA:0:8}/<suite>/results.txt" 2>&1
|
||||||
|
EXIT=$?
|
||||||
|
echo "EXIT=${EXIT}" >> "${GITHUB_ENV}"
|
||||||
|
exit ${EXIT}
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Tapa B: docker run --rm stepin sisällä (kuten example-bats-tests.yml)
|
||||||
|
jobs:
|
||||||
|
<työkalu>:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: <owner>/gitea-ci-library
|
||||||
|
path: .ci
|
||||||
|
|
||||||
|
- name: Run <työkalu>
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
docker volume create ws-<suite>
|
||||||
|
tar c . | docker run --rm -i -v ws-<suite>:/data alpine tar x -C /data
|
||||||
|
mkdir -p "reports/${GITHUB_SHA:0:8}/<suite>"
|
||||||
|
set +e
|
||||||
|
docker run --rm \
|
||||||
|
-v ws-<suite>:/data \
|
||||||
|
--entrypoint bash ${{ inputs.<image-name> }} \
|
||||||
|
-c 'cd /data && <komento>' \
|
||||||
|
> "reports/${GITHUB_SHA:0:8}/<suite>/results.txt" 2>&1
|
||||||
|
EXIT=$?
|
||||||
|
docker volume rm ws-<suite> > /dev/null 2>&1
|
||||||
|
echo "EXIT=${EXIT}" >> "${GITHUB_ENV}"
|
||||||
|
exit ${EXIT}
|
||||||
|
|
||||||
|
- name: Publish <suite> reports
|
||||||
|
if: always()
|
||||||
|
run: bash .ci/scripts/publish-git-pages.sh <suite>
|
||||||
|
|
||||||
|
- name: Report status
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
if [ "${EXIT}" = "0" ]; then
|
||||||
|
bash .ci/scripts/report-status.sh success "<kuvaus>" <context> <suite>
|
||||||
|
else
|
||||||
|
bash .ci/scripts/report-status.sh failure "<kuvaus>" <context> <suite>
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
**Malli:** `example-bats-tests.yml` (tapa B).
|
||||||
|
|
||||||
## 5. Raporttitasot
|
## 5. Raporttitasot
|
||||||
|
|
||||||
@@ -177,11 +251,12 @@ tiedostot löytyvät nopeasti ja niiden rooli on selvillä:
|
|||||||
<komponentti>.ci-feature.yml ← feature-haaran reititin
|
<komponentti>.ci-feature.yml ← feature-haaran reititin
|
||||||
<komponentti>.ci-main.yml ← main-haaran reititin
|
<komponentti>.ci-main.yml ← main-haaran reititin
|
||||||
<komponentti>.<testityyppi>.yml ← yksittäinen testi tai operaatio
|
<komponentti>.<testityyppi>.yml ← yksittäinen testi tai operaatio
|
||||||
|
<komponentti>.ci-container-build-<kontti>.yml ← CI-kontin build-workflow
|
||||||
<komponentti>.gitea-env.conf ← komponenttikohtainen konfiguraatio
|
<komponentti>.gitea-env.conf ← komponenttikohtainen konfiguraatio
|
||||||
```
|
```
|
||||||
|
|
||||||
Single repossa `<komponentti>` jätetään pois — tiedostot ovat suoraan `ci-feature.yml`,
|
Single repossa `<komponentti>` jätetään pois — tiedostot ovat suoraan `ci-feature.yml`,
|
||||||
`ci-main.yml`, `<testityyppi>.yml`.
|
`ci-main.yml`, `<testityyppi>.yml`, `ci-container-build-<kontti>.yml`.
|
||||||
|
|
||||||
Monorepossa prefiksi pitää komponentin tiedostot yhdessä: `ls <komponentti>.*` löytää kaikki
|
Monorepossa prefiksi pitää komponentin tiedostot yhdessä: `ls <komponentti>.*` löytää kaikki
|
||||||
kerralla.
|
kerralla.
|
||||||
@@ -309,7 +384,7 @@ jobs:
|
|||||||
<testit>:
|
<testit>:
|
||||||
needs: [load-config, check-version]
|
needs: [load-config, check-version]
|
||||||
if: needs.check-version.outputs.artifact_exists != 'true'
|
if: needs.check-version.outputs.artifact_exists != 'true'
|
||||||
uses: ./.gitea/workflows/<komponentti>.<testi>.yml@main
|
uses: ./.gitea/workflows/<komponentti>.<testi>.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
with:
|
with:
|
||||||
env_json: ${{ needs.load-config.outputs.env_json }}
|
env_json: ${{ needs.load-config.outputs.env_json }}
|
||||||
@@ -405,6 +480,19 @@ Ei kahta eri komentoa samassa workflow'ssa.
|
|||||||
Kaikki provider-viittaukset käyttävät `@v1`-tagia. `@main` on vain providerin oman repon
|
Kaikki provider-viittaukset käyttävät `@v1`-tagia. `@main` on vain providerin oman repon
|
||||||
sisäiseen dogfood-käyttöön. Breaking changet kielletty — `v1`-rajapinta on pysyvä.
|
sisäiseen dogfood-käyttöön. Breaking changet kielletty — `v1`-rajapinta on pysyvä.
|
||||||
|
|
||||||
|
### Paikalliset `uses:` eivät käytä refiä
|
||||||
|
|
||||||
|
Gitea act runner v1.0.8 muodostaa paikallisista `uses: ./.gitea/workflows/*.yml@main`-viittauksista
|
||||||
|
epävalidin git-refin `main@<sha>`, joka aiheuttaa virheen `Revision invalid : reference must
|
||||||
|
be defined once at the beginning`.
|
||||||
|
|
||||||
|
Paikallisista `uses:`-direktiiveistä EI koskaan käytetä `@main`- tai muuta ref-päätettä:
|
||||||
|
- `uses: ./.gitea/workflows/chart.helm-lint.yml` ← oikein
|
||||||
|
- `uses: ./.gitea/workflows/chart.helm-lint.yml@main` ← väärin
|
||||||
|
|
||||||
|
Ilman refiä runner käyttää workflow'ta triggeröivästä commitista. Ulkoisten repojen
|
||||||
|
viittauksissa (`niko/...@v1`) pääte pysyy. Nämä resolvoidaan eri reittiä ja toimivat oikein.
|
||||||
|
|
||||||
### Exit-koodi on ainoa onnistumisen mittari (ADR 0008)
|
### Exit-koodi on ainoa onnistumisen mittari (ADR 0008)
|
||||||
|
|
||||||
Ei pipeä (`|`) komennon perässä — se syö exit-koodin. Käytä redirectiä (`> file 2>&1`).
|
Ei pipeä (`|`) komennon perässä — se syö exit-koodin. Käytä redirectiä (`> file 2>&1`).
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const PROJECT_ROOT = path.resolve(__dirname, '..', '..', '..');
|
|||||||
const MOCK_SCRIPT = path.join(PROJECT_ROOT, 'tests', 'helpers', 'mock-api.sh');
|
const MOCK_SCRIPT = path.join(PROJECT_ROOT, 'tests', 'helpers', 'mock-api.sh');
|
||||||
|
|
||||||
Before({ tags: '@mock' }, function () {
|
Before({ tags: '@mock' }, function () {
|
||||||
const out = execSync(`bash -c 'source "${MOCK_SCRIPT}" && mock_start && sleep 0.3 && curl -s -o /dev/null -w "%{http_code}" --max-time 3 http://localhost:18080/api/v1/repos/health/check'`, {
|
const out = execSync(`bash -c 'source "${MOCK_SCRIPT}" && mock_start && sleep 1 && curl -s -o /dev/null -w "%{http_code}" --max-time 3 http://localhost:18080/api/v1/repos/health/check'`, {
|
||||||
cwd: PROJECT_ROOT,
|
cwd: PROJECT_ROOT,
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
stdio: ['pipe', 'pipe', 'pipe'],
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
|
|||||||
@@ -24,6 +24,14 @@ _wait_port_free() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_wait_port_ready() {
|
||||||
|
local i=0
|
||||||
|
while ! lsof -ti ":$MOCK_PORT" >/dev/null 2>&1 && [ $i -lt 5 ]; do
|
||||||
|
sleep 0.2
|
||||||
|
i=$((i + 1))
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
mock_set_sequence() {
|
mock_set_sequence() {
|
||||||
MOCK_SEQUENCE_FILE=$(mktemp)
|
MOCK_SEQUENCE_FILE=$(mktemp)
|
||||||
echo "$1" | jq -c '.' > "$MOCK_SEQUENCE_FILE"
|
echo "$1" | jq -c '.' > "$MOCK_SEQUENCE_FILE"
|
||||||
@@ -55,7 +63,7 @@ mock_start() {
|
|||||||
nohup python3 "$(dirname "${BASH_SOURCE[0]}")/mock-server.py" "$MOCK_PORT" "$MOCK_CONFIG_FILE" "$MOCK_REQUEST_FILE" \
|
nohup python3 "$(dirname "${BASH_SOURCE[0]}")/mock-server.py" "$MOCK_PORT" "$MOCK_CONFIG_FILE" "$MOCK_REQUEST_FILE" \
|
||||||
</dev/null >/dev/null 2>&1 &
|
</dev/null >/dev/null 2>&1 &
|
||||||
MOCK_PID=$!
|
MOCK_PID=$!
|
||||||
sleep 0.5
|
_wait_port_ready
|
||||||
}
|
}
|
||||||
|
|
||||||
mock_stop() {
|
mock_stop() {
|
||||||
|
|||||||
Reference in New Issue
Block a user