Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/api.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: api

on:
push:
branches: [main]
paths:
- 'api/**'
- '.github/workflows/api.yaml'
pull_request:
paths:
- 'api/**'
- '.github/workflows/api.yaml'
workflow_dispatch:

permissions:
contents: read

concurrency:
group: api-${{ github.ref }}
cancel-in-progress: true

env:
GO_VERSION: '1.25.4'

jobs:
build:
name: vet, test, build
runs-on: ubuntu-24.04
defaults:
run:
working-directory: api
steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true
cache-dependency-path: api/go.sum

- name: Go module verify
run: go mod download && go mod verify

- name: Vet
run: go vet ./...

- name: Test
run: go test ./... -race -count=1

- name: Build
run: |
mkdir -p ../bin
CGO_ENABLED=0 go build -trimpath -o ../bin/stigman ./cmd/stigman

- name: Upload binary
uses: actions/upload-artifact@v4
with:
name: stigman-linux-amd64
path: bin/stigman
if-no-files-found: error
retention-days: 14
12 changes: 8 additions & 4 deletions .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@ on:
branches: [main]
paths:
- 'docs/**'
- 'pnpm-workspace.yaml'
- 'pnpm-lock.yaml'
- 'package.json'
- '.github/workflows/docs.yaml'
pull_request:
paths:
- 'docs/**'
- 'pnpm-workspace.yaml'
- 'pnpm-lock.yaml'
- 'package.json'
- '.github/workflows/docs.yaml'
workflow_dispatch:

Expand Down Expand Up @@ -40,19 +46,17 @@ jobs:
with:
node-version: ${{ env.NODE_VERSION }}
cache: pnpm
cache-dependency-path: docs/pnpm-lock.yaml
cache-dependency-path: pnpm-lock.yaml

- name: Install dependencies
working-directory: docs
run: pnpm install --frozen-lockfile

- name: Astro check (typecheck)
working-directory: docs
run: pnpm exec astro check || true

- name: Build
working-directory: docs
run: pnpm build
run: pnpm --filter docs build

- name: Upload built site
uses: actions/upload-artifact@v4
Expand Down
67 changes: 67 additions & 0 deletions .github/workflows/web.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: web

on:
push:
branches: [main]
paths:
- 'web/**'
- 'pnpm-workspace.yaml'
- 'pnpm-lock.yaml'
- 'package.json'
- '.github/workflows/web.yaml'
pull_request:
paths:
- 'web/**'
- 'pnpm-workspace.yaml'
- 'pnpm-lock.yaml'
- 'package.json'
- '.github/workflows/web.yaml'
workflow_dispatch:

permissions:
contents: read

concurrency:
group: web-${{ github.ref }}
cancel-in-progress: true

env:
NODE_VERSION: '22'
PNPM_VERSION: '9'

jobs:
build:
name: lint, typecheck, build
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}

- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: pnpm
cache-dependency-path: pnpm-lock.yaml

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Lint
run: pnpm --filter @stig-manager-react/web lint

- name: Typecheck
run: pnpm --filter @stig-manager-react/web typecheck

- name: Build
run: pnpm --filter @stig-manager-react/web build

- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: web-dist
path: web/dist
if-no-files-found: error
retention-days: 14
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ node_modules/
dist/
.astro/
.cache/
web/dist/
bin/

# Logs
*.log
Expand All @@ -25,6 +27,10 @@ Thumbs.db

# Test / coverage
coverage/
*.out

# Go
*.test

# Devin / planning artifacts (not committed to the repo as part of code changes)
.devin-screenshots/
Expand Down
60 changes: 34 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,58 @@ A modern re-implementation of
[NUWCDIVNPT/stig-manager](https://github.com/NUWCDIVNPT/stig-manager):

- **Frontend:** React 19 + Vite + TypeScript + [shadcn/ui](https://ui.shadcn.com).
- **Backend:** Go (`net/http` + `chi`), OpenAPI 3.0.1 v1 — byte-compatible with upstream.
- **Database:** PostgreSQL 18.
- **Backend:** Go 1.25 (`net/http` + `chi`), OpenAPI 3.0.1 v1 — byte-compatible with upstream.
- **Database:** PostgreSQL 18 (via pgx v5).
- **Auth:** OIDC / OAuth 2.0 PKCE (Keycloak / Okta / Azure Entra ID).
- **Docs:** [Astro Starlight](https://starlight.astro.build/) (this repo's `docs/`).

The project is staged across a series of milestones; the current PR adds
Milestone 0, the documentation site.

## Repository layout

```
.
├── docs/ Astro Starlight docs site (Milestone 0 — this PR)
├── api/ Go backend (Milestone 1+)
├── web/ React 19 SPA (Milestone 1+)
├── deploy/ Docker / Compose / Helm (Milestone 1+)
├── tools/ supporting scripts (later)
└── .github/workflows/ CI
├── api/ Go backend (chi, pgx, slog)
├── web/ React 19 SPA (Vite, Tailwind v4, shadcn/ui)
├── docs/ Astro Starlight docs site
├── deploy/ docker-compose + Keycloak realm import
├── .github/workflows/ CI (web, api, docs)
├── pnpm-workspace.yaml pnpm workspace (docs + web)
└── pnpm-lock.yaml single lockfile at repo root
```

## Quick start (docs)
## Prerequisites

- **Node.js 22** and **pnpm 9** (via [Corepack](https://nodejs.org/api/corepack.html)).
- **Go 1.25** for the API.
- **Docker / Docker Compose** for the integrated dev stack.

## Quick start (everything via compose)

```bash
cd docs
pnpm install
pnpm dev
# open http://127.0.0.1:4321
docker compose -f deploy/compose/docker-compose.yaml up -d --build
# SPA: http://localhost:54000
# API: http://localhost:54001
# Keycloak: http://localhost:8080 (admin / admin)
```

To build the static site:
## Quick start (host development)

From the repo root, install JS deps:

```bash
cd docs
pnpm build
# output: docs/dist/
pnpm install
```

## Quick start (application)

*(Available from Milestone 1 onward.)*
In three terminals:

```bash
docker compose -f deploy/compose/docker-compose.yaml up -d
# SPA: http://localhost:54000
# Docs: http://localhost:54000/docs
# 1. Go API on :54001
cd api && cp -n .env.example .env && go run ./cmd/stigman

# 2. React SPA on :54000 (proxies /api/* to the Go API)
pnpm --filter @stig-manager-react/web dev

# 3. Docs site on :4321
pnpm --filter docs dev
```

## Status
Expand Down
11 changes: 11 additions & 0 deletions api/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Listen address for the HTTP API.
STIGMAN_HTTP_ADDR=:54001

# Postgres connection. Required from Milestone 2 onward; optional during scaffold.
STIGMAN_DATABASE_URL=postgres://stigman:stigman@localhost:5432/stigman?sslmode=disable

# Comma-separated CORS origins.
STIGMAN_ALLOWED_ORIGINS=http://localhost:54000,http://127.0.0.1:54000

# Log level: debug | info | warn | error
STIGMAN_LOG_LEVEL=info
28 changes: 28 additions & 0 deletions api/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# syntax=docker/dockerfile:1.7
FROM golang:1.23-alpine AS build
WORKDIR /src

COPY go.mod go.sum ./
RUN go mod download

COPY . ./

ARG VERSION=0.0.0-dev
ARG COMMIT=unknown
ARG BUILD_DATE=unknown

RUN CGO_ENABLED=0 GOOS=linux go build \
-trimpath \
-ldflags="-s -w \
-X main.version=${VERSION} \
-X main.commit=${COMMIT} \
-X main.buildDate=${BUILD_DATE}" \
-o /out/stigman \
./cmd/stigman

FROM gcr.io/distroless/static-debian12:nonroot AS run
WORKDIR /app
COPY --from=build /out/stigman /app/stigman
USER nonroot:nonroot
EXPOSE 54001
ENTRYPOINT ["/app/stigman"]
58 changes: 58 additions & 0 deletions api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# api

Go HTTP API server for [stig-manager-react](https://github.com/Exonical/stig-manager-react).

- Go 1.23, [`chi`](https://github.com/go-chi/chi) router, structured logging
via `log/slog`.
- [`pgx`](https://github.com/jackc/pgx) v5 for Postgres 18.
- OpenAPI v1 surface (currently stubbed: `/api/v1/op/appinfo`,
`/api/v1/op/appdata/tables`). Code-generated handlers from
`docs/openapi/stig-manager.yaml` arrive in Milestone 2.

## Local development

```bash
cd api
cp .env.example .env
export $(grep -v '^#' .env | xargs)
go run ./cmd/stigman
# listens on :54001
```

Smoke test:

```bash
curl -s http://localhost:54001/health
curl -s http://localhost:54001/api/v1/op/appinfo | jq
```

## Test, lint, build

```bash
go vet ./...
go test ./...
go build ./...
```

## Layout

```
api/
├── cmd/stigman/main.go program entrypoint
├── internal/
│ ├── config/ env-based configuration
│ ├── handlers/ HTTP handlers (scaffold)
│ ├── server/ router wiring
│ └── store/ Postgres data layer (scaffold)
├── go.mod
└── Dockerfile multi-stage distroless build
```

## Environment

| variable | default | description |
| ------------------------- | ---------------------------------------------------- | -------------------------------------------- |
| `STIGMAN_HTTP_ADDR` | `:54001` | HTTP listen address |
| `STIGMAN_DATABASE_URL` | _(empty during scaffold)_ | Postgres DSN (`postgres://…`) |
| `STIGMAN_ALLOWED_ORIGINS` | `http://localhost:54000,http://127.0.0.1:54000` | comma-separated CORS allow-list |
| `STIGMAN_LOG_LEVEL` | `info` | `debug` \| `info` \| `warn` \| `error` |
Loading
Loading