218 lines
6.6 KiB
Markdown
218 lines
6.6 KiB
Markdown
---
|
|
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.
|