Initial scaffold: generation-rule-only Crossplane Bucket example

Educational RunWhen CodeCollection that discovers Crossplane GCP
Bucket CRDs (storage.gcp.upbound.io/v1beta1) and generates one SLX
per bucket. Ships only generation rules and Jinja templates; the
runtime lives in rw-generic-codecollection/k8s-kubectl-cmd (already
loaded by the airgap runner).

Includes:
- codebundles/gcp-bucket-crossplane-health with generation rule + 3 templates
- docs/01..07 numbered training chapters with screenshot placeholders
- README, .gitignore

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
stewartshea
2026-06-30 21:51:04 -04:00
commit eb8160e659
15 changed files with 1244 additions and 0 deletions
+120
View File
@@ -0,0 +1,120 @@
# 06 — Runner integration
## What you'll do
Tell the airgap `workspace-builder` where to find this repository and
have Flux reconcile the change.
## The single edit
Open the airgap runner's HelmRelease values file:
`apps/runwhen-env/airgap/runwhen-runner/helm.yaml`
Under `spec.values.workspaceBuilder.workspaceInfo.configMap.data.codeCollections`,
append one entry. Before:
```yaml
codeCollections:
- repoURL: http://rw-airgap-cc-catalog-svc.runwhen-env-airgap:8080/git/rw-cli-codecollection.git
ref: main
```
After:
```yaml
codeCollections:
- repoURL: http://rw-airgap-cc-catalog-svc.runwhen-env-airgap:8080/git/rw-cli-codecollection.git
ref: main
- repoURL: https://<gitea-token>@gitea.airgap.shared.runwhen.com/gitea-admin/simple-private-codecollection.git
ref: main
```
The `<gitea-token>` value is a Gitea personal access token with at least
`read:repository` scope on the `simple-private-codecollection` repo.
Screenshot placeholder: `images/06-helm-yaml-diff.png` — annotated diff of
the two-line addition.
## What we intentionally did NOT change
- `runner.codeCollections` — the list of code collections whose Robot
code is executed by worker pods. Because our private CC ships **no
robots**, it never needs a runner worker. The runtime lives in the
already-registered `rw-generic-codecollection`.
- Any secret configuration — we are using the fastest working option:
the token embedded directly in the `repoURL`. This trades tidiness
for zero setup complexity. See "Trade-offs" below.
## Trade-offs of token-in-URL (option B)
The token becomes visible to anyone with read access to the
`workspace-builder` `ConfigMap` — via `kubectl get cm workspace-builder
-o yaml` in the runner namespace, and to anyone reading the Flux repo.
That is acceptable for a **test** token you can rotate, but not
production hygiene.
Two better options once this example is working:
### Option A — cc-catalog proxy (production path)
Turn on runtime git sync in the platform-side cc-catalog service and add
a `simple-private-codecollection` slug there. The workspace-builder then
clones from the internal proxy URL (no token in ConfigMap):
```yaml
- repoURL: http://rw-airgap-cc-catalog-svc.runwhen-env-airgap:8080/git/simple-private-codecollection.git
ref: main
```
That requires editing `apps/runwhen-env/airgap/runwhen-platform/helmrelease.yaml`
to (a) add the slug under `ccCatalog.config.sources[].codecollections`
and (b) enable `git.runtime_sync: true` with `git.auth.token_env`
pointing at a Kubernetes secret storing the Gitea token. Track that as a
follow-up.
### Option C — fix upstream
Patch `runwhen-local` to actually apply `authUser`/`authToken` in
[`code_collection.py`](https://github.com/runwhen-contrib/runwhen-local/blob/main/src/enrichers/code_collection.py)
`update_repo()`. Today those fields are parsed and stored on the
`CodeCollection` object but never applied to `Repo.clone_from()`. A
one-line fix to route through `git_utils.get_repo_url_with_auth()`. Then
you can pass `authUser`/`authToken` in `workspaceInfo.yaml` and reference
them as environment variables or literal values without leaking the
token.
## Trigger the change
The Flux `HelmRelease` for `runwhen-local` reconciles every 5 minutes,
but you can force it:
```bash
flux reconcile hr runwhen-local -n runwhen-env-airgap-runner --with-source
```
Watch for the reconcile to complete:
```bash
kubectl -n runwhen-env-airgap-runner get pods -w
```
You should see the `runwhen-local` pod restart (because the ConfigMap
changed). Its next start will use the new `workspaceInfo`.
## Verify the workspace-builder can reach Gitea
```bash
kubectl -n runwhen-env-airgap-runner exec deploy/runwhen-local -c workspace-builder -- \
curl -sSI --max-time 5 https://gitea.airgap.shared.runwhen.com/ | head -1
```
Expected: `HTTP/2 200` or `HTTP/1.1 200 OK`. If the request hangs, check
`NetworkPolicy` — the airgap deps namespace should already permit this
traffic on 443.
Screenshot placeholder: `images/06-curl-gitea.png`.
## Next
Continue to [07 — Validate and observe](07-validate-and-observe.md).