Generate and maintain Gitea Actions CI/CD pipelines that build & publish Docker images (applications-backend/*, applications-frontend/*) and OCI Helm charts (helm-charts/*) from a pnpm + Turborepo monorepo to a Harbor registry, authenticated by a project robot account via Gitea org secret + global vars. - SKILL.md: auth model, convention-driven discovery, publish gating, gotchas - references/harbor-auth.md: docker/helm login, robot accounts, secret/var taxonomy, bake-into-runner alternative, troubleshooting - references/pipeline-workflow.md: jobs, discovery loops, tagging, turbo prune - references/conventions.md: Dockerfile/chart locations, image & chart naming - assets/workflows/ci-cd.yaml: ready-to-drop .gitea/workflows pipeline Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
62 lines
2.7 KiB
Markdown
62 lines
2.7 KiB
Markdown
# devsecops-ci-cd-gitea
|
|
|
|
Agent Skill for **Gitea Actions** CI/CD pipelines that build and publish the artifacts of a
|
|
**pnpm + Turborepo** monorepo to a **Harbor** registry:
|
|
|
|
```text
|
|
applications-backend/<svc>/Dockerfile ─▶ image harbor/<project>/<svc>:<tag>
|
|
applications-frontend/<app>/Dockerfile ─▶ image harbor/<project>/<app>:<tag>
|
|
helm-charts/<chart>/Chart.yaml ─▶ OCI chart harbor/<project>/charts/<chart>:<ver>
|
|
```
|
|
|
|
Discovery is convention-driven — the pipeline finds every app with a `Dockerfile` and every
|
|
chart under `helm-charts/`, builds them, and pushes only on the default branch or a tag.
|
|
Authentication uses a Harbor **robot account** whose credential lives in Gitea Actions
|
|
secrets/variables — never a person's login, never a value committed to the repo.
|
|
|
|
The skill owns the pipeline up to *"published to Harbor"*. Deploying the artifact is the
|
|
**development-gitops-argo-cd** skill's job.
|
|
|
|
## Layout
|
|
|
|
```text
|
|
devsecops-ci-cd-gitea/
|
|
├── SKILL.md # Entry point — auth model, discovery, gating, gotchas
|
|
├── references/
|
|
│ ├── harbor-auth.md # docker/helm login, robot accounts, Gitea vars/secrets, runner-bake
|
|
│ ├── pipeline-workflow.md # jobs, discovery loops, tagging, gating, turbo prune
|
|
│ └── conventions.md # where Dockerfiles/charts live, image & chart naming
|
|
└── assets/
|
|
└── workflows/
|
|
└── ci-cd.yaml # ready-to-drop <repo>/.gitea/workflows/ci-cd.yaml
|
|
```
|
|
|
|
## The one thing to get right up front
|
|
|
|
**Build context is the repository root**, always:
|
|
`docker build -f applications-backend/<svc>/Dockerfile … .` — the Dockerfile runs `turbo prune`
|
|
over the whole monorepo, so building from the app directory fails. And charts are **centralized
|
|
under `helm-charts/`**, not co-located under the app — discover images and charts independently,
|
|
with no assumed 1:1 mapping.
|
|
|
|
## Registry auth in one table
|
|
|
|
| Kind | Name | Scope | Example |
|
|
|---|---|---|---|
|
|
| Variable | `HL_V1_HARBOR_ADDRESS` | global | `harbor-v1.apps.lego-cloud.eu` |
|
|
| Variable | `HL_V1_HARBOR_ROBOT_GITEA_ACTIONS_V1_USERNAME` | global | `robot$gondor-v1+gitea-actions-v1` |
|
|
| Secret | `HL_V1_HARBOR_ROBOT_GITEA_ACTIONS_V1_SECRET` | org | *(robot secret)* |
|
|
|
|
Username and address are not secret → global variables (set once). Gitea has no global-secret
|
|
level, so the robot secret is a per-org secret. Details in `references/harbor-auth.md`.
|
|
|
|
## Deploy
|
|
|
|
```bash
|
|
cd ../skill-manager/scripts
|
|
task deploy -- --skill-dir="$(cd ../../devsecops-ci-cd-gitea && pwd)"
|
|
```
|
|
|
|
Built with the `skill-manager` skill, following the
|
|
[agentskills.io specification](https://agentskills.io/specification).
|