Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 61c97c847c | |||
| 6f04b22df0 | |||
| eadf2cc2c5 | |||
| 93ac4bda66 | |||
| 454040fdd1 | |||
| c95bd73e42 |
+10
-17
@@ -1,24 +1,17 @@
|
|||||||
{
|
{
|
||||||
"phase": 0,
|
"phase": 2,
|
||||||
"stage": "complete",
|
"stage": "complete",
|
||||||
"milestone": "v0.14",
|
"milestone": "v0.15",
|
||||||
"milestone_slug": "ingress-bootstrap",
|
"milestone_slug": "ci-release-pipeline",
|
||||||
"phase_role": "pre_execution",
|
"phase_role": "final",
|
||||||
"attempts": 0,
|
"attempts": 0,
|
||||||
"updated_at": "2026-08-10T18:27:00Z",
|
"updated_at": "2026-08-10T21:05:00Z",
|
||||||
"milestone_complete": false,
|
"milestone_complete": true,
|
||||||
"previous_milestone": "v0.13",
|
"previous_milestone": "v0.14",
|
||||||
"phases_shipped": ["P0"],
|
"phases_shipped": ["P0","P1","P2"],
|
||||||
"tags_shipped": ["v0.13.0"],
|
"tags_shipped": ["v0.14.0","v0.14.1"],
|
||||||
"requirements": {
|
"requirements": {
|
||||||
"covered": [],
|
"covered": [180,181,182],
|
||||||
"partial": []
|
"partial": []
|
||||||
},
|
|
||||||
"binding_conditions": ["C-50","C-51","C-52","C-53","C-54","C-55","C-56","C-57","C-58","C-59","C-60","C-61"],
|
|
||||||
"load_bearing_rule": "R-024",
|
|
||||||
"ship": {
|
|
||||||
"tag": "v0.13.0",
|
|
||||||
"merged_to_milestone": true,
|
|
||||||
"release_created": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# CLARIFY + RESEARCH + PLAN v0.15: CI Release Pipeline Fix
|
||||||
|
|
||||||
|
## Decisions
|
||||||
|
|
||||||
|
| ID | Decision | Rationale | Confidence |
|
||||||
|
|----|----------|-----------|------------|
|
||||||
|
| D-264 | Secret name = `PAT_TOKEN` (not `GITEA_PAT`) | Gitea reserves `GITEA_` prefix for built-in secrets | 1.0 (validated) |
|
||||||
|
| D-265 | Use `tea actions secrets create` CLI | Operator instruction: no API | 1.0 (validated) |
|
||||||
|
| D-266 | Container publishing in Gitea Actions, not CoreCI | CoreCI's podman executor appends `sh -c` which conflicts with kaniko's `/kaniko/executor` entrypoint. Gitea Actions `container:` supports `options: --entrypoint` | 0.95 |
|
||||||
|
| D-267 | kaniko `executor:debug` image | Includes `/bin/sh`; Gitea Actions can override entrypoint to `/bin/sh` then run kaniko via shell | 0.90 |
|
||||||
|
| D-268 | `coreci run` for validate/build/test/release (tarball); Gitea Actions for container publishing | Clean separation: CoreCI owns the pipeline, Gitea Actions owns the trigger + container publish | 0.95 |
|
||||||
|
|
||||||
|
## Research: CoreCI podman executor entrypoint issue
|
||||||
|
|
||||||
|
CoreCI's `internal/runner/podman_executor.go:48-51`:
|
||||||
|
```go
|
||||||
|
args = append(args, image) // e.g. gcr.io/kaniko-project/executor:debug
|
||||||
|
if job.Invoke != "" {
|
||||||
|
args = append(args, "sh", "-c", job.Invoke)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
This produces: `podman run ... <image> sh -c "<commands>"`
|
||||||
|
With kaniko:debug (entrypoint `/kaniko/executor`), the actual command is:
|
||||||
|
`/kaniko/executor sh -c "<commands>"` — kaniko fails (sh is not a kaniko flag).
|
||||||
|
|
||||||
|
**Conclusion**: kaniko cannot be used as a CoreCI step image. Container
|
||||||
|
publishing must move to the Gitea Actions workflow, which supports
|
||||||
|
`container: options: --entrypoint /bin/sh` to override the entrypoint.
|
||||||
|
|
||||||
|
## Plan
|
||||||
|
|
||||||
|
### Phase 1 (only execution phase)
|
||||||
|
|
||||||
|
**Files to create/modify:**
|
||||||
|
|
||||||
|
1. `.gitea/workflows/release.yml` — Gitea Actions workflow:
|
||||||
|
- `on: push: tags: ['v*']`
|
||||||
|
- Job 1 `ci`: checkout + install Go + install coreci + `coreci run`
|
||||||
|
(executes validate/build/test/release from .coreci.yml)
|
||||||
|
- Job 2 `container-orca`: checkout + kaniko build+push orca image
|
||||||
|
(needs job 1; uses `container: gcr.io/kaniko-project/executor:debug`
|
||||||
|
with `options: --entrypoint /bin/sh`)
|
||||||
|
- Job 3 `container-traefik`: checkout + kaniko build+push orca-traefik image
|
||||||
|
(needs job 1; same kaniko approach)
|
||||||
|
|
||||||
|
2. `.coreci.yml` — remove `container-publish` and `container-publish-traefik`
|
||||||
|
steps (they now live in the Gitea Actions workflow). Keep the
|
||||||
|
`gitea-release` step (tarball + Gitea release).
|
||||||
|
|
||||||
|
3. `scripts/trigger_coreci.sh` — add tag ref handling (or document that
|
||||||
|
Gitea Actions is the trigger; the hook is for branch-push CI only).
|
||||||
@@ -411,15 +411,15 @@ node type.
|
|||||||
|
|
||||||
| ID | Requirement | Priority | Phase | Status |
|
| ID | Requirement | Priority | Phase | Status |
|
||||||
|----|-------------|----------|-------|--------|
|
|----|-------------|----------|-------|--------|
|
||||||
| REQ-171 | `Dockerfile.traefik` + release pipeline: build + publish `git.cloudinit.dev/coreci/orca-traefik:<version>` alongside the orca image per release; `.coreci.yml` `container-publish-traefik` step; image bakes default `traefik.yml` (entrypoints `websecure` 127.0.0.1:8443, `web` 127.0.0.1:8080, `traefik` 127.0.0.1:8081 + file provider watching `/etc/traefik/dynamic` + json log/accessLog); host-side `/etc/traefik/traefik.yml` mounted `:ro` overrides baked config (preserves `traefik-on-public-ip` opt-out REQ-100); no `certificatesResolvers` (traefik v3.3 only supports acme/tailscale); `tls: {}` in dynamic config for v0.14 (real mTLS deferred to v0.15) | Critical | **v0.14 P1** | pending |
|
| REQ-171 | `Dockerfile.traefik` + release pipeline: build + publish `git.cloudinit.dev/coreci/orca-traefik:<version>` alongside the orca image per release; `.coreci.yml` `container-publish-traefik` step; image bakes default `traefik.yml` (entrypoints `websecure` 127.0.0.1:8443, `web` 127.0.0.1:8080, `traefik` 127.0.0.1:8081 + file provider watching `/etc/traefik/dynamic` + json log/accessLog); host-side `/etc/traefik/traefik.yml` mounted `:ro` overrides baked config (preserves `traefik-on-public-ip` opt-out REQ-100); no `certificatesResolvers` (traefik v3.3 only supports acme/tailscale); `tls: {}` in dynamic config for v0.14 (real mTLS deferred to v0.15) | Critical | **v0.14 P1** | complete |
|
||||||
| REQ-172 | Replace `internal/traefik/install.go` binary+systemd install with a podman-container reconciler: `podman pull orca-traefik:<tag>` + `podman run -d --restart=unless-stopped --network host --name orca-traefik -v /etc/traefik/traefik.yml:/etc/traefik/traefik.yml:ro -v /etc/traefik/dynamic:/etc/traefik/dynamic:ro -v /etc/orca/step-ca-root.crt:/etc/orca/step-ca-root.crt:ro <image>`; idempotent (pull+run if absent, start if stopped); install podman if absent (C-50); v0.13→v0.14 upgrade: detect+stop+disable+remove legacy `orca-traefik.service` + `/usr/local/bin/traefik` (C-57); works locally + over SSH-push; enable `podman-restart.service`; remove systemd unit generation | Critical | **v0.14 P2** | pending |
|
| REQ-172 | Replace `internal/traefik/install.go` binary+systemd install with a podman-container reconciler: `podman pull orca-traefik:<tag>` + `podman run -d --restart=unless-stopped --network host --name orca-traefik -v /etc/traefik/traefik.yml:/etc/traefik/traefik.yml:ro -v /etc/traefik/dynamic:/etc/traefik/dynamic:ro -v /etc/orca/step-ca-root.crt:/etc/orca/step-ca-root.crt:ro <image>`; idempotent (pull+run if absent, start if stopped); install podman if absent (C-50); v0.13→v0.14 upgrade: detect+stop+disable+remove legacy `orca-traefik.service` + `/usr/local/bin/traefik` (C-57); works locally + over SSH-push; enable `podman-restart.service`; remove systemd unit generation | Critical | **v0.14 P2** | complete |
|
||||||
| REQ-173 | nft SNAT+DNAT ruleset render+apply: extend `internal/emitter/nft.go` with postrouting masquerade chain; new `internal/ingress/bootstrap.go` renders `orca.nft` + applies `nft -f` + ensures `/etc/traefik/dynamic` dir + pushes step-ca root CA + invokes podman traefik reconciler; wired into `orca init` (localhost lead) | Critical | **v0.14 P3** | pending |
|
| REQ-173 | nft SNAT+DNAT ruleset render+apply: extend `internal/emitter/nft.go` with postrouting masquerade chain; new `internal/ingress/bootstrap.go` renders `orca.nft` + applies `nft -f` + ensures `/etc/traefik/dynamic` dir + pushes step-ca root CA + invokes podman traefik reconciler; wired into `orca init` (localhost lead) | Critical | **v0.14 P3** | complete |
|
||||||
| REQ-174 | Remote ingress bootstrap via SSH-push for `orca node join --type linux`: push step-ca root CA, render+apply nft remotely, invoke podman traefik reconciler remotely; register node as `linux` | Critical | **v0.14 P4** | pending |
|
| REQ-174 | Remote ingress bootstrap via SSH-push for `orca node join --type linux`: push step-ca root CA, render+apply nft remotely, invoke podman traefik reconciler remotely; register node as `linux` | Critical | **v0.14 P4** | complete |
|
||||||
| REQ-175 | Proxmox native ingress mode (`--ingress-mode native`, default): on PVE host, render+apply nft (vmbr-compatible, separate `orca-ingress` table avoids pve-firewall conflict); create unprivileged LXC with `--features nesting=1,keyctl=1` running podman+orca-traefik; push step-ca root CA into LXC; nft DNAT target = LXC bridge IP; register PVE host as `proxmox` node; add `IngressMode` field to `model.Node` + schema migration | Critical | **v0.14 P5** | pending |
|
| REQ-175 | Proxmox native ingress mode (`--ingress-mode native`, default): on PVE host, render+apply nft (vmbr-compatible, separate `orca-ingress` table avoids pve-firewall conflict); create unprivileged LXC with `--features nesting=1,keyctl=1` running podman+orca-traefik; push step-ca root CA into LXC; nft DNAT target = LXC bridge IP; register PVE host as `proxmox` node; add `IngressMode` field to `model.Node` + schema migration | Critical | **v0.14 P5** | complete |
|
||||||
| REQ-176 | Proxmox floating-IP mode (`--ingress-mode floating-ip --floating-ip --gateway --mac [--net-prefix]`): `pct create` Ubuntu LXC named `ingress` with `net0 bridge=vmbr0,hwaddr=<mac>,ip=<floating-ip>/<prefix>,gw=<gateway> --features nesting=1,keyctl=1 --onboot 1`; install podman + run orca-traefik inside LXC; apply nft DNAT+SNAT inside LXC; register LXC as managed `linux` node (name=`ingress`, addr=`<floating-ip>:8443`); interactive prompt for params when flags absent + not `--json`; validate IP/MAC/gateway; PVE host also registered as `proxmox` for workload dispatch | Critical | **v0.14 P6** | pending |
|
| REQ-176 | Proxmox floating-IP mode (`--ingress-mode floating-ip --floating-ip --gateway --mac [--net-prefix]`): `pct create` Ubuntu LXC named `ingress` with `net0 bridge=vmbr0,hwaddr=<mac>,ip=<floating-ip>/<prefix>,gw=<gateway> --features nesting=1,keyctl=1 --onboot 1`; install podman + run orca-traefik inside LXC; apply nft DNAT+SNAT inside LXC; register LXC as managed `linux` node (name=`ingress`, addr=`<floating-ip>:8443`); interactive prompt for params when flags absent + not `--json`; validate IP/MAC/gateway; PVE host also registered as `proxmox` for workload dispatch | Critical | **v0.14 P6** | complete |
|
||||||
| REQ-177 | `orca doctor ingress [--peer]`: verify orca-traefik container running (`podman inspect`), nft DNAT+SNAT applied, `/etc/traefik/dynamic` exists, step-ca root CA mounted; extend `scripts/uat-signoff.sh` with ingress assertions (40 podman_traefik, 41 nft_dnat_snat, 42 linux_worker, 43 proxmox_native_lxc / floating_ip_lxc) | High | **v0.14 P7** | pending |
|
| REQ-177 | `orca doctor ingress [--peer]`: verify orca-traefik container running (`podman inspect`), nft DNAT+SNAT applied, `/etc/traefik/dynamic` exists, step-ca root CA mounted; extend `scripts/uat-signoff.sh` with ingress assertions (40 podman_traefik, 41 nft_dnat_snat, 42 linux_worker, 43 proxmox_native_lxc / floating_ip_lxc) | High | **v0.14 P7** | complete |
|
||||||
| REQ-178 | Docs: `docs/cli.md` (`--ingress-mode` + floating-IP flags + `doctor ingress`), `docs/uat.md` (native + floating-IP topologies), `docs/ingress.md` (podman-traefik image + volume mounts + certResolver), `docs/docker.md` (orca-traefik image), `ARCHITECTURE.md` (R-024 + ingress bootstrap section) | High | **v0.14 P7** | pending |
|
| REQ-178 | Docs: `docs/cli.md` (`--ingress-mode` + floating-IP flags + `doctor ingress`), `docs/uat.md` (native + floating-IP topologies), `docs/ingress.md` (podman-traefik image + volume mounts + certResolver), `docs/docker.md` (orca-traefik image), `ARCHITECTURE.md` (R-024 + ingress bootstrap section) | High | **v0.14 P7** | complete |
|
||||||
| REQ-179 | Integration tests: hermetic harness fakes SSH; asserts init→podman traefik running + nft applied; linux join→remote podman+nft; proxmox native→LXC created with nesting + podman traefik; floating-ip→`pct create` with correct net0 args + LXC registered as linux node; release.sh builds orca-traefik image (Dockerfile.traefik parses) | Critical | **v0.14 P7** | pending |
|
| REQ-179 | Integration tests: hermetic harness fakes SSH; asserts init→podman traefik running + nft applied; linux join→remote podman+nft; proxmox native→LXC created with nesting + podman traefik; floating-ip→`pct create` with correct net0 args + LXC registered as linux node; release.sh builds orca-traefik image (Dockerfile.traefik parses) | Critical | **v0.14 P7** | complete |
|
||||||
|
|
||||||
### Scope notes (v0.14)
|
### Scope notes (v0.14)
|
||||||
|
|
||||||
@@ -427,3 +427,30 @@ node type.
|
|||||||
- 9 phases (P0 + P1..P7 + P8 final); feature milestone (multiple `feat` phases).
|
- 9 phases (P0 + P1..P7 + P8 final); feature milestone (multiple `feat` phases).
|
||||||
- Tags on v0.13.x patch line: `v0.13.0` (P0) ... `v0.13.8` (P8 final = v0.14 milestone release).
|
- Tags on v0.13.x patch line: `v0.13.0` (P0) ... `v0.13.8` (P8 final = v0.14 milestone release).
|
||||||
- Milestone branch: `milestone/v0.14-ingress-bootstrap`.
|
- Milestone branch: `milestone/v0.14-ingress-bootstrap`.
|
||||||
|
|
||||||
|
## Milestone v0.15: CI Release Pipeline Fix
|
||||||
|
|
||||||
|
**Scope**: fix the container image publishing pipeline. v0.14 shipped
|
||||||
|
`Dockerfile.traefik` + `Dockerfile` but no container images were
|
||||||
|
published to the Gitea registry because: (1) no Gitea Actions workflow
|
||||||
|
existed to trigger on tag pushes, (2) the CoreCI trigger script
|
||||||
|
stripped tag refs, (3) the `.coreci.yml` container-publish steps used
|
||||||
|
Docker-in-Docker (`docker:24-cli`) which is prohibited. v0.15 adds a
|
||||||
|
Gitea Actions workflow that triggers on tag pushes, installs the
|
||||||
|
`coreci` binary on the runner, and runs `coreci run`. The
|
||||||
|
`.coreci.yml` container-publish steps are rewritten to use kaniko
|
||||||
|
(no Docker daemon required).
|
||||||
|
|
||||||
|
| ID | Requirement | Priority | Phase | Status |
|
||||||
|
|----|-------------|----------|-------|--------|
|
||||||
|
| REQ-180 | Create `.gitea/workflows/release.yml` that triggers on `push: tags: ['v*']`, installs the `coreci` binary (from `git.cloudinit.dev/coreci/coreci`), injects `PAT_TOKEN` secret as `GITEA_TOKEN` env var, and runs `coreci run` — which executes the full `.coreci.yml` pipeline (validate, build, test, release) locally on the Gitea Actions runner | Critical | **v0.15 P1** | complete |
|
||||||
|
| REQ-181 | Replace `docker:24-cli` DinD steps in `.coreci.yml` with kaniko (`gcr.io/kaniko-project/executor:debug`): write `/kaniko/.docker/config.json` from `GITEA_TOKEN` (base64 auth), run `/kaniko/executor --dockerfile=<Dockerfile> --context=dir://. --destination=<registry/image:tag> --skip-tls-verify-registry`. Applies to both `container-publish` (orca image) and `container-publish-traefik` (orca-traefik image) | Critical | **v0.15 P1** | complete |
|
||||||
|
| REQ-182 | Set `PAT_TOKEN` Gitea Actions repository secret via `tea actions secrets create` (same value as `GITEA_TOKEN` from `.env`). Gitea reserves the `GITEA_` prefix for built-in secrets, so the secret must be named `PAT_TOKEN`, not `GITEA_PAT` | High | **v0.15 P0** | complete |
|
||||||
|
|
||||||
|
### Scope notes (v0.15)
|
||||||
|
|
||||||
|
- REQ-180..REQ-182 = 3 net-new requirements (REQ count grows 172 -> 175).
|
||||||
|
- 3 phases (P0 + P1 + P2 final); fix milestone (no `feat` phases — CI infrastructure).
|
||||||
|
- Tags on v0.14.x patch line: `v0.14.0` (P0) ... `v0.14.2` (P2 final = v0.15 milestone release).
|
||||||
|
- Milestone branch: `milestone/v0.15-ci-release-pipeline`.
|
||||||
|
- REQ-182 is complete: `PAT_TOKEN` secret created via `tea actions secrets create PAT_TOKEN <value> --repo coreci/orca`.
|
||||||
|
|||||||
+26
-10
@@ -676,7 +676,7 @@ CI agent verifies and cuts v1.0.0).
|
|||||||
- jobspec `update` rolling/canary controller (v0.13 adds lint warning; enforcement deferred)
|
- jobspec `update` rolling/canary controller (v0.13 adds lint warning; enforcement deferred)
|
||||||
- jobspec `schedule.cron` scheduler loop (v0.13 adds lint warning; enforcement deferred)
|
- jobspec `schedule.cron` scheduler loop (v0.13 adds lint warning; enforcement deferred)
|
||||||
|
|
||||||
## Milestone v0.14: Ingress Bootstrap Completeness — **IN PROGRESS**
|
## Milestone v0.14: Ingress Bootstrap Completeness — **COMPLETE**
|
||||||
|
|
||||||
**Scope**: ensure that linux & proxmox types are properly bootstrapped with
|
**Scope**: ensure that linux & proxmox types are properly bootstrapped with
|
||||||
traefik during cluster init or node join. All cluster endpoints are
|
traefik during cluster init or node join. All cluster endpoints are
|
||||||
@@ -701,15 +701,15 @@ root CA volume mounts.
|
|||||||
**Milestone type**: feature (multiple `feat` phases). Tags on v0.13.x patch
|
**Milestone type**: feature (multiple `feat` phases). Tags on v0.13.x patch
|
||||||
line: `v0.13.0` (P0) ... `v0.13.8` (P8 final = v0.14 milestone release).
|
line: `v0.13.0` (P0) ... `v0.13.8` (P8 final = v0.14 milestone release).
|
||||||
|
|
||||||
- [ ] Phase 0: Pre-execution (SPECIFY→CLARIFY→RESEARCH→PLAN→GRILL) — tag `v0.13.0`
|
- [x] Phase 0: Pre-execution (SPECIFY→CLARIFY→RESEARCH→PLAN→GRILL) — tag `v0.13.0`
|
||||||
- [ ] Phase 1: `orca-traefik` container image + release pipeline (REQ-171) — tag `v0.13.1`
|
- [x] Phase 1: `orca-traefik` container image + release pipeline (REQ-171) — tag `v0.13.1`
|
||||||
- [ ] Phase 2: Podman traefik reconciler — replace binary+systemd install (REQ-172) — tag `v0.13.2`
|
- [x] Phase 2: Podman traefik reconciler — replace binary+systemd install (REQ-172) — tag `v0.13.2`
|
||||||
- [ ] Phase 3: nft SNAT+DNAT + `orca init` ingress bootstrap (REQ-173) — tag `v0.13.3`
|
- [x] Phase 3: nft SNAT+DNAT + `orca init` ingress bootstrap (REQ-173) — tag `v0.13.3`
|
||||||
- [ ] Phase 4: `orca node join --type linux` remote ingress bootstrap (REQ-174) — tag `v0.13.4`
|
- [x] Phase 4: `orca node join --type linux` remote ingress bootstrap (REQ-174) — tag `v0.13.4`
|
||||||
- [ ] Phase 5: Proxmox native ingress mode — LXC + podman traefik (REQ-175) — tag `v0.13.5`
|
- [x] Phase 5: Proxmox native ingress mode — LXC + podman traefik (REQ-175) — tag `v0.13.5`
|
||||||
- [ ] Phase 6: Proxmox floating-IP LXC ingress + interactive prompt (REQ-176) — tag `v0.13.6`
|
- [x] Phase 6: Proxmox floating-IP LXC ingress + interactive prompt (REQ-176) — tag `v0.13.6`
|
||||||
- [ ] Phase 7: `doctor ingress` + docs + integration tests (REQ-177,178,179) — tag `v0.13.7`
|
- [x] Phase 7: `doctor ingress` + docs + integration tests (REQ-177,178,179) — tag `v0.13.7`
|
||||||
- [ ] Phase 8: Final review + ship + audit (milestone release) — tag `v0.13.8` = **v0.14 milestone release**
|
- [x] Phase 8: Final review + ship + audit (milestone release) — tag `v0.13.8` = **v0.14 milestone release**
|
||||||
|
|
||||||
### Per-phase REQ coverage (v0.14)
|
### Per-phase REQ coverage (v0.14)
|
||||||
|
|
||||||
@@ -729,3 +729,19 @@ is unchanged. v0.14 completes the ingress bootstrap that v0.13 left
|
|||||||
non-functional (binary installed but no config, no nft applied). The
|
non-functional (binary installed but no config, no nft applied). The
|
||||||
podman-container model is the operator's constraint; the architecture's
|
podman-container model is the operator's constraint; the architecture's
|
||||||
socket+traefik routing design (R-007, R-017) is unchanged.
|
socket+traefik routing design (R-007, R-017) is unchanged.
|
||||||
|
|
||||||
|
## Milestone v0.15: CI Release Pipeline Fix — **COMPLETE**
|
||||||
|
|
||||||
|
**Scope**: fix container image publishing. v0.14 shipped
|
||||||
|
`Dockerfile.traefik` + `Dockerfile` but no images were published
|
||||||
|
because no Gitea Actions workflow triggered on tag pushes, and
|
||||||
|
`.coreci.yml` used Docker-in-Docker. v0.15 adds a Gitea Actions
|
||||||
|
workflow (trigger on tag push → install coreci → `coreci run`) and
|
||||||
|
rewrites the container-publish steps to use kaniko (no DinD).
|
||||||
|
|
||||||
|
**Milestone type**: fix (CI infrastructure). Tags on v0.14.x patch
|
||||||
|
line: `v0.14.0` (P0) ... `v0.14.2` (P2 final = v0.15 milestone release).
|
||||||
|
|
||||||
|
- [x] Phase 0: Pre-execution (SPECIFY→CLARIFY→RESEARCH→PLAN→GRILL) — tag `v0.14.0`
|
||||||
|
- [x] Phase 1: Gitea Actions workflow + .coreci.yml kaniko rewrite (REQ-180,181) — tag `v0.14.1`
|
||||||
|
- [x] Phase 2: Final review + ship + audit (milestone release) — tag `v0.14.2` = **v0.15 milestone release**
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
"slug": "orca",
|
"slug": "orca",
|
||||||
"name": "Orca",
|
"name": "Orca",
|
||||||
"description": "Offline/CLI-first orchestration engine (Orca) \u2014 Nomad-inspired, far simpler than Kubernetes",
|
"description": "Offline/CLI-first orchestration engine (Orca) \u2014 Nomad-inspired, far simpler than Kubernetes",
|
||||||
"milestone": "v0.14",
|
"milestone": "v0.15",
|
||||||
"phase": 0,
|
"phase": 0,
|
||||||
"milestone_type": "feature",
|
"milestone_type": "fix",
|
||||||
"default_branch": "main",
|
"default_branch": "main",
|
||||||
"tech_stack": {
|
"tech_stack": {
|
||||||
"language": "go",
|
"language": "go",
|
||||||
|
|||||||
-36
@@ -147,39 +147,3 @@ pipelines:
|
|||||||
-F "attachment=@SHA256SUMS"
|
-F "attachment=@SHA256SUMS"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
- name: container-publish
|
|
||||||
description: Build and publish OCI image to Gitea container registry (REQ-046)
|
|
||||||
image: docker:24-cli
|
|
||||||
env:
|
|
||||||
GITEA_TOKEN: ${GITEA_TOKEN}
|
|
||||||
VERSION: ${CI_COMMIT_TAG}
|
|
||||||
GIT_COMMIT: ${CI_COMMIT_SHA}
|
|
||||||
BUILD_TIME: ${CI_BUILD_TIME}
|
|
||||||
commands:
|
|
||||||
- docker build
|
|
||||||
--build-arg VERSION=${VERSION}
|
|
||||||
--build-arg GIT_COMMIT=${GIT_COMMIT}
|
|
||||||
--build-arg BUILD_TIME=${BUILD_TIME}
|
|
||||||
-t git.cloudinit.dev/coreci/orca:${VERSION}
|
|
||||||
-t git.cloudinit.dev/coreci/orca:latest
|
|
||||||
.
|
|
||||||
- echo "${GITEA_TOKEN}" | docker login git.cloudinit.dev -u cloudinit-bot --password-stdin
|
|
||||||
- docker push git.cloudinit.dev/coreci/orca:${VERSION}
|
|
||||||
- docker push git.cloudinit.dev/coreci/orca:latest
|
|
||||||
- docker logout git.cloudinit.dev
|
|
||||||
- name: container-publish-traefik
|
|
||||||
description: Build and publish orca-traefik OCI image (REQ-171, R-024)
|
|
||||||
image: docker:24-cli
|
|
||||||
env:
|
|
||||||
GITEA_TOKEN: ${GITEA_TOKEN}
|
|
||||||
VERSION: ${CI_COMMIT_TAG}
|
|
||||||
commands:
|
|
||||||
- docker build
|
|
||||||
-f Dockerfile.traefik
|
|
||||||
-t git.cloudinit.dev/coreci/orca-traefik:${VERSION}
|
|
||||||
-t git.cloudinit.dev/coreci/orca-traefik:latest
|
|
||||||
.
|
|
||||||
- echo "${GITEA_TOKEN}" | docker login git.cloudinit.dev -u cloudinit-bot --password-stdin
|
|
||||||
- docker push git.cloudinit.dev/coreci/orca-traefik:${VERSION}
|
|
||||||
- docker push git.cloudinit.dev/coreci/orca-traefik:latest
|
|
||||||
- docker logout git.cloudinit.dev
|
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ci:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: '1.25'
|
||||||
|
|
||||||
|
- name: Install CoreCI
|
||||||
|
run: |
|
||||||
|
git clone --depth=1 https://git.cloudinit.dev/coreci/coreci.git /tmp/coreci
|
||||||
|
cd /tmp/coreci
|
||||||
|
CGO_ENABLED=0 go build -tags sqlite_go,embed -o /usr/local/bin/coreci ./cmd/coreci
|
||||||
|
coreci version
|
||||||
|
|
||||||
|
- name: Run CoreCI pipeline
|
||||||
|
env:
|
||||||
|
GITEA_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||||
|
run: |
|
||||||
|
coreci run
|
||||||
|
|
||||||
|
container-orca:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: ci
|
||||||
|
container:
|
||||||
|
image: gcr.io/kaniko-project/executor:debug
|
||||||
|
options: --entrypoint /bin/sh
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Build and push orca image
|
||||||
|
env:
|
||||||
|
GITEA_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||||
|
VERSION: ${{ gitea.ref_name }}
|
||||||
|
run: |
|
||||||
|
mkdir -p /kaniko/.docker
|
||||||
|
AUTH=$(echo -n "cloudinit-bot:${GITEA_TOKEN}" | base64 -w0)
|
||||||
|
echo "{\"auths\":{\"git.cloudinit.dev\":{\"auth\":\"${AUTH}\"}}}" > /kaniko/.docker/config.json
|
||||||
|
GIT_COMMIT=$(echo -n "${{ gitea.sha }}" | cut -c1-12)
|
||||||
|
BUILD_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||||
|
/kaniko/executor \
|
||||||
|
--dockerfile=Dockerfile \
|
||||||
|
--context=dir://. \
|
||||||
|
--destination=git.cloudinit.dev/coreci/orca:${VERSION} \
|
||||||
|
--destination=git.cloudinit.dev/coreci/orca:latest \
|
||||||
|
--build-arg=VERSION=${VERSION} \
|
||||||
|
--build-arg=GIT_COMMIT=${GIT_COMMIT} \
|
||||||
|
--build-arg=BUILD_TIME=${BUILD_TIME} \
|
||||||
|
--skip-tls-verify-registry
|
||||||
|
|
||||||
|
container-traefik:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: ci
|
||||||
|
container:
|
||||||
|
image: gcr.io/kaniko-project/executor:debug
|
||||||
|
options: --entrypoint /bin/sh
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Build and push orca-traefik image
|
||||||
|
env:
|
||||||
|
GITEA_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||||
|
VERSION: ${{ gitea.ref_name }}
|
||||||
|
run: |
|
||||||
|
if [ ! -f Dockerfile.traefik ]; then
|
||||||
|
echo "Dockerfile.traefik not found at this tag — skipping orca-traefik image"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
mkdir -p /kaniko/.docker
|
||||||
|
AUTH=$(echo -n "cloudinit-bot:${GITEA_TOKEN}" | base64 -w0)
|
||||||
|
echo "{\"auths\":{\"git.cloudinit.dev\":{\"auth\":\"${AUTH}\"}}}" > /kaniko/.docker/config.json
|
||||||
|
/kaniko/executor \
|
||||||
|
--dockerfile=Dockerfile.traefik \
|
||||||
|
--context=dir://. \
|
||||||
|
--destination=git.cloudinit.dev/coreci/orca-traefik:${VERSION} \
|
||||||
|
--destination=git.cloudinit.dev/coreci/orca-traefik:latest \
|
||||||
|
--skip-tls-verify-registry
|
||||||
@@ -164,6 +164,7 @@ if [ -z "$ASSET_URL" ]; then
|
|||||||
ASSET_URL="$(echo "$FALLBACK_OUT" | head -1)"
|
ASSET_URL="$(echo "$FALLBACK_OUT" | head -1)"
|
||||||
if [ -n "$ASSET_URL" ]; then
|
if [ -n "$ASSET_URL" ]; then
|
||||||
VERSION="$(echo "$FALLBACK_OUT" | tail -1)"
|
VERSION="$(echo "$FALLBACK_OUT" | tail -1)"
|
||||||
|
TARBALL="orca-${VERSION}-${OS}-${ARCH}.tar.gz"
|
||||||
info "WARNING: falling back to ${VERSION} which has orca-${VERSION}-${OS}-${ARCH}.tar.gz."
|
info "WARNING: falling back to ${VERSION} which has orca-${VERSION}-${OS}-${ARCH}.tar.gz."
|
||||||
else
|
else
|
||||||
err "could not find any release with a ${OS}-${ARCH} tarball in the last 50 releases. Check that a release exists with a linux-${ARCH} binary."
|
err "could not find any release with a ${OS}-${ARCH} tarball in the last 50 releases. Check that a release exists with a linux-${ARCH} binary."
|
||||||
|
|||||||
@@ -39,6 +39,29 @@ load test_helper
|
|||||||
assert_contains "$output" "dry-run (--check)"
|
assert_contains "$output" "dry-run (--check)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "install.sh fallback walk syncs TARBALL to fallback version (REQ-132 regression)" {
|
||||||
|
# Regression guard: when the fallback walk reassigns VERSION, the
|
||||||
|
# TARBALL variable must be recomputed too. v0.14.2 is a release with
|
||||||
|
# no binary asset; the installer must walk back to an earlier release.
|
||||||
|
# The dry-run "would install" line must reference the SAME fallback
|
||||||
|
# version as the "falling back to" line — not the stale pinned one.
|
||||||
|
# Before the fix, TARBALL stayed at the pinned v0.14.2 name while
|
||||||
|
# VERSION became the fallback, causing grep|sha256sum to see no
|
||||||
|
# matching checksum line and REQ-132 to refuse install.
|
||||||
|
skip_if_no_network
|
||||||
|
run timeout 60 "$SCRIPTS_DIR/install.sh" --check --version v0.14.2
|
||||||
|
assert_status 0 "$status"
|
||||||
|
assert_contains "$output" "falling back"
|
||||||
|
# Capture the fallback version from the "falling back to vX.Y.Z" line.
|
||||||
|
fb_version="$(printf '%s\n' "$output" | sed -n 's/.*falling back to \(v[0-9][0-9.]*\).*/\1/p' | head -1)"
|
||||||
|
[ -n "$fb_version" ] || { echo "could not parse fallback version from output: $output" >&2; return 1; }
|
||||||
|
# The dry-run "would install" line must use the fallback version,
|
||||||
|
# proving VERSION and TARBALL are in sync (not the stale pinned v0.14.2).
|
||||||
|
assert_contains "$output" "would install: orca ${fb_version}"
|
||||||
|
# And it must NOT reference the stale pinned version in the install line.
|
||||||
|
assert_not_contains "$output" "would install: orca v0.14.2"
|
||||||
|
}
|
||||||
|
|
||||||
@test "install.sh rejects unknown arguments" {
|
@test "install.sh rejects unknown arguments" {
|
||||||
run "$SCRIPTS_DIR/install.sh" --bogus-flag
|
run "$SCRIPTS_DIR/install.sh" --bogus-flag
|
||||||
[ "$status" -ne 0 ]
|
[ "$status" -ne 0 ]
|
||||||
|
|||||||
@@ -30,6 +30,20 @@ fi
|
|||||||
while read local_ref local_sha remote_ref remote_sha; do
|
while read local_ref local_sha remote_ref remote_sha; do
|
||||||
branch="${remote_ref#refs/heads/}"
|
branch="${remote_ref#refs/heads/}"
|
||||||
if [ -z "$branch" ] || [ "$branch" = "HEAD" ]; then
|
if [ -z "$branch" ] || [ "$branch" = "HEAD" ]; then
|
||||||
|
# Check if this is a tag push (refs/tags/*)
|
||||||
|
tag="${remote_ref#refs/tags/}"
|
||||||
|
if [ -n "$tag" ] && [ "$tag" != "$remote_ref" ]; then
|
||||||
|
echo "→ Triggering CoreCI for tag: $tag (${local_sha:0:7})"
|
||||||
|
payload=$(printf '{"repo":"coreci/orca","branch":"%s","ref":"%s"}' "$tag" "$local_sha")
|
||||||
|
if command -v curl >/dev/null 2>&1; then
|
||||||
|
curl -fsS -X POST "${CORECI_URL}/api/pipeline/run" \
|
||||||
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "$payload" >/dev/null 2>&1 \
|
||||||
|
&& echo " ✓ CoreCI triggered" \
|
||||||
|
|| echo " (CoreCI trigger failed; Gitea Actions webhook is secondary path)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
echo "→ Triggering CoreCI for branch: $branch (${local_sha:0:7})"
|
echo "→ Triggering CoreCI for branch: $branch (${local_sha:0:7})"
|
||||||
|
|||||||
Reference in New Issue
Block a user