Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .claude/skills/chart-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
name: chart-change
description: Change an EduIDE Helm chart safely. Use when editing templates or values in EduIDE-Helm, or when asked why a chart change is or is not behaviour-preserving.
---

# Changing a chart

The question that matters is not "does it lint" but **"what does this do to the
five live environments"**. There is a command for that.

## Loop

```bash
# 1. baseline BEFORE touching anything
./scripts/render-envs.sh /tmp/before

# 2. make one change, one concern at a time

# 3. what did it actually do?
./scripts/render-envs.sh /tmp/after
diff -r /tmp/before /tmp/after
```

For a refactor the diff must be **empty**. If it is not, either the refactor is
not behaviour-preserving or the change was larger than intended — both worth
knowing before review.

For an intentional change, the diff should contain exactly that change and
nothing else. Ten lines across five environments is one line per environment.

## Then

```bash
helm lint charts/eduide charts/eduide-cluster
# bump the chart version - CI enforces it, and release.yml silently
# publishes nothing if you forget
docker run --rm -v "$PWD/charts:/helm-docs" -u "$(id -u)" jnorwood/helm-docs:v1.14.2
```

## Traps

- **Never release-prefix resource names.** The operator mounts
`oauth2-proxy-config`, `oauth2-templates` and `oauth2-emails` by literal name
into every session pod.
- **Adding a `lookup`?** Add it to the mask list in `scripts/render-envs.sh` too,
or every future PR shows a false diff.
- **A Go-template comment is `{{/* */}}`.** A YAML `#` comment inside a template
ends up in the rendered manifest and shows as a diff.
- **`helm lint` accepts invalid YAML.** Duplicate keys pass lint and render, and
are only caught by `kubeconform`. Run it.
76 changes: 76 additions & 0 deletions .claude/skills/cut-a-release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
name: cut-a-release
description: Cut an EduIDE platform release across all four repositories. Use when asked to release, cut a version, publish charts, or ship a version of EduIDE.
---

# Cutting a release

A release is one version across EduIDE-Cloud, EduIDE, EduIDE-Landing-Page and
EduIDE-Helm.

**Do not bump the chart version from a workflow or by pushing to `main`.** The
release train deliberately does not do this, and neither should you. It checks
the charts are already at the requested version and fails otherwise. The bump is
a reviewed pull request; automation that pushes to `main` triggers the workflows
watching `main`.

## 1. Dry run first, always

```bash
gh workflow run release-train.yml --repo EduIDE/EduIDE-Helm \
-f version=2.3.0 -f dry_run=true
```

Read the summary. It reports which images the version would need, and builds
nothing.

## 2. Bump both charts in a pull request

Both charts, both fields — four values, all identical:

```yaml
# charts/eduide/Chart.yaml AND charts/eduide-cluster/Chart.yaml
version: 2.3.0
appVersion: "2.3.0"
```

Then regenerate the READMEs, or the `docs-drift` job fails:

```bash
docker run --rm -v "$PWD/charts:/helm-docs" -u "$(id -u)" jnorwood/helm-docs:v1.14.2
```

Open the PR and let CI run. Do not merge it yourself unless asked to.

## 3. Run it for real

```bash
gh workflow run release-train.yml --repo EduIDE/EduIDE-Helm \
-f version=2.3.0 -f dry_run=false
```

Order: validate, build all 14 images, verify they exist and are multi-arch,
**then** tag, then publish. Building before tagging means a flaky image build
costs a re-run rather than stranding immutable tags on repositories whose
images were never published.

## 4. Roll it out separately

The train deploys nothing. In EduIDE-deployment, bump
`spec.platform.chartVersion` in the relevant `environments/*/env.yaml`, in a
pull request. Production is never deployed automatically.

## Version forms

- git tags `vX.Y.Z`
- chart `version`, chart `appVersion` and image tags all `X.Y.Z`
- release candidates `2.3.0-rc.1` throughout

## Common failures

| Message | Meaning |
|---|---|
| `version is 'X', expected 'Y'` | step 2 skipped, or only one chart/field bumped |
| `missing ghcr.io/...` | a component build failed; check that repository's Actions |
| `is not multi-arch` | one architecture failed; re-run the whole build, not just the merge job |
| `tag v2.3.0 already exists` | pick the next version, tags are immutable |
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ jobs:
with:
version: ${{ env.HELM_VERSION }}

- name: AGENTS.md does not reference missing paths
run: ./scripts/check-agents-md.sh

- name: helm lint
run: |
set -euo pipefail
Expand All @@ -40,6 +43,9 @@ jobs:
echo "::endgroup::"
done

- name: App definitions, landing page and preloading agree
run: ./scripts/test-app-consistency.sh

- name: Chart version must be bumped when a chart changes
if: github.event_name == 'pull_request'
run: |
Expand Down Expand Up @@ -103,7 +109,9 @@ jobs:
failed=0
for chart in charts/*/; do
echo "::group::kubeconform $(basename "$chart")"
./scripts/resolve-deps.sh "$chart"
helm template test "$chart" \
--set keycloak.allowUnauthenticated=true \
| kubeconform -strict -summary -ignore-missing-schemas -skip HTTPRoute "${SCHEMAS[@]}" || failed=1
echo "::endgroup::"
done
Expand Down
Loading
Loading