Files
git.stella-ops.org/docs/devportal/publishing.md
StellaOps Bot 6bee1fdcf5
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
work
2025-11-25 08:01:23 +02:00

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.yaml is committed; no timestamps in emitted HTML (set SOURCE_DATE_EPOCH if needed).

Publish (connected)

  1. Build the static site: pnpm build (or reuse CI artifact).
  2. Create artefact bundle:
    tar -C dist -czf out/devportal/site.tar.gz .
    sha256sum out/devportal/site.tar.gz > out/devportal/site.tar.gz.sha256
    
  3. Container image (optional):
    docker build -t registry.example.com/stella/devportal:${VERSION} -f ops/devportal/Dockerfile .
    docker push registry.example.com/stella/devportal:${VERSION}
    
  4. 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.gz with accompanying .sha256 and manifest.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-Modified headers from manifest.
  • Docker Compose: mount site.tar.gz into a lightweight nginx container; sample compose snippet lives in ops/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 lint and optional pnpm 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 /meta path for auditors; include build source_commit and timestamp.

Release checklist

  • pnpm build succeeds reproducibly.
  • site.tar.gz + .sha256 generated and verified.
  • manifest.json populated 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.