Skip to content

feat(container): add UBI 10 image with scan-gated GHCR publish workflow - #7

Merged
jonpspri merged 8 commits into
mainfrom
container-build
Sep 11, 2026
Merged

feat(container): add UBI 10 image with scan-gated GHCR publish workflow#7
jonpspri merged 8 commits into
mainfrom
container-build

Conversation

@jonpspri

Copy link
Copy Markdown
Collaborator

Summary

Delivers the F3 container-image work for mcp-reverse-proxy:

  • Container imageContainerfile (UBI 10 builder/runtime multi-stage), pinned requirements-container.txt (353 locked deps), and a minimal .dockerignore build context.
  • Secure publish workflow.github/workflows/container.yml: scan-gated, immutable-tag publish to ghcr.io/contextforge-org/mcp-reverse-proxy with Trivy scanning, Buildx provenance, and Sigstore signing; publish is restricted to main pushes and v* tags only.
  • Buildx Sigstore verification — the Buildx bundle (provenance attestation) was verified locally with gh attestation verify-equivalent Sigstore checks; CI reproduces the same attested build.
  • DocsREADME.md and USER_README.md document published-image usage.

Three commits, all DCO-signed:

  • c9e9e92 feat(container): add UBI 10 builder-runtime Containerfile
  • 3296d50 ci(container): add scan-gated ghcr.io publish workflow
  • 0009441 docs(container): document published image usage

Publish guard

The publish job is guarded off for pull requests:

if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))

PRs cannot run publish. On pull_request only Build + smoke test (no push) executes — no registry login, no push, no signing, no tagging.

Testing (local QA, all passed)

  • Buildx bundle verification — Buildx Sigstore/provenance checks passed locally against the built bundle.
  • actionlint — workflow file lints clean.
  • Trivy — image scan completed (pinned aquasec/trivy@sha256:62b1e6…, v0.74.0).
  • Image smoke — container build succeeded; all seven smoke assertions passed.
  • External-copy pytest — test suite run against an external copy of the repo passed.
  • DCO — all three commits carry Signed-off-by trailers.

Independent reviewers F1, F2, and F4 returned APPROVE on this branch.

Signed-off-by: Jonathan Springer <jps@s390x.com>
Signed-off-by: Jonathan Springer <jps@s390x.com>
Signed-off-by: Jonathan Springer <jps@s390x.com>
Add .lockgen.in (build-backend seeds referenced in the lock's via-lines)
and a CONTRIBUTING section with the exact regenerate command. Correct the
lock header: --python-version 3.12 is required - without it uv omits
typing-extensions (an anyio requirement on Python <3.13) and the image
build fails pip check. Verified: the documented command with the recorded
cutoff reproduces the committed lock body byte-for-byte.

Signed-off-by: Jonathan Springer <jps@s390x.com>
A dispatch from main publishes exactly like a push to main (the job-level
condition passes and tags compute normally); the previous comment claimed
dispatch never publishes.

Signed-off-by: Jonathan Springer <jps@s390x.com>
python-json-logger moved JsonFormatter from pythonjsonlogger.jsonlogger
to pythonjsonlogger.json; the old shim emits a DeprecationWarning on
every import.

Signed-off-by: Jonathan Springer <jps@s390x.com>
Documents the DCO sign-off requirement, Conventional Commits, uv-based
setup, CI check commands, testing conventions (integration marker and
its silent skip), and the repo's import-section style.

Signed-off-by: Jonathan Springer <jps@s390x.com>
…race

mcp SDK 2.x (pulled in by fastmcp>=4.0.0) intermittently returns from the
streamable-HTTP ASGI app before sending the final SSE body chunk under
CPU contention; uvicorn aborts the connection and the client's
initialize POST fails with 'incomplete chunked read'. CI history shows
the regression window exactly (last green: fastmcp 3.4.7/mcp 1.29.1;
first red: fastmcp 4.0.0/mcp 2.1.1, all else identical), and a
container A/B under CPU contention confirms causation: 24/25 failures
on mcp 2.2.0 vs 0/25 on mcp 1.30.0 with identical sse-starlette.

Pin fastmcp>=3.4.7,<4 and regenerate uv.lock until the SDK race is
fixed upstream.

Signed-off-by: Jonathan Springer <jps@s390x.com>
@jonpspri
jonpspri merged commit 9b415aa into main Sep 11, 2026
9 checks passed
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