Skip to content

Commit a6e3471

Browse files
docs: add AGENTS.md and agent skills for runner workflows
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent f27b39a commit a6e3471

4 files changed

Lines changed: 270 additions & 0 deletions

File tree

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
---
2+
name: runner-add-tool
3+
description: >-
4+
Add or update a CLI/tool in the Deerhide python-github-runner image (Containerfile,
5+
manifest.yaml pins, Renovate, OpenAPI npm overrides, README). Use when adding a binary,
6+
apt package, OpenAPI npm CLI, changing an install RUN layer, or wiring a new *_VERSION pin.
7+
---
8+
9+
# Add a tool to the runner image
10+
11+
## When to use
12+
13+
- New CLI or runtime in the image
14+
- Change how an existing tool is installed
15+
- OpenAPI npm tool / CVE override in `openapi-tools/`
16+
- Keywords: Containerfile, manifest.yaml, Renovate, `*_VERSION`, redocly, spectral, portman, newman, oasdiff
17+
18+
## Install method
19+
20+
| Method | When |
21+
| --- | --- |
22+
| GitHub release binary (curl + install to `/usr/local/bin`) | Default for pin-able CLIs |
23+
| apt | OS packages only (skopeo, buildah, jq, trivy repo, deadsnakes) |
24+
| npm via `openapi-tools/` | OpenAPI JS CLIs sharing one prefix + CVE overrides |
25+
| pip | Rare (e.g. pre-commit); prefer binary otherwise |
26+
27+
## Checklist
28+
29+
Copy and track:
30+
31+
```
32+
Task progress:
33+
- [ ] 1. Choose install method
34+
- [ ] 2. Pin FOO_VERSION in manifest.yaml + Containerfile ARG
35+
- [ ] 3. Add RUN install layer (root, before USER runner)
36+
- [ ] 4. OpenAPI npm only: package + symlink + overrides if needed
37+
- [ ] 5. Renovate customManagers entry for the new pin
38+
- [ ] 6. Update README "What's included"
39+
- [ ] 7. Validate (hadolint / pre-commit / build-scan)
40+
```
41+
42+
### 1–2. Pin versions
43+
44+
Add the same value in both places:
45+
46+
```yaml
47+
# manifest.yaml → build.args
48+
- FOO_VERSION=1.2.3
49+
```
50+
51+
```dockerfile
52+
# Containerfile
53+
ARG FOO_VERSION=1.2.3
54+
```
55+
56+
### 3. Binary install example
57+
58+
```dockerfile
59+
ARG FOO_VERSION=1.2.3
60+
RUN curl -sSL -o /usr/local/bin/foo \
61+
"https://github.com/org/foo/releases/download/v${FOO_VERSION}/foo-linux-amd64" \
62+
&& chmod +x /usr/local/bin/foo
63+
```
64+
65+
Install as root in the `base` stage. Do not leave the final stage as root.
66+
67+
**Bun:** use `bun-linux-x64-baseline.zip` (no AVX2 on some runner CPUs).
68+
69+
### 4. OpenAPI npm tools
70+
71+
Versions come from build args. CVE overrides only in `openapi-tools/package.json` (no lockfile).
72+
73+
1. Add `FOO_VERSION` to `manifest.yaml` and `ARG` in Containerfile.
74+
2. Extend the `npm install --prefix /tmp/openapi-tools` line with `"@scope/pkg@${FOO_VERSION}"`.
75+
3. Add the binary name to the symlink `for bin in ...` loop.
76+
4. Add `overrides` only when Trivy reports a fixable transitive CVE.
77+
78+
`oasdiff` is a standalone Go binary — do **not** put it in the npm prefix.
79+
80+
### 5. Renovate
81+
82+
Mirror existing managers in `renovate.json`:
83+
84+
```json
85+
{
86+
"customType": "regex",
87+
"description": "Update Foo version",
88+
"fileMatch": ["^Containerfile$", "^manifest\\.yaml$"],
89+
"matchStrings": ["FOO_VERSION=(?<currentValue>\\S+)"],
90+
"depNameTemplate": "org/foo",
91+
"datasourceTemplate": "github-releases",
92+
"extractVersionTemplate": "^v?(?<version>.+)$"
93+
}
94+
```
95+
96+
Adjust `extractVersionTemplate` / `datasourceTemplate` to match upstream tags (see Node / Bun managers).
97+
98+
### 6–7. Docs and validate
99+
100+
- Update the matching table in [README.md](../../../README.md).
101+
- Run `pre-commit run --all-files` (includes hadolint).
102+
- Prefer a full build-scan via the [`runner-build-release`](../runner-build-release/SKILL.md) skill before merge.
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
---
2+
name: runner-build-release
3+
description: >-
4+
Build, scan, and release the Deerhide python-github-runner OCI image. Use when running
5+
local builds, debugging CI/PR validation, semantic-release on main, dive/trivy failures,
6+
image tags, or .trivyignore updates.
7+
---
8+
9+
# Build and release the runner image
10+
11+
## When to use
12+
13+
- Local image build / push
14+
- PR CI failures (commitlint, hadolint, build-and-scan)
15+
- Release on `main` (semantic-release + GHCR push)
16+
- dive efficiency or Trivy HIGH/CRITICAL findings
17+
- Keywords: `builder.sh`, validate.yaml, release.yaml, GHCR, `.trivyignore`, dive
18+
19+
## Prerequisites
20+
21+
```bash
22+
# Docker required
23+
./scripts/install_tools.sh
24+
skopeo login ghcr.io
25+
```
26+
27+
Local tool versions from `install_tools.sh` MAY differ from pinned image/CI versions.
28+
29+
## Local full pipeline
30+
31+
```bash
32+
./scripts/builder.sh
33+
```
34+
35+
Order: hadolint → buildah (OCI, squashed) → dive → trivy → push to registry from `manifest.yaml`.
36+
37+
Config knobs:
38+
39+
| File | Role |
40+
| --- | --- |
41+
| `manifest.yaml` | Name, registry, build args, labels |
42+
| `.hadolint.yaml` | Containerfile lint |
43+
| `.dive-ci` | Layer efficiency thresholds |
44+
| `.trivyignore` | Base-image CVEs with `exp:` dates |
45+
46+
## CI map
47+
48+
| Workflow | Trigger | What it does |
49+
| --- | --- | --- |
50+
| `ci.yaml` | PR → `main` | commitlint + calls `validate.yaml` |
51+
| `validate.yaml` | `workflow_call` | hadolint, buildah build, dive, trivy |
52+
| `release.yaml` | push → `main` | validate → semantic-release → build & push if new version |
53+
54+
## Image tags (after release)
55+
56+
```
57+
ghcr.io/deerhide/python-github-runner:latest
58+
ghcr.io/deerhide/python-github-runner:1
59+
ghcr.io/deerhide/python-github-runner:1.2
60+
ghcr.io/deerhide/python-github-runner:1.2.3
61+
```
62+
63+
## Semantic-release / commits
64+
65+
Conventional Commits drive the bump (commitlint enforced):
66+
67+
| Prefix | Bump |
68+
| --- | --- |
69+
| `fix:` | patch |
70+
| `feat:` | minor |
71+
| `feat!:` / `BREAKING CHANGE:` | major |
72+
73+
Examples:
74+
75+
```bash
76+
git commit -m "feat: add kubectl to image"
77+
git commit -m "fix: correct trivy scan exit code"
78+
git commit -m "chore: update argo to v4.0.7"
79+
```
80+
81+
On new version, release workflow updates `CHANGELOG.md`, creates the GitHub release, builds, scans, and pushes semver tags.
82+
83+
## Scan policy
84+
85+
Trivy in this repo:
86+
87+
- Library packages only (`--pkg-types library`)
88+
- Ignores unfixed vulnerabilities
89+
- Fails on HIGH/CRITICAL that are not ignored
90+
91+
**When a finding appears:**
92+
93+
1. Prefer upgrade (tool pin / `RUNNER_VERSION` / Renovate PR).
94+
2. For base-image / upstream-only CVEs that cannot be fixed here: add to `.trivyignore` with `exp:YYYY-MM-DD` and a short comment naming the origin.
95+
3. MUST NOT add ignores without expiry. Re-evaluate when bumping the base runner.
96+
97+
Dive failures: fix layer bloat in Containerfile (cleanup apt lists, remove temp archives) or adjust `.dive-ci` only with justification.
98+
99+
## Quick checklist
100+
101+
```
102+
Task progress:
103+
- [ ] Tools installed (`install_tools.sh`)
104+
- [ ] Registry login (`skopeo login ghcr.io`)
105+
- [ ] `./scripts/builder.sh` green locally OR CI validate green
106+
- [ ] Conventional commit message matches intended bump
107+
- [ ] New .trivyignore entries have exp: dates (if any)
108+
```

AGENTS.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# AGENTS.md — Python GitHub Runner
2+
3+
Always-on orientation for AI agents working in this repo. Read before touching files.
4+
5+
## What this repo is
6+
7+
Self-hosted GitHub Actions runner **container image** for Deerhide / Velmios CI:
8+
9+
- Image: `ghcr.io/deerhide/python-github-runner`
10+
- Base: `ghcr.io/actions/actions-runner` (`RUNNER_VERSION` in `manifest.yaml`)
11+
- Includes Python 3.12/3.13 (deadsnakes), Poetry, UV, DevOps CLIs (argo, kargo, kubectl, pack, skopeo, buildah, …), OpenAPI CLIs (redocly, spectral, portman, newman, oasdiff), Node/Bun, and a full OCI build/scan pipeline so the image can build itself.
12+
13+
Tool inventory and version tables live in [README.md](README.md). Do not duplicate them here.
14+
15+
## Directory map
16+
17+
| Path | What lives here |
18+
| --- | --- |
19+
| [Containerfile](Containerfile) | Multi-stage image definition (`base``runtime`) |
20+
| [manifest.yaml](manifest.yaml) | Build args, OCI labels, registry, Actions cache list |
21+
| [openapi-tools/package.json](openapi-tools/package.json) | CVE `overrides` for npm OpenAPI CLIs (no lockfile) |
22+
| [scripts/](scripts/) | `builder.sh`, `install_tools.sh`, `cache_actions.sh`, helpers |
23+
| [.github/workflows/](.github/workflows/) | `ci.yaml`, `validate.yaml`, `release.yaml`, nightly/update |
24+
| [renovate.json](renovate.json) | Regex managers for `*_VERSION=` pins |
25+
| [.pre-commit-config.yaml](.pre-commit-config.yaml) | hadolint, shellcheck, commitlint, hygiene |
26+
| [.hadolint.yaml](.hadolint.yaml) | Containerfile lint config |
27+
| [.trivyignore](.trivyignore) | Base-image CVEs with `exp:` dates |
28+
| [.dive-ci](.dive-ci) | Dive efficiency thresholds |
29+
| [.releaserc.yaml](.releaserc.yaml) | semantic-release config |
30+
31+
## Key invariants
32+
33+
- Pin tool versions in **both** `manifest.yaml` `build.args` and `Containerfile` `ARG` defaults. Renovate regex managers match both files.
34+
- Prefer pinned GitHub-release / curl binary installs over apt. Use apt for OS packages only (skopeo, buildah, jq, trivy apt repo, deadsnakes Python, etc.).
35+
- OpenAPI npm CLIs: versions come from build args; CVE overrides **only** in `openapi-tools/package.json`. No `package-lock.json`.
36+
- Pre-cache GitHub Actions listed under `manifest.yaml` `cache.actions` via `scripts/cache_actions.sh` at image build time.
37+
- Trivy scans library packages only and ignores unfixed vulns. Base-image findings go in `.trivyignore` with `exp:` dates — MUST NOT ignore without expiry.
38+
- Conventional Commits + commitlint; semantic-release bumps and publishes on push to `main`.
39+
- Install as root in `base`, then switch to `USER runner`. Final stage MUST NOT stay root (hadolint DL3002).
40+
- Bun: install `bun-linux-x64-baseline` (runner CPUs may lack AVX2).
41+
42+
## Local validation
43+
44+
```bash
45+
pre-commit install --hook-type pre-commit --hook-type commit-msg
46+
pre-commit run --all-files
47+
./scripts/install_tools.sh
48+
skopeo login ghcr.io
49+
./scripts/builder.sh # hadolint → buildah → dive → trivy → push
50+
```
51+
52+
## Task → skill index
53+
54+
Skills live under [.agents/skills/](.agents/skills/). Read the matching skill when starting a task:
55+
56+
| Task | Skill |
57+
| --- | --- |
58+
| Add or change a CLI/tool in the image (binary, apt, OpenAPI npm, Renovate pin) | [`runner-add-tool`](.agents/skills/runner-add-tool/SKILL.md) |
59+
| Local build, CI/PR validation, release, dive/trivy failures, semantic-release | [`runner-build-release`](.agents/skills/runner-build-release/SKILL.md) |

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858

5959
### Added
6060

61+
* **docs:** add AGENTS.md and agent skills for adding tools and build/release workflows
6162
* **ci:** add nightly rebuild workflow to force daily semantic-release/image refreshes when no unreleased commits exist
6263

6364
### Changed

0 commit comments

Comments
 (0)