Files
niko 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
Fix/ci kontin no internet vaatimus (#34)
Co-authored-by: moilanik <niko.moilanen@tietoevry.com>
Reviewed-on: #34
2026-06-20 14:36:42 +03:00

8.1 KiB

name, description, activation-gate, category, impact
name description activation-gate category impact
ci-container-build 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. 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. ci 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_dispatchei 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.txtCOPY --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):

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.

# 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.

# 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:

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ä