Files
cc-ci-orchestrator/.opencode/skills/cctest-recipe-upstream/SKILL.md
T

91 lines
5.9 KiB
Markdown

---
name: cctest-recipe-upstream
description: "[recipe-maintainer/cctest] From a git.autonomic.zone review-PR URL, fetch the branch + tag locally and emit the commands to open the upstream PR on git.coopcloud.tech (Wraps the autonomic-recipe-maintainer skill /recipe-upstream; runs against the cctest test server + ARM sandbox, not cc-ci. Invoke as /cctest-recipe-upstream.)"
---
# cctest-recipe-upstream (cctest wrapper)
**Canonical procedure:** `references/recipe-maintainer/.opencode/skills/recipe-upstream/SKILL.md`
— read it and follow it. This wrapper only sets context + policy.
**Context:** this is an **autonomic-recipe-maintainer (ARM)** skill. It operates on the
recipe-maintainer **cctest** test server / local abra sandbox — NOT on the cc-ci CI server or
its shared swarm. Execute with the submodule as your working directory:
`cd /srv/cc-ci-orch/references/recipe-maintainer`. If the ARM environment is not yet
configured on this host (`settings.toml` from `settings.toml.example`, sandbox/test instances),
run `/cctest-intro` / `/cctest-setup-sandbox` first.
**Unified policy (same as cc-ci — no differences):**
- **Recipe PRs are NEVER merged by an agent.** Every flow ends at an open PR; the operator
reviews and merges. This is ARM's own rule too ("PRs are reviewed and merged manually by a
human afterwards — never pushes to upstream or merges anything"); ARM's "no human review in
the middle" wording refers only to skipping the mid-run plan confirmation, not to merging.
- Never touch cc-ci infrastructure (the CI server, its swarm, `/root/*` clones, the weekly
timers) from an ARM skill — cc-ci work goes through the cc-ci skills.
- The submodule is **pinned**: don't commit into it from here; upstream ARM changes arrive via
a deliberate submodule bump + `scripts/gen-cctest-skills.py` regeneration.
**Sandboxed vs non-sandboxed mode.** This skill needs only git + (optionally) the Gitea API —
not the test server — so it can run either way. Probe, then follow that branch:
- **Sandboxed** (ARM env configured: `test-ssh/.testenv` with `GITEA_USERNAME`/`GITEA_PASSWORD`/
`GITEA_URL`, sandbox/test instances): the canonical `recipe-upstream` script in
`references/recipe-maintainer/.claude/commands/recipe-upstream.md` runs as written. Note its
WORKSPACE probing expects `/workspace` or `~/Documents/recipe-maintainer`; on a bare host pass
the submodule dir explicitly instead.
- **Non-sandboxed** (no ARM env on the host — e.g. the orchestrator, where the recipe-maintainer
checkout is only a pinned submodule): no sandbox/test instances are needed and NONE of the
setup skills are. Recipe-maintainer mirrors on `git.autonomic.zone` are publicly readable, so:
1. Check out the recipe if missing: `abra recipe fetch <recipe>` (lands in `~/.abra/recipes/<recipe>`)
— or a plain anonymous `git clone https://git.autonomic.zone/recipe-maintainers/<recipe>.git`
if abra is unavailable.
2. Fetch the PR head branch from the mirror **anonymously** — no credentials in the remote URL:
`git remote add gitea https://git.autonomic.zone/recipe-maintainers/<recipe>.git`
(remote update rather than re-add if it exists), then
`git fetch gitea +refs/pull/<N>/head:refs/heads/<head_ref>`.
3. Fetch PR metadata (head/base refs, merged flag, release bump line) from
`https://git.autonomic.zone/api/v1/repos/recipe-maintainers/<recipe>/pulls/<N>` —
unauthenticated; use bot creds only if the repo turns out to be private (orchestrator hosts
can read them from `/srv/cc-ci-orch/.testenv` — never written anywhere else).
4. Everything else in the canonical script (origin/dev remote setup, release recommendation,
emitted next-steps) is identical.
Every time the branch was prepared **here**, remember it exists only on this host — the
operator's machine must fetch it first. Always emit this **step 0** before the push step
(anonymous public fetch, no credentials needed):
```
# 0. On a machine WITHOUT the branch pre-fetched, get it from the autonomic mirror
# (fetch by URL — works regardless of what the local remotes are named):
cd <local checkout of the recipe>
git fetch https://git.autonomic.zone/recipe-maintainers/<recipe>.git +refs/pull/<PR_NUM>/head:refs/heads/<HEAD_REF>
git checkout <HEAD_REF>
```
If the operator's checkout does NOT yet have the mirror remote, emit once before the fetch:
```
git remote add gitea https://git.autonomic.zone/recipe-maintainers/<recipe>.git
```
In both modes the final output is a set of commands for the operator to run on a machine **with
push access to `git.coopcloud.tech`** — always print them, even when everything local is
already prepared.
**History-divegence check before emitting the compare URL.** The autonomic recipe-maintainer
mirrors' `main` can share only a distant ancestor with upstream `main` (same work re-committed
with different hashes as the mirror was synced/rebuilt). A 3-dot compare
`main...<head_ref>` from the raw mirror branch then shows the ENTIRE diverged history, not the
one upgrade commit. Guard: while preparing, run
`git merge-base <head_ref> <base_ref>`; if the result is older than a few commits below upstream
`origin/main`, cherry-pick the upgrade commit(s) onto fresh upstream `origin/main` (branch
`<head_ref>-rebased`), push THAT to the autonomic mirror, and emit the fetch/push/compare commands
using the rebased branch instead of the raw one. Also fix the stale `origin/main` wording above:
the upstream base branch may be `master`, not `main` — derive it from the remotes.
**Branch-name mismatch mirror vs upstream.** The mirror and upstream can use different base-branch
names (gitea: mirror `main`, upstream `master`). When emitting step 3 (the post-merge release),
NEVER hardcode `main` — derive the upstream default branch from the existing remotes (`git
remote show origin` or `git ls-remote --symref origin HEAD`) and emit `git checkout <that>;
git fetch origin; git merge --ff-only origin/<that>;` before `abra recipe release`.