81 lines
3.5 KiB
Markdown
81 lines
3.5 KiB
Markdown
# 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)
|
|
```bash
|
|
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:
|
|
```bash
|
|
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):
|
|
```bash
|
|
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`:
|
|
```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:
|
|
```bash
|
|
sha256sum -c offline/devportal/site.tar.gz.sha256
|
|
```
|
|
- Serve locally:
|
|
```bash
|
|
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.
|