Compare commits

..

1 Commits

Author SHA1 Message Date
niko dd9cdf70b6 Featuer/gitops extra command (#47)
CI Main / Config load (push) Successful in 1m48s
CI Main / Latest versio (push) Successful in 1m38s
unit-tests Bats test report
CI Main / Bats tests (push) Successful in 2m15s
acc-tests Cucumber test report
CI Main / Cucumber tests (push) Successful in 2m46s
ci-docker-build-push Docker push 0.2.35
CI Main / Build & Push Docker (push) Successful in 40s
gitops/gitea-ci-library GitOps: 0.2.35
CI Main / GitOps (push) Successful in 1m34s
CI Main / Report Summary (push) Successful in 3s
CI Main / Move provider version tag (push) Successful in 11s
Co-authored-by: moilanik <niko.moilanen@tietoevry.com>
Reviewed-on: #47
2026-06-27 05:20:09 +03:00
7 changed files with 125 additions and 24 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ on:
jobs: jobs:
build-push: build-push:
runs-on: ubuntu-latest runs-on: docker
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
+2 -2
View File
@@ -32,7 +32,7 @@ concurrency:
jobs: jobs:
build-push: build-push:
runs-on: ubuntu-latest runs-on: docker
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -91,7 +91,7 @@ jobs:
fi fi
tag-commit: tag-commit:
runs-on: ubuntu-latest runs-on: docker
needs: [build-push] needs: [build-push]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
+14 -1
View File
@@ -17,6 +17,9 @@ on:
GITOPS_REPO: GITOPS_REPO:
required: true required: true
type: string type: string
GITOPS_EXTRA_CMD:
required: false
type: string
secrets: secrets:
GITOPS_DISPATCH_TOKEN: GITOPS_DISPATCH_TOKEN:
required: true required: true
@@ -34,6 +37,7 @@ env:
GITOPS_SOURCE_COMMIT: ${{ github.sha }} GITOPS_SOURCE_COMMIT: ${{ github.sha }}
GITEA_API_URL: ${{ fromJson(inputs.env_json).GITEA_API_URL }} GITEA_API_URL: ${{ fromJson(inputs.env_json).GITEA_API_URL }}
GITOPS_TAG_PREFIX: ${{ fromJson(inputs.env_json).GIT_TAG_PREFIX || '' }} GITOPS_TAG_PREFIX: ${{ fromJson(inputs.env_json).GIT_TAG_PREFIX || '' }}
GITOPS_EXTRA_CMD: ${{ inputs.GITOPS_EXTRA_CMD || '' }}
GITOPS_WORKFLOW: gitops-service.yaml GITOPS_WORKFLOW: gitops-service.yaml
GITOPS_DISPATCH_TIMEOUT: 30 GITOPS_DISPATCH_TIMEOUT: 30
@@ -49,19 +53,28 @@ jobs:
ID=$(date +%s | md5sum | head -c 8) ID=$(date +%s | md5sum | head -c 8)
echo "dispatch_id=$ID" >> "$GITHUB_OUTPUT" echo "dispatch_id=$ID" >> "$GITHUB_OUTPUT"
- name: Resolve commit author
id: author
run: |
echo "name=$(git log -1 --format='%an')" >> "$GITHUB_OUTPUT"
echo "email=$(git log -1 --format='%ae')" >> "$GITHUB_OUTPUT"
- name: Dispatch to GitOps repo - name: Dispatch to GitOps repo
env: env:
GITEA_TOKEN: ${{ secrets.GITOPS_DISPATCH_TOKEN }} GITEA_TOKEN: ${{ secrets.GITOPS_DISPATCH_TOKEN }}
run: | run: |
INPUTS=$(jq -nc \ INPUTS=$(jq -nc \
--arg dispatch_id "${{ steps.gen.outputs.dispatch_id }}" \ --arg dispatch_id "${{ steps.gen.outputs.dispatch_id }}" \
--arg author_name "${{ steps.author.outputs.name }}" \
--arg author_email "${{ steps.author.outputs.email }}" \
--arg file "$GITOPS_FILE" \ --arg file "$GITOPS_FILE" \
--arg yq_tpl "$GITOPS_YQ_TPL" \ --arg yq_tpl "$GITOPS_YQ_TPL" \
--arg version "$GITOPS_VERSION" \ --arg version "$GITOPS_VERSION" \
--arg source_repo "$GITOPS_SOURCE_REPO" \ --arg source_repo "$GITOPS_SOURCE_REPO" \
--arg source_commit "$GITOPS_SOURCE_COMMIT" \ --arg source_commit "$GITOPS_SOURCE_COMMIT" \
--arg git_tag_prefix "${GITOPS_TAG_PREFIX:-}" \ --arg git_tag_prefix "${GITOPS_TAG_PREFIX:-}" \
'{dispatch_id: $dispatch_id, file: $file, yq_tpl: $yq_tpl, version: $version, source_repo: $source_repo, source_commit: $source_commit, git_tag_prefix: $git_tag_prefix}') --arg extra_cmd "${GITOPS_EXTRA_CMD:-}" \
'{dispatch_id: $dispatch_id, author_name: $author_name, author_email: $author_email, file: $file, yq_tpl: $yq_tpl, version: $version, source_repo: $source_repo, source_commit: $source_commit, git_tag_prefix: $git_tag_prefix, extra_cmd: $extra_cmd}')
curl -s -X POST \ curl -s -X POST \
"${GITEA_API_URL}/api/v1/repos/${GITOPS_REPO}/actions/workflows/${GITOPS_WORKFLOW}/dispatches" \ "${GITEA_API_URL}/api/v1/repos/${GITOPS_REPO}/actions/workflows/${GITOPS_WORKFLOW}/dispatches" \
-H "Authorization: token $GITEA_TOKEN" \ -H "Authorization: token $GITEA_TOKEN" \
+60 -14
View File
@@ -141,7 +141,7 @@ kubectl create secret generic act-runner-token \
### 4. Helm install / upgrade ### 4. Helm install / upgrade
Menee samalla komennolla. Menee samalla komennolla.
> Muista asettaa variables ennen ajoa. > Muista asettaa variables ennen ajoa.
@@ -151,58 +151,102 @@ ja sitä kautta Gitea ei tarvitse päivityksessä mitään temppuja.
Päivityksen jälkeen muista tappaa pod (käynnistyy automaattisesti uudelleen), että lataa varmasti kaikki uudesta. Sillä ConfigMap tms eivät lataudu Päivityksen jälkeen muista tappaa pod (käynnistyy automaattisesti uudelleen), että lataa varmasti kaikki uudesta. Sillä ConfigMap tms eivät lataudu
mikäli pod jatkaa ajamista. mikäli pod jatkaa ajamista.
Klusterissa on kaksi StatefulSetiä, joilla on eri labelit:
- **`act-runner`** — yleisrunneri (label `ubuntu-latest`). DinD-sidecar on olemassa mutta idle — `require_docker: false` estää runneria käyttämästä sitä.
- **`act-runner-docker`** — Docker-buildien runneri (label `docker`). DinD on aktiivinen, `require_docker: true`.
Vain `docker-build-push.yml` ja `ci-container-build-push.yml` käyttävät `docker`-labelia.
Kaikki muut workflowt (testit, lintit, helm-publish, gitops-dispatch) ajetaan `ubuntu-latest`-runnerilla.
Steppien suoritus ei mene Docker Daemonin läpi, joten konekielisiä kontteja luodaan suoraan K8s-runtimella.
```bash ```bash
helm repo add gitea https://dl.gitea.com/charts helm repo add gitea https://dl.gitea.com/charts
helm repo update helm repo update
# 1. Yleisrunneri (DinD idle)
helm upgrade --install act-runner gitea/actions \ helm upgrade --install act-runner gitea/actions \
--set enabled=true \ --set enabled=true \
--set giteaRootURL="$GITEA_URL" \ --set giteaRootURL="$GITEA_URL" \
--set existingSecret=act-runner-token \ --set existingSecret=act-runner-token \
--set existingSecretKey=token \ --set existingSecretKey=token \
--set statefulset.replicas=3 \ --set statefulset.replicas=2 \
--set statefulset.runner.tag=1.0.8 \ --set statefulset.runner.tag=1.0.8 \
--set statefulset.dind.tag=29.5.2-dind \ --set statefulset.dind.tag=29.5.2-dind \
--set statefulset.dind.resources.requests.memory=250Mi \
--set statefulset.dind.resources.limits.memory=750Mi \
--set-string 'statefulset.runner.config=log: --set-string 'statefulset.runner.config=log:
level: info level: info
cache: cache:
enabled: false enabled: true
container: container:
require_docker: true require_docker: false' \
docker_timeout: 300s' \
--namespace "$GITEA_ACTIONS_NAMESPACE" \ --namespace "$GITEA_ACTIONS_NAMESPACE" \
--create-namespace --create-namespace
```
path escapes from parent -bugi korjattiin Docker 29.5.2:ssa. Tämän teko aikana default on 29.5.1 — juuri tämän alle jäävä versio. # 2. Docker-runner (DinD)
helm upgrade --install act-runner-docker gitea/actions \
--set enabled=true \
--set giteaRootURL="$GITEA_URL" \
--set existingSecret=act-runner-token \
--set existingSecretKey=token \
--set statefulset.replicas=1 \
--set statefulset.runner.tag=1.0.8 \
--set statefulset.dind.tag=29.5.2-dind \
--set statefulset.dind.resources.requests.memory=250Mi \
--set statefulset.dind.resources.limits.memory=750Mi \
--set-string 'statefulset.runner.config=log:
level: info
cache:
enabled: true
container:
require_docker: true
docker_timeout: 300s
runner:
labels:
- "docker:docker://catthehacker/ubuntu:act-latest"' \
--namespace "$GITEA_ACTIONS_NAMESPACE"
```
`path escapes from parent` -bugi korjattiin Docker 29.5.2:ssa. Tämän teko aikana default on 29.5.1 — juuri tämän alle jäävä versio.
Oletus-lokitaso on `debug` — suositeltu `info`. Näkee jobien aloitukset ja valmistumiset ilman konttikerrosten purkua (Downloading/Extracting-spämmiä). `debug` on tarpeen vain vianselvityksessä. Oletus-lokitaso on `debug` — suositeltu `info`. Näkee jobien aloitukset ja valmistumiset ilman konttikerrosten purkua (Downloading/Extracting-spämmiä). `debug` on tarpeen vain vianselvityksessä.
`cache.enabled: true` nappaa image-cachen käyttöön — ilman sitä jokainen ajo lataa konttikuvat uudestaan.
#### Docker (DinD) #### Docker (DinD)
Helm chart deployaa DinD:n init-sidecarina (`docker:dind` samassa podissa). > **Huomio:** Gitea 1.26.x ei tue vielä label-pohjaista runner-valintaa.
`require_docker: true` kytkee jobit siihen — erillistä DinD-asennusta ei tarvita. > `runs-on: ubuntu-latest`-jobi saattaa päätyä `docker`-labeliselle runnerille.
> Bugi on tunnettu Gitean FAQ:ssa — korjaus tulossa myöhemmässä versiossa.
> Katso: [docs.gitea.com/usage/actions/faq](https://docs.gitea.com/usage/actions/faq)
**DinD-tag pinottu:** `29.5.2-dind` (ei chart-oletusta). Docker 29.5.1 aiheuttaa act-runnerissa Helm chart deployaa DinD:n init-sidecarina (`docker:dind` samassa podissa).
`path escapes from parent` -virheen job-kontin käynnistyksessä. Molemmissa StatefulSetissä on DinD-sidecar, mutta:
- **`act-runner`**: `require_docker: false` → runner ei käytä DinD:tä lainkaan, steppien suoritus menee suoraan K8s-runtimella
- **`act-runner-docker`**: `require_docker: true` → runner luo steppikontit DinD:n kautta (tarvitaan `docker build` -komentoja varten)
**DinD-tag pinottu:** `29.5.2-dind` molemmissa (ei chart-oletusta `29.5.1-dind`). Docker 29.5.1 aiheuttaa act-runnerissa
`path escapes from parent` -virheen job-kontin käynnistyksessä sekä `mkdirat var/run: file exists` -virheen tiedostojen kopioinnissa.
Maven/npm-ajot käyttävät vain workflow'n `container:`-imagea; DinD tarvitaan vasta Docker-buildissä. Maven/npm-ajot käyttävät vain workflow'n `container:`-imagea; DinD tarvitaan vasta Docker-buildissä.
### 3. Varmista ### 5. Varmista
```bash ```bash
kubectl get pods -n gitea-actions kubectl get pods -n gitea-actions
# → act-runner-runner-0 Running # → act-runner-runner-0 Running
# → act-runner-docker-runner-0 Running
kubectl exec -n gitea-actions act-runner-runner-0 -c dind -- docker version kubectl exec -n gitea-actions act-runner-docker-runner-0 -c dind -- docker version
# → Server Version: 29.5.2 (tai uudempi) # → Server Version: 29.5.2 (tai uudempi)
``` ```
Gitean puolella runner ilmestyy Active-tilaan pienellä viiveellä: Gitean puolella runnerit ilmestyvät Active-tilaan pienellä viiveellä:
``` ```
Site Admin → Actions → Runners (tai Org → Settings → Actions → Runners) Site Admin → Actions → Runners (tai Org → Settings → Actions → Runners)
# → act-runner-runner-0 Active ubuntu-latest # → act-runner-runner-0 Active ubuntu-latest
# → act-runner-docker-runner-0 Active docker
``` ```
Tämän jälkeen `.gitea/workflows/ci.yml` triggeröityy automaattisesti pushista. Tämän jälkeen `.gitea/workflows/ci.yml` triggeröityy automaattisesti pushista.
@@ -279,5 +323,7 @@ Tarkka asennus: [skills/gitops-update/SKILL.md](skills/gitops-update/SKILL.md)
| `existingSecret` | Kubernetes secretin nimi, jossa token | | `existingSecret` | Kubernetes secretin nimi, jossa token |
| `existingSecretKey` | Avain secretin sisällä | | `existingSecretKey` | Avain secretin sisällä |
| `statefulset.dind.tag` | DinD-image tag (`29.5.2-dind` minimi) | | `statefulset.dind.tag` | DinD-image tag (`29.5.2-dind` minimi) |
| `statefulset.dind.resources.requests.memory` | DinD muistirequest (suositus `250Mi`) |
| `statefulset.dind.resources.limits.memory` | DinD muistilimitti (suositus `750Mi`) |
| `statefulset.runner.labels` | Mukautetut labelit | | `statefulset.runner.labels` | Mukautetut labelit |
+4 -1
View File
@@ -22,7 +22,10 @@ INPUTS=$(jq -nc \
--arg source_repo "$GITOPS_SOURCE_REPO" \ --arg source_repo "$GITOPS_SOURCE_REPO" \
--arg source_commit "$GITOPS_SOURCE_COMMIT" \ --arg source_commit "$GITOPS_SOURCE_COMMIT" \
--arg git_tag_prefix "${GITOPS_TAG_PREFIX:-}" \ --arg git_tag_prefix "${GITOPS_TAG_PREFIX:-}" \
'{file: $file, yq_tpl: $yq_tpl, version: $version, source_repo: $source_repo, source_commit: $source_commit, git_tag_prefix: $git_tag_prefix}') --arg extra_cmd "${GITOPS_EXTRA_CMD:-}" \
--arg author_name "${GIT_USER_NAME:-}" \
--arg author_email "${GIT_USER_EMAIL:-}" \
'{file: $file, yq_tpl: $yq_tpl, version: $version, source_repo: $source_repo, source_commit: $source_commit, git_tag_prefix: $git_tag_prefix, extra_cmd: $extra_cmd, author_name: $author_name, author_email: $author_email}')
DIR="$(cd "$(dirname "$0")" && pwd)" DIR="$(cd "$(dirname "$0")" && pwd)"
echo "gitops-dispatch: dispatching to $GITOPS_REPO/$GITOPS_WORKFLOW..." echo "gitops-dispatch: dispatching to $GITOPS_REPO/$GITOPS_WORKFLOW..."
+8 -3
View File
@@ -84,7 +84,12 @@ _gitops_update() {
cd "${CLONE_DIR}" || _gitops_fail "Failed to enter clone directory" cd "${CLONE_DIR}" || _gitops_fail "Failed to enter clone directory"
yq eval -i "${YQ_EXPR}" "${INPUT_FILE}" || _gitops_fail "Failed to update ${INPUT_FILE}" yq eval -i "${YQ_EXPR}" "${INPUT_FILE}" || _gitops_fail "Failed to update ${INPUT_FILE}"
git add "${INPUT_FILE}" || _gitops_fail "Failed to stage ${INPUT_FILE}" if [ -n "${GITOPS_EXTRA_CMD:-}" ]; then
eval "${GITOPS_EXTRA_CMD}" || _gitops_fail "Extra command failed: ${GITOPS_EXTRA_CMD}"
git add -A || _gitops_fail "Failed to stage all changes"
else
git add "${INPUT_FILE}" || _gitops_fail "Failed to stage ${INPUT_FILE}"
fi
if git diff --cached --quiet; then if git diff --cached --quiet; then
echo "No changes — ${INPUT_FILE} already at ${VERSION}" echo "No changes — ${INPUT_FILE} already at ${VERSION}"
@@ -93,8 +98,8 @@ _gitops_update() {
exit 0 exit 0
fi fi
git -c user.name="gitea-ci-bot" \ git -c user.name="${GIT_USER_NAME:-gitea-ci-bot}" \
-c user.email="ci@keskikuja.site" \ -c user.email="${GIT_USER_EMAIL:-ci@keskikuja.site}" \
commit -m "[skip ci] gitops: update version to ${VERSION}" || _gitops_fail "Failed to commit" commit -m "[skip ci] gitops: update version to ${VERSION}" || _gitops_fail "Failed to commit"
GITOPS_SHA="$(git rev-parse HEAD)" GITOPS_SHA="$(git rev-parse HEAD)"
git push || _gitops_fail "Failed to push" git push || _gitops_fail "Failed to push"
+36 -2
View File
@@ -56,6 +56,15 @@ on:
git_tag_prefix: git_tag_prefix:
required: false required: false
type: string type: string
extra_cmd:
required: false
type: string
author_name:
required: false
type: string
author_email:
required: false
type: string
env: env:
INPUT_FILE: ${{ inputs.file }} INPUT_FILE: ${{ inputs.file }}
@@ -66,6 +75,9 @@ env:
GITOPS_REPO: ${{ github.repository }} GITOPS_REPO: ${{ github.repository }}
GITEA_API_URL: ${{ gitea.server_url }} GITEA_API_URL: ${{ gitea.server_url }}
GIT_TAG_PREFIX: ${{ inputs.git_tag_prefix || '' }} GIT_TAG_PREFIX: ${{ inputs.git_tag_prefix || '' }}
GITOPS_EXTRA_CMD: ${{ inputs.extra_cmd || '' }}
GIT_USER_NAME: ${{ inputs.author_name || '' }}
GIT_USER_EMAIL: ${{ inputs.author_email || '' }}
jobs: jobs:
update: update:
@@ -130,15 +142,37 @@ gitops-update:
This single job handles: dispatch → poll → find commit SHA → set commit-status on your commit → produce `GITOPS_SUMMARY` output. This single job handles: dispatch → poll → find commit SHA → set commit-status on your commit → produce `GITOPS_SUMMARY` output.
To run extra commands (e.g. `helm dependency update`) after the version bump and before the commit:
```yaml
gitops-update:
needs: [load-config, check-version, helm-build-push]
if: success()
uses: niko/gitea-ci-library/.gitea/workflows/gitops-dispatch.yml@v1
secrets: inherit
with:
env_json: ${{ needs.load-config.outputs.env_json }}
version: ${{ needs.check-version.outputs.version }}
GITOPS_FILE: Chart.yaml
GITOPS_YQ_TPL: '(.dependencies[] | select(.name == "agent-platform-helm") | .version) = "{{VERSION}}"'
GITOPS_REPO: niko/agent-platform-gitops
GITOPS_EXTRA_CMD: helm dependency update
```
When `GITOPS_EXTRA_CMD` is set, the script runs it after `yq` and stages all changes (`git add -A`) instead of only the input file — so any files generated by the extra command (e.g. `Chart.lock`, `charts/`) are included in the commit.
By default the GitOps commit is made as `gitea-ci-bot`. To use the original commit author instead, the dispatch workflow resolves it automatically from the consumer repo — no extra config needed. Just ensure the GitOps repo's `gitops-service.yaml` template has the `author_name` and `author_email` inputs and env mappings.
### 2.3 Parameters ### 2.3 Parameters
| Input | Required | Description | | Input | Required | Description |
|---|---|---| |---|---|---|---|
| `env_json` | Yes | Config JSON with `GITEA_API_URL`, optional `GIT_TAG_PREFIX` (for multi-component repos) | | `env_json` | Yes | Config JSON with `GITEA_API_URL`, optional `GIT_TAG_PREFIX` (for multi-component repos) |
| `version` | Yes | Version to write (e.g. `0.2.3`) | | `version` | Yes | Version to write (e.g. `0.2.3`) |
| `GITOPS_FILE` | Yes | Path in GitOps repo (e.g. `dev/Chart.yaml`) | | `GITOPS_FILE` | Yes | Path in GitOps repo (e.g. `dev/Chart.yaml`) |
| `GITOPS_YQ_TPL` | Yes | yq expression, `{{VERSION}}` is replaced at runtime | | `GITOPS_YQ_TPL` | Yes | yq expression, `{{VERSION}}` is replaced at runtime |
| `GITOPS_REPO` | Yes | GitOps repo slug (e.g. `niko/agent-platform-gitops`) | | `GITOPS_REPO` | Yes | GitOps repo slug (e.g. `niko/agent-platform-gitops`) |
| `GITOPS_EXTRA_CMD` | No | Shell command to run after yq update, before git commit (e.g. `helm dependency update`) |
### 2.4 Output ### 2.4 Output
@@ -177,7 +211,7 @@ report-summary:
## 4. What happens at runtime ## 4. What happens at runtime
1. Consumer's `gitops-dispatch.yml` generates a unique `dispatch_id` and POSTs it to the GitOps repo 1. Consumer's `gitops-dispatch.yml` generates a unique `dispatch_id` and POSTs it to the GitOps repo
2. GitOps workflow clones its own repo, applies `yq`, commits + pushes 2. GitOps workflow clones its own repo, applies `yq`, runs `GITOPS_EXTRA_CMD` if set, then commits + pushes
3. Consumer polls the GitOps repo's runs until the workflow completes 3. Consumer polls the GitOps repo's runs until the workflow completes
4. Consumer lists recent commits and finds the matching one by commit message `"gitops: update version to X.Y.Z"` 4. Consumer lists recent commits and finds the matching one by commit message `"gitops: update version to X.Y.Z"`
5. Consumer sets commit-status `gitops/{repo}[/{prefix}]` on its own commit with a link to the exact GitOps commit 5. Consumer sets commit-status `gitops/{repo}[/{prefix}]` on its own commit with a link to the exact GitOps commit