--- name: gitops-update description: | Getting GitOps configuration updates working for a consumer project — GitOps repo setup, consumer pipeline wiring, secrets, and commit-status output. activation-gate: | User mentions GitOps update, gitops-update, dispatch to another repo, two-repo version bump, cross-repo deployment, or wiring build output to config repo. category: ci impact: high --- # GitOps Update — consumer setup ## What you need - **GitOps repo** — holds the configuration files (e.g. `Chart.yaml`, `values.yaml`) - **Consumer repo** — builds artifacts and triggers the update - **Bottitoken** — Gitea token with write access to the GitOps repo only Two repos, isolated access. The consumer never writes to GitOps directly; it dispatches a workflow that clones, updates, commits, and pushes. --- ## 1. GitOps-repo setup Create `.gitea/workflows/gitops-service.yaml`: ```yaml name: GitOps Update run-name: "GitOps (${{ inputs.dispatch_id || 'manual' }})" on: workflow_dispatch: inputs: file: required: true type: string yq_tpl: required: true type: string version: required: true type: string source_repo: required: true type: string source_commit: required: true type: string dispatch_id: required: false type: string git_tag_prefix: required: false type: string env: INPUT_FILE: ${{ inputs.file }} YQ_TPL: ${{ inputs.yq_tpl }} VERSION: ${{ inputs.version }} SOURCE_REPO: ${{ inputs.source_repo }} SOURCE_COMMIT: ${{ inputs.source_commit }} GITOPS_REPO: ${{ github.repository }} GITEA_API_URL: ${{ gitea.server_url }} GIT_TAG_PREFIX: ${{ inputs.git_tag_prefix || '' }} jobs: update: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/checkout@v4 with: repository: niko/gitea-ci-library path: .ci - name: Install yq run: | wget -qO /usr/local/bin/yq \ https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 chmod +x /usr/local/bin/yq - name: Run GitOps update env: GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} run: | bash .ci/scripts/gitops-update.sh ``` > **⚠️ yq ladataan lennossa.** Tämä on väliaikainen kompromissi. Myöhemmin > julkaistaan Docker Hubiin custom CI-kontti, jossa nodejs + git + yq > valmiina. Sama patterni kuin `ci-bats` ja `ci-cucumber`. > Ks. `skills/ci-container-build/SKILL.md`. Key points: - `run-name` must include `dispatch_id` — the consumer's poll step uses it to find the run - `secrets.GITEA_TOKEN` is the **auto-token** — write access to the GitOps repo only, no consumer access needed - Commit message becomes `"[skip ci] gitops: update version to X.Y.Z"` — used by consumer to find the commit SHA --- ## 2. Consumer-repo setup ### 2.1 Token Create a Gitea token with write access to the GitOps repo: 1. Gitea → `Settings` → `Applications` → `Generate Token` 2. Select the GitOps repo, grant write access 3. Save as an Actions secret in the consumer repo: **`GITOPS_DISPATCH_TOKEN`** ### 2.2 Pipeline call Add a job after your build step that calls the dispatch workflow: ```yaml gitops-update: needs: [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.version.outputs.version }} GITOPS_FILE: dev/Chart.yaml GITOPS_YQ_TPL: '.version = "{{VERSION}}"' GITOPS_REPO: niko/your-gitops-repo ``` This single job handles: dispatch → poll → find commit SHA → set commit-status on your commit → produce `GITOPS_SUMMARY` output. ### 2.3 Parameters | Input | Required | Description | |---|---|---| | `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`) | | `GITOPS_FILE` | Yes | Path in GitOps repo (e.g. `dev/Chart.yaml`) | | `GITOPS_YQ_TPL` | Yes | yq expression, `{{VERSION}}` is replaced at runtime | | `GITOPS_REPO` | Yes | GitOps repo slug (e.g. `niko/agent-platform-gitops`) | ### 2.4 Output The workflow produces a `summary` output in pipe format: ``` component|version|status|commit_sha|repo agent-platform-helm|0.2.3|success|abc789def|niko/agent-platform-gitops ``` Pass it to `report-summary.yml` for the pipeline summary: ```yaml report-summary: needs: [load-config, gitops-update] if: always() uses: niko/gitea-ci-library/.gitea/workflows/report-summary.yml@main with: env_json: ${{ needs.load-config.outputs.env_json }} suites: bats cucumber gitops: ${{ needs.gitops-update.outputs.summary }} ``` --- ## 3. Token summary | Token | Where | Scope | Purpose | |---|---|---|---| | `GITOPS_DISPATCH_TOKEN` (manual) | Consumer secrets | write GitOps repo | Dispatches the GitOps workflow | | `GITHUB_TOKEN` (auto) | Consumer workflow | write consumer repo | Sets commit-status on consumer's commit | | `GITEA_TOKEN` (auto) | GitOps workflow | write GitOps repo | Clone, push, commit-status in GitOps repo | --- ## 4. What happens at runtime 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 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"` 5. Consumer sets commit-status `gitops/{repo}[/{prefix}]` on its own commit with a link to the exact GitOps commit 6. If no matching commit is found (no change or error), the job fails 7. On failure, `GITOPS_SUMMARY` still flows through `report-summary` with `status=failure` --- ## 5. GIT_TAG_PREFIX (optional) If the same consumer repo dispatches updates for multiple components (e.g. Docker image + Helm chart), set `GIT_TAG_PREFIX` in your `gitea-env.conf`: ``` GIT_TAG_PREFIX=docker/ ``` Each component gets its own commit-status context: | Prefix | Context | |---|---| | (empty) | `gitops/agent-platform` | | `docker/` | `gitops/agent-platform/docker` | | `helm/` | `gitops/agent-platform/helm` | This prevents status overwrites between parallel dispatch jobs. --- ## 6. What you do NOT need to know - How `gitops-update.sh` works internally - How the polling finds the run - How the commit SHA is extracted - Race condition handling - CI container plans All of that is handled by `gitops-dispatch.yml`. You just call it.