Skip to content

fix(ci): unblock container publication and validate every main run - #619

Merged
Destynova2 merged 2 commits into
mainfrom
fix/container-contract-port-after-restart
Sep 27, 2026
Merged

Destynova2 merged 2 commits into
mainfrom
fix/container-contract-port-after-restart

Conversation

@Destynova2

Copy link
Copy Markdown
Contributor

Problem

CI on main (fa213a0, v0.36.117) failed in Container image (run 36236068303), which skipped Create Release, Homebrew tap and E2E. v0.36.117 is tagged but never published. The three previous main runs were cancelled.

Root causes and fixes

  1. scripts/ci/container-contract.sh captured the host port once; Docker reallocates the ephemeral port of -p 127.0.0.1::8080 after restart, so the post-restart health probe hit a dead port for 30 s. The mapping is now resolved on every attempt.
  2. Containerfile hardcoded x86_64-unknown-linux-musl; the documented podman build failed on arm64 hosts. The musl target now follows the rust image host triple (same approach as deploy/demo/Containerfile).
  3. ci.yml concurrency cancelled the previous main run on each release-plz push, so releases shipped without a completed pipeline. cancel-in-progress now applies to non-main refs only.

Validation

  • podman build --target runtime -f Containerfile on Apple Silicon: builds, grob 0.36.117
  • container-contract.sh end-to-end under podman against both the compiled and prebuilt stages: pass
  • shellcheck, actionlint, prek hooks: pass
  • cargo fmt --check, clippy -D warnings, nextest 1881/1881: pass
  • Not reproduced locally: the Docker port reallocation (podman keeps the port). Diagnosis is from the CI log; this PR's Container image job is the definitive check.

Docker may allocate a different ephemeral host port when a container
started with `-p 127.0.0.1::8080` is restarted. The contract check
captured the mapping once, so the post-restart health probe targeted a
port nobody listened on and the Container image job failed on main
(run 36236068303), which skipped the v0.36.117 release publication.

Resolve the port mapping on every health attempt instead.
- Containerfile hardcoded x86_64-unknown-linux-musl, so the documented
  `podman build` failed on arm64 hosts ("can't find crate for core").
  Derive the musl target from the rust image host triple, matching the
  demo Containerfile, and set the aarch64 linker alongside x86_64.
- The CI concurrency group cancelled the previous main run on every
  release-plz push, so consecutive releases shipped without a completed
  pipeline. Keep cancel-in-progress for PR refs only.
@Destynova2
Destynova2 enabled auto-merge (squash) September 27, 2026 10:57
@Destynova2
Destynova2 merged commit 1c86bd8 into main Sep 27, 2026
41 checks passed
@Destynova2
Destynova2 deleted the fix/container-contract-port-after-restart branch September 27, 2026 11:11
Destynova2 added a commit that referenced this pull request Sep 27, 2026
## 🤖 New release

* `grob`: 0.36.117 -> 0.36.118

<details><summary><i><b>Changelog</b></i></summary><p>

<blockquote>

##
[0.36.118](v0.36.117...v0.36.118)
- 2026-09-27

### Fixed

- *(ci)* unblock container publication and validate every main run
([#619](#619))

### Other

- fix private intra-doc links, drop dead code and duplicate defaults
([#620](#620))
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).
Destynova2 added a commit that referenced this pull request Sep 27, 2026
…h admin contract (#622)

E2E has failed on main since v0.36.112 without anyone noticing, because
the CI concurrency group cancelled most main runs (#619 fixed that) and
the Container job failure masked the rest.

Streaming (regression since #617):
- Output DLP rejected text_delta events with no content_block_start and
  message_stop with an open block. Anthropic-compatible backends such as
the E2E mock do exactly that, so every streaming response was cut after
the first chunk. Missing block boundaries are now synthesised; the text
  is still checked as one complete block before release, and EOF with an
open block still fails closed (a truncated block could split a secret).
- /v1/chat/completions and /v1/responses swallowed mid-stream errors
  without a log line; they now log like /v1/messages does.

Auth tests (contract change in #600, tests never updated):
- POST /api/config/reload requires an admin credential; a tenant JWT is
  403. Tests and advanced/fanout scripts use the server api_key.
- The server api_key is accepted alongside JWT as an operator credential
  instead of being rejected with 401.

E2E runner image downloads hurl/k6/age for TARGETARCH instead of
hardcoded amd64, so the suite runs on arm64 hosts.

## Validation
- Local E2E pod (podman, arm64): `make test-hurl` **9/9 suites** (was
5/9 on main since v0.36.112), `make test-advanced` 10/10, fanout F0
pass.
- nextest 1882/1882 (new test
`missing_block_boundaries_are_synthesised_and_text_still_checked`),
clippy `-D warnings`, shellcheck on touched scripts.
- The E2E job on the push to main after merge is the definitive check
(it does not run on PRs).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant