3.5 KiB
3.5 KiB
Developer Portal Publishing Guide
Last updated: 2025-11-25
Goals
- Publish the StellaOps Developer Portal consistently across connected and air-gapped environments.
- Produce deterministic artefacts (checksums, manifests) so releases are auditable and reproducible.
- Keep docs, API specs, and examples in sync with the CI pipelines that build the portal.
Prerequisites
- Node.js 20.x + pnpm 9.x
- Docker / Podman (for static-site container image)
- Spectral lint baseline from
src/Api/StellaOps.Api.OpenApi(optional, to embed OAS links) - Access to
local-nugets/cache and offline asset bundle (see Offline section)
Build & Test (connected)
pnpm install --frozen-lockfile
pnpm lint # markdownlint/prettier/eslint as configured
pnpm build # generates static site into dist/
pnpm test # component/unit tests if configured
- Determinism: ensure
pnpm-lock.yamlis committed; no timestamps in emitted HTML (setSOURCE_DATE_EPOCHif needed).
Publish (connected)
- Build the static site:
pnpm build(or reuse CI artifact). - Create artefact bundle:
tar -C dist -czf out/devportal/site.tar.gz . sha256sum out/devportal/site.tar.gz > out/devportal/site.tar.gz.sha256 - Container image (optional):
docker build -t registry.example.com/stella/devportal:${VERSION} -f ops/devportal/Dockerfile . docker push registry.example.com/stella/devportal:${VERSION} - Record manifest
out/devportal/manifest.json:{ "version": "${VERSION}", "checksum": "$(cat out/devportal/site.tar.gz.sha256 | awk '{print $1}')", "build": { "node": "20.x", "pnpm": "9.x" }, "timestamp": "${UTC_ISO8601}", "source_commit": "$(git rev-parse HEAD)" }
Offline / Air-gap
- Use pre-seeded bundle
offline/devportal/site.tar.gzwith accompanying.sha256andmanifest.json. - Verify before use:
sha256sum -c offline/devportal/site.tar.gz.sha256 - Serve locally:
mkdir -p /srv/devportal && tar -C /srv/devportal -xzf offline/devportal/site.tar.gz # then point nginx/caddy to /srv/devportal - No external CDN references allowed; ensure assets are bundled and CSP is self-contained.
Deployment targets
- Kubernetes: use the static-site container image with a read-only root filesystem; expose via ingress with TLS; set
ETAG/Last-Modifiedheaders from manifest. - Docker Compose: mount
site.tar.gzinto a lightweight nginx container; sample compose snippet lives inops/deployment/devportal/docker-compose.devportal.yml(to be authored alongside this doc). - File share: extract bundle onto shared storage for disconnected viewing; keep manifest + checksum adjacent.
Checks & Observability
- Lint/OAS links: run
pnpm lintand optionalpnpm api:check(if wired) to ensure embedded API links resolve. - Availability: configure basic
/healthz(static 200) and enable access logging at the reverse proxy. - Integrity: serve checksums/manifest from
/metapath for auditors; include buildsource_commitandtimestamp.
Release checklist
pnpm buildsucceeds reproducibly.site.tar.gz+.sha256generated and verified.manifest.jsonpopulated with version, checksum, UTC timestamp, commit SHA.- Offline bundle placed in
offline/devportal/with checksums. - Image (if used) pushed to registry and noted in release notes.
- Deployment target (K8s/Compose/File share) instructions updated if changed.