Files
niko d6343438a3
CI Main / Build & Push Docker (push) Successful in 56s
gitops/gitea-ci-library GitOps: 0.2.32
CI Main / GitOps (push) Successful in 45s
CI Main / Move provider version tag (push) Successful in 16s
CI Main / Report Summary (push) Successful in 7s
CI Main / Latest versio (push) Successful in 24s
CI Main / Bats tests (push) Successful in 1m38s
CI Main / Cucumber tests (push) Successful in 1m44s
CI Main / Config load (push) Successful in 21s
unit-tests Bats test report
acc-tests Cucumber test report
ci-docker-build-push Docker push 0.2.32
Feture/gitops7 (#44)
Co-authored-by: moilanik <niko.moilanen@tietoevry.com>
Reviewed-on: #44
2026-06-23 12:45:42 +03:00

6.6 KiB

name, description, activation-gate, category, impact
name description activation-gate category impact
gitops-update Getting GitOps configuration updates working for a consumer project — GitOps repo setup, consumer pipeline wiring, secrets, and commit-status output. User mentions GitOps update, gitops-update, dispatch to another repo, two-repo version bump, cross-repo deployment, or wiring build output to config repo. ci 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:

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 → SettingsApplicationsGenerate 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:

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:

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.