Skip to content

Commit c7c5289

Browse files
baijumclaude
andcommitted
Add spec conformance validator with reusable GitHub Action
Introduce a Python validation script that checks app repos against the platform spec across three tiers (structure, content, runtime). Distribute it to app repos via a reusable composite action. Tighten spec.md with explicit Dockerfile locations, dependency requirements, HTTP 200 health status, and an expanded compatibility checklist aligned to validator checks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent c9309a7 commit c7c5289

4 files changed

Lines changed: 626 additions & 9 deletions

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: 'Towlion Spec Validator'
2+
description: 'Validates an app repo conforms to the Towlion platform spec'
3+
inputs:
4+
tier:
5+
description: 'Validation tier (1=structure, 2=content, 3=runtime)'
6+
default: '2'
7+
strict:
8+
description: 'Treat warnings as errors'
9+
default: 'false'
10+
runs:
11+
using: 'composite'
12+
steps:
13+
- uses: actions/checkout@v4
14+
with:
15+
repository: towlion/platform
16+
path: .towlion-validator
17+
sparse-checkout: validator
18+
- uses: actions/setup-python@v5
19+
with:
20+
python-version: '3.11'
21+
- shell: bash
22+
run: |
23+
python .towlion-validator/validator/validate.py \
24+
--tier ${{ inputs.tier }} \
25+
${{ inputs.strict == 'true' && '--strict' || '' }}
26+
- shell: bash
27+
run: rm -rf .towlion-validator

docs/spec.md

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Application Specification
22

3+
**Spec Version:** 1.0
4+
35
This document defines the **standard contract for applications** running on the Towlion platform. Every application repository in the ecosystem should follow this specification.
46

57
## Goals
@@ -18,7 +20,10 @@ Each application lives in its own GitHub repository under the `towlion` organiza
1820
```
1921
repo/
2022
app/ # FastAPI backend
21-
frontend/ # Next.js frontend
23+
Dockerfile # Backend container image
24+
main.py # Application entry point
25+
frontend/ # Next.js frontend (optional)
26+
Dockerfile # Frontend container image
2227
2328
deploy/
2429
docker-compose.yml # App-specific containers
@@ -35,7 +40,9 @@ repo/
3540
README.md
3641
```
3742

38-
In the multi-app setup, `docker-compose.yml` defines only the application containers (app, frontend, workers). Shared platform services (Caddy, PostgreSQL, Redis, MinIO) are managed at the server level. The `docker-compose.standalone.yml` file bundles everything for self-hosted fork deployments.
43+
In the multi-app setup, `docker-compose.yml` defines only the application containers (app, frontend, workers). Shared platform services (Caddy, PostgreSQL, Redis, MinIO) are managed at the server level.
44+
45+
The `docker-compose.standalone.yml` file provides a complete, self-contained stack for self-hosted fork deployments. It bundles all platform services (Caddy, PostgreSQL, Redis, MinIO) alongside the application containers so the app can run on a single server without any external dependencies.
3946

4047
## Backend Requirements
4148

@@ -52,6 +59,7 @@ The platform reverse proxy routes traffic to this port.
5259
Every application must provide a health check endpoint:
5360

5461
- **Endpoint:** `GET /health`
62+
- **HTTP Status:** `200 OK`
5563
- **Response:** `{"status": "ok"}`
5664

5765
This endpoint is used during deployments to verify the application started correctly.
@@ -118,15 +126,26 @@ Applications should avoid storing large files on the container filesystem.
118126

119127
Applications may include a frontend built with Next.js, React, and TypeScript. The frontend communicates with the backend via `/api`.
120128

129+
## Dependencies
130+
131+
Python dependencies must be declared in one of:
132+
133+
- `requirements.txt` (default)
134+
- `pyproject.toml` (alternative)
135+
136+
At minimum, dependencies must include `fastapi` and `uvicorn`.
137+
121138
## Docker Requirements
122139

123-
Each repository must include Docker configuration. The container must:
140+
Each repository must include Docker configuration. The backend Dockerfile must be located at `app/Dockerfile`. If the app includes a frontend, its Dockerfile must be at `frontend/Dockerfile`.
141+
142+
The container must:
124143

125144
- Start automatically
126145
- Expose port 8000
127146
- Read configuration from environment variables
128147

129-
Example Dockerfile:
148+
Example `app/Dockerfile`:
130149

131150
```dockerfile
132151
FROM python:3.11
@@ -161,9 +180,43 @@ Applications should follow basic security practices:
161180

162181
To remain compatible with the Towlion platform, applications must:
163182

183+
**Structure:**
184+
- [ ] Include `app/` directory with `Dockerfile` and `main.py`
185+
- [ ] Include `deploy/` directory with `docker-compose.yml`, `docker-compose.standalone.yml`, `Caddyfile`, and `env.template`
186+
- [ ] Include `.github/workflows/deploy.yml`
187+
- [ ] Include `scripts/health-check.sh`
188+
- [ ] Include `README.md`
189+
190+
**Content:**
191+
- [ ] `deploy/docker-compose.yml` is valid YAML, references port 8000, and includes a healthcheck
192+
- [ ] `deploy/env.template` contains `APP_DOMAIN`, `DATABASE_URL`, and `REDIS_URL`
193+
- [ ] `deploy/Caddyfile` contains `reverse_proxy` directive targeting port 8000
194+
- [ ] `app/main.py` uses FastAPI
195+
- [ ] Python dependencies (`requirements.txt` or `pyproject.toml`) include `fastapi` and `uvicorn`
196+
- [ ] No hardcoded secrets in source code
197+
198+
**Runtime:**
164199
- [ ] Expose HTTP service on port 8000
165-
- [ ] Provide `GET /health` endpoint
166-
- [ ] Support environment-based configuration
167-
- [ ] Support automated deployment via GitHub Actions
168-
- [ ] Use PostgreSQL for database
169-
- [ ] Include Docker configuration
200+
- [ ] `GET /health` returns HTTP 200 with `{"status": "ok"}`
201+
- [ ] Containers build and start successfully
202+
203+
## Validation
204+
205+
Use the [Towlion Spec Validator](../validator/README.md) to automatically check conformance.
206+
207+
**Local usage:**
208+
209+
```bash
210+
# Clone the platform repo and run against your app
211+
python validator/validate.py --tier 2 --dir /path/to/your/app
212+
```
213+
214+
**CI usage (GitHub Actions):**
215+
216+
```yaml
217+
steps:
218+
- uses: actions/checkout@v4
219+
- uses: towlion/platform/.github/actions/validate@main
220+
with:
221+
tier: '2'
222+
```

validator/README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Towlion Spec Validator
2+
3+
Validates that an application repository conforms to the [Towlion Platform Specification](../docs/spec.md) (Spec Version 1.0).
4+
5+
## Tiers
6+
7+
The validator runs checks in three tiers:
8+
9+
| Tier | Name | What it checks |
10+
|------|------|----------------|
11+
| 1 | Structure | Required files and directories exist |
12+
| 2 | Content | File contents match spec requirements (default) |
13+
| 3 | Runtime | Docker builds and health endpoint works (requires Docker) |
14+
15+
Each tier includes all checks from lower tiers.
16+
17+
## Local Usage
18+
19+
```bash
20+
# Run from the platform repo against an app repo
21+
python validator/validate.py --dir /path/to/your/app
22+
23+
# Structure checks only
24+
python validator/validate.py --tier 1 --dir /path/to/your/app
25+
26+
# Full validation including runtime (requires Docker)
27+
python validator/validate.py --tier 3 --dir /path/to/your/app
28+
29+
# Strict mode: treat warnings as errors
30+
python validator/validate.py --strict --dir /path/to/your/app
31+
```
32+
33+
## CI Usage (GitHub Actions)
34+
35+
Add this step to your app's workflow:
36+
37+
```yaml
38+
steps:
39+
- uses: actions/checkout@v4
40+
- uses: towlion/platform/.github/actions/validate@main
41+
with:
42+
tier: '2'
43+
strict: 'false'
44+
```
45+
46+
## Options
47+
48+
| Flag | Default | Description |
49+
|------|---------|-------------|
50+
| `--tier` | `2` | Validation tier (1, 2, or 3) |
51+
| `--strict` | off | Treat warnings as errors (exit code 1) |
52+
| `--dir` | `.` | Path to the app repo to validate |
53+
54+
## Exit Codes
55+
56+
- `0` — All checks passed (warnings are allowed unless `--strict`)
57+
- `1` — One or more checks failed
58+
59+
## Dependencies
60+
61+
- Python 3.11+ (standard library only)
62+
- PyYAML is used for YAML validation if installed, but is not required
63+
- Tier 3 requires Docker

0 commit comments

Comments
 (0)