From 280b6b104a9f468bb3ca0f93a97d9a554aa3aebd Mon Sep 17 00:00:00 2001 From: moilanik Date: Sun, 21 Jun 2026 04:54:57 +0300 Subject: [PATCH] docker ja helm build context root monorepo ja in folder build --- .dockerignore | 20 ++ .gitea/workflows/ci-container-build-push.yml | 4 +- .gitea/workflows/docker-build-push.yml | 4 +- .gitea/workflows/helm-build-push.yml | 13 +- docs/ai-context.md | 3 +- skills/consumer-pipelines/SKILL.md | 244 ++++++++++++++++++- 6 files changed, 268 insertions(+), 20 deletions(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..7485fca --- /dev/null +++ b/.dockerignore @@ -0,0 +1,20 @@ +.git/ +.gitignore +node_modules/ +reports/ +coverage/ +.ai/ +.cursor/ +.vscode/ +tmp/ +.DS_Store +*.md +docs/ +guides/ +.simplecov +cucumber.js +package-lock.json +package.json +CURRENT_PROVIDER_VERSION +README.md +AGENTS.md diff --git a/.gitea/workflows/ci-container-build-push.yml b/.gitea/workflows/ci-container-build-push.yml index b1b9ac4..1091e6b 100644 --- a/.gitea/workflows/ci-container-build-push.yml +++ b/.gitea/workflows/ci-container-build-push.yml @@ -41,12 +41,14 @@ jobs: TAG="${{ inputs.tag }}" NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ) + CONTEXT_DIR=$(dirname "${DOCKERFILE}") docker build \ --label "git.commit=${{ github.sha }}" \ --label "git.commitBy=${{ github.actor }}" \ --label "build.date=${NOW}" \ -f "${DOCKERFILE}" \ - -t "${IMAGE_NAME}:${TAG}" . + -t "${IMAGE_NAME}:${TAG}" \ + "${CONTEXT_DIR}" FULL_IMAGE="${REGISTRY}/${IMAGE_NAME}:${TAG}" echo "Pushing ${FULL_IMAGE} ..." diff --git a/.gitea/workflows/docker-build-push.yml b/.gitea/workflows/docker-build-push.yml index 230d328..8d32334 100644 --- a/.gitea/workflows/docker-build-push.yml +++ b/.gitea/workflows/docker-build-push.yml @@ -52,13 +52,15 @@ jobs: REGISTRY_HOST="${REGISTRY%%/*}" NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ) + CONTEXT_DIR=$(dirname "${DOCKERFILE}") docker build \ --label "git.commit=${{ github.sha }}" \ --label "git.commitBy=${{ github.actor }}" \ --label "build.date=${NOW}" \ -f "${DOCKERFILE}" \ -t "${IMAGE}:${VERSION}" \ - -t "${IMAGE}:latest" . + -t "${IMAGE}:latest" \ + "${CONTEXT_DIR}" FULL_IMAGE="${REGISTRY}/${IMAGE}:${VERSION}" echo "Pushing ${FULL_IMAGE} ..." diff --git a/.gitea/workflows/helm-build-push.yml b/.gitea/workflows/helm-build-push.yml index bec4aab..133827c 100644 --- a/.gitea/workflows/helm-build-push.yml +++ b/.gitea/workflows/helm-build-push.yml @@ -8,10 +8,6 @@ on: version: required: true type: string - chart_path: - required: false - type: string - default: '.' secrets: GITEA_TOKEN: required: true @@ -26,7 +22,7 @@ env: HELM_REGISTRY: ${{ fromJson(inputs.env_json).HELM_REGISTRY || '' }} HELM_UI_URL: ${{ fromJson(inputs.env_json).HELM_UI_URL || '' }} GIT_TAG_PREFIX: ${{ fromJson(inputs.env_json).GIT_TAG_PREFIX || '' }} - CHART_PATH: ${{ inputs.chart_path }} + CHART_FILE: ${{ fromJson(inputs.env_json).VERSION_FILE || 'Chart.yaml' }} VERSION: ${{ inputs.version }} concurrency: @@ -53,8 +49,9 @@ jobs: - name: Package Helm chart run: | - helm dependency update "${CHART_PATH}" - helm package "${CHART_PATH}" \ + CHART_DIR=$(dirname "${CHART_FILE}") + helm dependency update "${CHART_DIR}" + helm package "${CHART_DIR}" \ --version "${VERSION}" \ --app-version "${VERSION}" \ --destination /tmp/helm-packages @@ -74,7 +71,7 @@ jobs: - name: Report status with UI link if: success() && env.HELM_UI_URL != '' run: | - CHART_NAME=$(grep '^name:' "${CHART_PATH}/Chart.yaml" | awk '{print $2}') + CHART_NAME=$(grep '^name:' "${CHART_FILE}" | awk '{print $2}') UI_URL="${HELM_UI_URL}/${CHART_NAME}/${VERSION}" bash .ci/scripts/report-status.sh success "Helm chart ${VERSION}" ci-helm-build-push "" "$UI_URL" diff --git a/docs/ai-context.md b/docs/ai-context.md index 0047e28..cc9d3a4 100644 --- a/docs/ai-context.md +++ b/docs/ai-context.md @@ -37,7 +37,7 @@ kuuluu `git-pages/docs/`-alle, ei juuren `docs/`-kansioon. | `git-pages/` | Raporttien hostaus (Helm-chartti) | | `tests/` | Bats-testit skripteille | -### Provider workflowt (5 kpl) +### Provider workflowt (6 kpl) | Workflow | Input | Output | Kuvaus | |---|---|---|---| @@ -46,6 +46,7 @@ kuuluu `git-pages/docs/`-alle, ei juuren `docs/`-kansioon. | `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+) | +| `helm-build-push.yml` | `env_json`, `version` | — | Pakkaa + puskea Helm chartin OCI-registryyn, tagittaa commitin. **Tekninen velka:** asentaa node.js:n runtime-vaiheessa (`apk add --no-cache nodejs` ennen checkouttia) koska `alpine/helm`-kontissa ei ole nodea. Rikkoo Offline Container -periaatetta. Ratkaistaan myöhemmin: proper multi-tool CI-kontti (helm + nodejs + git) docker hubiin. Ei consumerin ongelma. | ### Example-tiedostot (consumer-referenssi) diff --git a/skills/consumer-pipelines/SKILL.md b/skills/consumer-pipelines/SKILL.md index 542fc0c..c41a93a 100644 --- a/skills/consumer-pipelines/SKILL.md +++ b/skills/consumer-pipelines/SKILL.md @@ -123,6 +123,88 @@ ajetaan kontin *sisällä* — myös `actions/checkout@v4`. Se on JavaScript-act joka vaatii sekä `nodejs` että `git`. Varmista että CI-kontin Dockerfilessä on molemmat — muuten checkout ei toimi ja pipeline failaa. +### 4.4 Build-konteksti, `.dockerignore` ja `COPY` + +**Build-konteksti** on aina tiedoston (Dockerfile, Chart.yaml) oman hakemiston +juuri (`dirname "${DOCKERFILE}"` / `dirname "${CHART_FILE}"`). Kaikki +suhteelliset polut — ignore-tiedosto, `COPY`, `ADD` — ovat suhteessa tähän +kontekstiin. + +| Tiedosto | Konteksti | Ignore-tiedosto | Käyttö | +|---|---|---|---| +| `Dockerfile` | `.` | `./.dockerignore` | `docker build` / `COPY src/ src/` | +| `api/Dockerfile` | `api/` | `api/.dockerignore` | `docker build` / `COPY src/ src/` | +| `Chart.yaml` (`VERSION_FILE`) | `.` | `./.helmignore` | `helm package` | +| `api/Chart.yaml` (`VERSION_FILE`) | `api/` | `api/.helmignore` | `helm package` | + +Helm chartin polku luetaan confin `VERSION_FILE`-kentästä — sama rivi jota +`check-version.yml` käyttää version lähteenä. Yksi conf-rivi ohjaa molempia: +sekä versionlaskentaa että chartin sijaintia. + +**Mitä ignore-tiedosto sisältää:** Kaikki mikä EI ole konttiin tai chart-pakettiin +tarkoitettua koodia tai resurssia, ON oltava ignore-tiedostossa: + +- Git- ja CI-historia (`.git/`, `.gitea/`, `.github/`) +- Testikoodi, testidata, testiraportit (`tests/`, `reports/`, `coverage/`) +- Dokumentaatio (`docs/`, `guides/`, `*.md`, `CHANGELOG`, `README`) +- Editori- ja työkalukonfiguraatio (`.vscode/`, `.cursor/`, `.idea/`, `.DS_Store`) +- Riippuvuudet jotka asennetaan Dockerfilessä (`node_modules/`) +- Väliaikaistiedostot (`tmp/`, `*.log`) +- Projektikohtaiset konfiguraatiot (`.env`, `*.conf`, `CURRENT_PROVIDER_VERSION`) + +**Miksi:** Build-kontekstin koko vaikuttaa suoraan `docker build` -nopeuteen. +Raskas konteksti (etenkin `.git/` ja `node_modules/`) hidastaa buildia ja +kuluttaa runnerin resursseja turhaan. Ylimääräiset tiedostot kontissa ovat +**tietoturvariski** — tokenit, `.env` ja sensitiivinen data voivat päätyä +kontin layeriin jos `.dockerignore` ei ole kattava. + +### 4.5 `COPY`-kuri — kopioi vain tarvittava + +`COPY . .` on kielletty. Jokainen `COPY` kopioi vain tarvittavat tiedostot +tai hakemistot: + +```dockerfile +# VÄÄRIN +COPY . . + +# OIKEIN +COPY package.json package-lock.json ./ +COPY src/ src/ +COPY public/ public/ +``` + +**Miksi:** +- Layer-cache: `COPY . .` rikkoo välimuistin — mikä tahansa muutos + tiedostossa tyhjentää koko layerin +- Tietoturva: konttiin voi päätyä ylimääräisiä tiedostoja vaikka + `.dockerignore` olisi kattava (unohtunut ignore-rivi, uusi työkalu + joka luo tiedostoja build-kontekstiin) +- Luettavuus: `COPY . .` ei kerro mitä kontti todella sisältää +- Kontin koko: eksplisiittinen `COPY` pitää image-koon kurissa + +### 4.6 `.helmignore` — pidä chart-paketti siistinä + +`helm package` käyttää `.helmignore`-tiedostoa samalla periaatteella kuin +`docker build` käyttää `.dockerignore`a: + +- Chart-hakemisto luetaan confin `VERSION_FILE`-kentästä (`dirname "${VERSION_FILE}"`) +- ignore-tiedosto luetaan chart-hakemiston juuresta (sama konteksti kuin + `Chart.yaml`, ks. 4.4) +- Kaikki turha (testit, docs, git, CI-konffit, kuvat) on poissuljettava +- Jos `.helmignore` puuttuu, `helm package` paketoi mukaan kaikki + chart-hakemiston tiedostot — turhaa bulkkia registryyn + +**`.helmignore` on pakollinen** jokaiselle chartille. Minimisisältö: + +``` +.git/ +.gitignore +tests/ +docs/ +*.md +.DS_Store +``` + ## 5. Raporttitasot Testi tuottaa raportin `reports//`-hakemistoon. Yksi `ci-report.sh`-kutsu hoitaa sekä @@ -257,6 +339,7 @@ Pakkaa ja pushee Helm-chartin OCI-registryyn. Käyttää `alpine/helm`-konttia. ```yaml HELM_REGISTRY: gitea.app.keskikuja.site/niko +VERSION_FILE: platform-helm/Chart.yaml # chart-hakemisto + versionlähde ``` **Käyttö reitittimessä:** @@ -270,20 +353,163 @@ helm-build-push: with: env_json: ${{ needs.load-config.outputs.env_json }} version: ${{ needs.check-version.outputs.version }} - # chart_path: '.' # oletus, vaihda jos Chart.yaml on alihakemistossa ``` -**Vanhentunut käytäntö:** Nykyinen `helm-build-push.yml` asentaa node.js:n -lennossa `apk add --no-cache nodejs` ennen checkouttia — tämä rikkoo -Offline Container -vaatimusta (4.1). - -**Korjaustoimenpide:** Rakenna custom CI-kontti `ci-container-build`-skillillä -jossa on helm + nodejs + git (katso pre-cache-esimerkit `REFERENCE.md`:stä), -päivitä workflow'n `container: image:` osoittamaan omaan konttiin, ja poista -runtime-apk. +Chart-hakemisto johdetaan `VERSION_FILE`-polusta: `dirname "${VERSION_FILE}"`. +Jos `VERSION_FILE` on `Chart.yaml`, konteksti on juuri. Jos `platform-helm/Chart.yaml`, +konteksti on `platform-helm/`. **Yksittäisten Helm-UI-linkkien raportointi:** `HELM_UI_URL` on tarkoitettu yleiselle registry UI:lle — provider muodostaa linkin `${HELM_UI_URL}/${CHART_NAME}/${VERSION}` automaattisesti. Tarkka input/secret-lista: `docs/workflows.md`. + +## 11. Multi-artifact monorepo -komponentti + +Yksi monorepo-komponentti voi tuottaa useita artefakteja (esim. Docker image ++ Helm chart). Kukin artefakti on **omassa reitittimessään** — ei yhtä +monoliittista pipelinea. Tämä on tietoinen arkkitehtuurivalinta: + +- Reitittimet ovat itsenäisiä: eri `paths:`-triggerit, eri tagit, eri confit +- Yksi commit voi triggeröidä molemmat rinnakkain +- Yhden artefaktin build tai testi ei estä toista + +### Esimerkki: `platform-helm` joka tuottaa Docker-imagen ja Helm chartin + +``` +.gitea/workflows/ +├── platform-helm.ci-main.yml # Docker build & push +├── platform-helm.gitea-env.conf # Docker-konffi +├── platform-helm.helm-ci-main.yml # Helm build & push +├── platform-helm.helm-gitea-env.conf # Helm-konffi +├── platform-helm.helm-chart-lint.yml # Chart-testi +└── platform-helm.ci-container-build-helm.yml # CI-kontin build +``` + +### `platform-helm.gitea-env.conf` (Docker) + +```ini +DOCKER_REGISTRY=gitea.app.keskikuja.site/niko +DOCKER_IMAGE_NAME=platform-helm +GIT_TAG_PREFIX=platform-helm/ +``` + +### `platform-helm.helm-gitea-env.conf` (Helm) + +```ini +HELM_REGISTRY=gitea.app.keskikuja.site/niko +VERSION_FILE=platform-helm/Chart.yaml +GIT_TAG_PREFIX=chart/ +``` + +### Reitittimet + +**`platform-helm.ci-main.yml`** — Docker-buildi, testit, oma tagi: + +```yaml +name: platform-helm CI Main +on: + push: + branches: [main] + paths: + - platform-helm/** + - .gitea/workflows/platform-helm.* + +jobs: + load-config: + uses: OWNER/gitea-ci-library/.gitea/workflows/config-provider.yml@v1 + secrets: inherit + with: + config_path: .gitea/workflows/platform-helm.gitea-env.conf + + check-version: + needs: [load-config] + uses: OWNER/gitea-ci-library/.gitea/workflows/check-version.yml@v1 + secrets: inherit + with: + env_json: ${{ needs.load-config.outputs.env_json }} + + test: + needs: [load-config, check-version] + uses: ./.gitea/workflows/platform-helm.sbom-lint.yml + secrets: inherit + with: + env_json: ${{ needs.load-config.outputs.env_json }} + + build-push: + needs: [load-config, check-version, test] + if: needs.check-version.outputs.artifact_exists == 'false' + uses: OWNER/gitea-ci-library/.gitea/workflows/docker-build-push.yml@v1 + secrets: inherit + with: + env_json: ${{ needs.load-config.outputs.env_json }} + version: ${{ needs.check-version.outputs.version }} + + report-summary: + needs: [load-config, test, build-push] + if: always() + uses: OWNER/gitea-ci-library/.gitea/workflows/report-summary.yml@v1 + with: + env_json: ${{ needs.load-config.outputs.env_json }} + suites: '' +``` + +**`platform-helm.helm-ci-main.yml`** — Helm-buildi, chart-testi, oma tagi: + +```yaml +name: platform-helm Helm CI Main +on: + push: + branches: [main] + paths: + - platform-helm/** + - .gitea/workflows/platform-helm.helm* + +jobs: + load-config: + uses: OWNER/gitea-ci-library/.gitea/workflows/config-provider.yml@v1 + secrets: inherit + with: + config_path: .gitea/workflows/platform-helm.helm-gitea-env.conf + + check-version: + needs: [load-config] + uses: OWNER/gitea-ci-library/.gitea/workflows/check-version.yml@v1 + secrets: inherit + with: + env_json: ${{ needs.load-config.outputs.env_json }} + + chart-lint: + needs: [load-config, check-version] + uses: ./.gitea/workflows/platform-helm.helm-chart-lint.yml + secrets: inherit + with: + env_json: ${{ needs.load-config.outputs.env_json }} + + helm-build-push: + needs: [load-config, check-version, chart-lint] + if: needs.check-version.outputs.artifact_exists == 'false' + uses: OWNER/gitea-ci-library/.gitea/workflows/helm-build-push.yml@v1 + secrets: inherit + with: + env_json: ${{ needs.load-config.outputs.env_json }} + version: ${{ needs.check-version.outputs.version }} + + report-summary: + needs: [load-config, chart-lint, helm-build-push] + if: always() + uses: OWNER/gitea-ci-library/.gitea/workflows/report-summary.yml@v1 + with: + env_json: ${{ needs.load-config.outputs.env_json }} + suites: '' +``` + +### Säännöt + +- Jokaisella artefaktilla on oma reititin, oma conf, omat testit +- Conf-tiedoston nimi erottaa artefaktit: `.gitea-env.conf` vs + `.helm-gitea-env.conf` +- `.helm-`-prefiksi erottaa Helm-artefaktin tiedostot +- `GIT_TAG_PREFIX` pitää tagit erillään: `platform-helm/1.2.3` vs `chart/1.2.3` +- Molemmat reitittimet voivat triggeröityä samasta commitista -- 2.52.0