2bef079d03
CI Main / Load example-gitea-env.conf to pipeline env (push) Successful in 22s
CI Main / Check existing artifact (push) Successful in 18s
acc-tests Cucumber test report
unit-tests Bats test report
CI Main / Cucumber tests (push) Successful in 1m25s
CI Main / Bats tests (push) Successful in 1m26s
ci-docker-build-push Docker build & push 0.2.19 OK
CI Main / Build & Push Docker (push) Successful in 47s
CI Main / Report Summary (push) Successful in 6s
CI Main / Move provider version tag (push) Successful in 16s
Co-authored-by: moilanik <niko.moilanen@tietoevry.com> Reviewed-on: #34
228 lines
8.1 KiB
Markdown
228 lines
8.1 KiB
Markdown
---
|
|
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ää.
|
|
|
|
## Offline-periaate (DoD)
|
|
|
|
CI-kontin **Definition of Done**:
|
|
|
|
> Kontti ei lataa mitään pipeline-vaiheessa (`workflow run` -stepit) eikä kontin
|
|
> runtime-prosessissa (`container:` / `docker run`). Kaikki riippuvuudet
|
|
> (kielikohtaiset paketit, työkalut, binäärit) on joko:
|
|
> - Pre-cachattu kontin **build-vaiheessa** Dockerfilessä, TAI
|
|
> - Kopioitu multi-stage buildilla toisesta imagesta (`COPY --from`)
|
|
>
|
|
> Ainoa sallittu lataushetki on `docker build`. Sen jälkeen kontti toimii
|
|
> ilman verkkoyhteyttä.
|
|
|
|
**Miksi:** Toistettavuus, air gap -yhteensopivuus, nopeus. Pipeline ei saa
|
|
epäonnistua sen takia että ulkoinen registry on alhaalla tai että `go mod download`
|
|
joutuu latamaan 100 modulia jokaisella testiajolla.
|
|
|
|
**Kielikohtaiset pre-cachet:** Jos kontissa ajetaan kielikohtaista testiä
|
|
(Go, Java, Node, Python, ...), kaikki kielikohtaiset riippuvuudet on
|
|
pre-cachattava Dockerfilessä build-vaiheessa:
|
|
- Go: `COPY go.mod go.sum ./` → `RUN go mod download`
|
|
- Java/Maven: `COPY pom.xml ./` → `RUN mvn dependency:go-offline`
|
|
- Node: `COPY package.json package-lock.json ./` → `RUN npm ci --omit=dev`
|
|
- Python: `COPY requirements.txt ./` → `RUN pip wheel --wheel-dir=/wheels -r requirements.txt` → `COPY --from` käyttöön
|
|
|
|
## 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.
|
|
**Kaikki riippuvuudet ladataan build-vaiheessa — kontti on täysin itseriittoinen.**
|
|
|
|
```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__
|
|
|
|
# Tapa B: Build-vaiheen curl-lataus
|
|
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
|
|
|
|
# Tapa C: Multi-stage + kielikohtainen pre-cache
|
|
FROM __BASE_IMAGE__:__VERSION__ AS deps
|
|
COPY go.mod go.sum ./
|
|
RUN go mod download
|
|
|
|
FROM deps AS build
|
|
COPY . .
|
|
RUN go test -c -o /tmp/test.bin ./...
|
|
|
|
FROM __BASE_IMAGE__:__VERSION__
|
|
COPY --from=deps /go/pkg/mod /go/pkg/mod
|
|
COPY --from=build /tmp/test.bin /usr/local/bin/test
|
|
```
|
|
|
|
`COPY --from` on kevyempi (ei curl-asennusta). `curl` (Tapa B) on sallittu
|
|
vain build-vaiheessa — `apk del curl` poistaa työkalun ennen runtimea.
|
|
Tapa C pre-cacheaa kielikohtaiset riippuvuudet ja tuottaa täysin
|
|
offline-runtime-kontin.
|
|
|
|
## Testaus ennen julkaisua
|
|
|
|
Konttia ei saa pushata registryyn ennen kuin se on validoitu.
|
|
|
|
### 1. Aja testit kontin sisällä
|
|
|
|
Testit on ajettava **kontin sisällä**, ei suoraan lokaalilla koneella.
|
|
|
|
```bash
|
|
# OIKEIN — kontin sisällä
|
|
docker build -t ci-tyokalu:test .
|
|
docker run --rm -v "$(pwd):/repo" -w /repo ci-tyokalu:test bash -c 'bats tests/'
|
|
|
|
# VÄÄRIN — lokaalit binäärit vs kontti
|
|
bats tests/ # eri bash/työkalut kuin kontissa
|
|
bashcov -- bats tests/ # eri ruby-versio kuin kontissa
|
|
```
|
|
|
|
Lokaali ympäristö (macOS, eri kirjastoversiot) poikkeaa aina kontista.
|
|
Testi voi mennä läpi lokaalissa mutta failata CI:ssä, tai päinvastoin.
|
|
|
|
### 2. Fragile-testien seulonta (10x ajo)
|
|
|
|
Aja koko testipaketti **10 kertaa peräkkäin** kontin sisällä ennen pushausta:
|
|
|
|
```bash
|
|
for i in $(seq 1 10); do
|
|
echo "=== RUN $i ==="
|
|
docker run --rm -v "$(pwd):/repo" -w /repo ci-tyokalu:test \
|
|
bash -c 'bats tests/' || exit 1
|
|
done
|
|
```
|
|
|
|
Jos yksikin ajo failaa, kontissa on fragile testi — korjaa ennen pushausta.
|
|
Fragile testit syövät devaukseen käytettyä aikaa turhilla uusinta-ajoilla.
|
|
|
|
## 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 lataa mitään pipeline- tai runtime-vaiheessa — kaikki lataukset kuuluvat `docker build` -vaiheeseen (Offline-periaate)
|
|
- Älä jätä kielikohtaisia riippuvuuksia pre-cachaamatta — `go mod download`, `npm install`, `mvn dependency:go-offline` jne. ajetaan Dockerfilessä, ei pipelinessä
|