feat(release): add verified image publication pipeline

This commit is contained in:
2026-08-15 14:52:01 +09:00
parent f7b33784ab
commit fd080496b3
47 changed files with 907 additions and 22 deletions
+56
View File
@@ -0,0 +1,56 @@
# PortfolioHub container publication and operator handoff
## Publication is not deployment
Only a requester-authorized strict `vX.Y.Z` tag push may publish. The workflow builds once and gives the same tested image exactly two selectors:
- `ghcr.io/fourblocks2020/portfolio-hub:<source-commit-first-12>`
- `ghcr.io/fourblocks2020/portfolio-hub:vX.Y.Z`
It never publishes `latest`. The registry digest is the immutable artifact identity:
```text
ghcr.io/fourblocks2020/portfolio-hub@sha256:<64-lowercase-hex-digest>
```
Publication does **not** deploy, place, replace, start, stop, or restart a container in any environment. This repository change adds no production Compose, Kubernetes, Helm, systemd, Dockge, or other deployment configuration. An authorized deployment system and operator must consume the digest separately.
## Operator handoff contract
A successful publication hands the operator or deployment system only these verified inputs:
- exact `vX.Y.Z` source tag;
- full source commit and OCI `org.opencontainers.image.revision`;
- immutable registry digest;
- matching commit-prefix and version selectors;
- successful tested-image workflow evidence.
Before any separately authorized use, verify that the digest and OCI revision identify the intended source. The publication workflow itself does not claim runtime deployment or production readiness.
## Required pre-start migration contract
Database migration is a separate, explicit pre-start operation using the exact image digest and runtime-injected production settings:
1. execute `pfhub migrate-db` as a one-shot operation;
2. stop on nonzero migration result;
3. start the application only after migration succeeds;
4. evaluate HTTP liveness and database readiness separately.
The image's default application command does not run migrations. Do not run migration implicitly from every application replica. Production migration execution remains outside this implementation and requires separate authorization.
## Runtime security inputs
The image contract provides:
- default UID/GID `10001:10001`;
- explicit command `uvicorn app.main:app --host 0.0.0.0 --port 8000`;
- no application-required writable data path;
- migration resources installed inside the Python package.
A deployment system should enforce a read-only root filesystem, dropped capabilities, no-new-privileges, and only a bounded temporary filesystem when needed. PostgreSQL credentials, token configuration, and `CREDENTIAL_ENCRYPTION_KEY` are runtime secrets; they must never be baked into the image or publication artifact. Secret injection and writable-mount configuration belong to the separately authorized deployment environment, not this repository change.
## Image and database rollback boundary
Rollback identity is a previously verified immutable image digest whose OCI revision is known. This document defines that identity boundary only; it does not add or execute rollback automation.
Image rollback is **not** database rollback. Selecting older application bytes does not reverse Alembic migrations, schema or data changes, tokens, or external side effects. Database restore, downgrade, or forward-fix requires a separately reviewed and authorized operational procedure.