mirror of
https://github.com/Heretek-AI/arcane-repo.git
synced 2026-07-01 18:25:50 -04:00
feat: Write CONTRIBUTING.md documenting the complete end-to-end templat…
- CONTRIBUTING.md GSD-Task: S04/T01
This commit is contained in:
+288
@@ -0,0 +1,288 @@
|
||||
# Contributing to the Arcane Template Registry
|
||||
|
||||
Thank you for contributing! This registry is a curated collection of Docker Compose templates for Arcane. Template folders are the single source of truth — CI validates their structure, assembles `registry.json` from on-disk state, and publishes it to GitHub Pages.
|
||||
|
||||
## Repository Overview
|
||||
|
||||
```
|
||||
arcane-repo/
|
||||
├── templates/ # One directory per template
|
||||
│ ├── litellm/ # Example: LiteLLM proxy template
|
||||
│ │ ├── arcane.json # Metadata (id, name, version, author, tags)
|
||||
│ │ ├── docker-compose.yml # Compose service definition
|
||||
│ │ ├── .env.example # Documented env var reference
|
||||
│ │ └── README.md # Template documentation
|
||||
│ └── ...
|
||||
├── scripts/
|
||||
│ └── build-registry.js # Validates and assembles registry.json
|
||||
├── schema.json # JSON Schema for validation
|
||||
├── .github/workflows/
|
||||
│ ├── validate.yml # Runs on PRs touching templates/**
|
||||
│ └── deploy.yml # Runs on push to main, publishes to Pages
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Adding a New Template
|
||||
|
||||
### 1. Fork and Branch
|
||||
|
||||
Fork the repository, clone your fork, and create a feature branch:
|
||||
|
||||
```bash
|
||||
git checkout -b add-<template-name>
|
||||
```
|
||||
|
||||
### 2. Create the Template Directory
|
||||
|
||||
```bash
|
||||
mkdir templates/<template-name>/
|
||||
```
|
||||
|
||||
Replace `<template-name>` with a lowercase slug using hyphens only (e.g., `my-app`, `custom-service`). This name becomes the template `id` and must match the folder name exactly.
|
||||
|
||||
### 3. Write the Four Required Files
|
||||
|
||||
#### `arcane.json`
|
||||
|
||||
Template metadata file. The `id` field must match the folder name, `version` must be valid semver, and `tags` must be a non-empty array of unique strings.
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "my-app",
|
||||
"name": "My App",
|
||||
"description": "A clear description of what the template provides and its use case",
|
||||
"version": "1.0.0",
|
||||
"author": "Your Name or Organization",
|
||||
"tags": ["category1", "category2"]
|
||||
}
|
||||
```
|
||||
|
||||
**Conventions:**
|
||||
- `id` — lowercase slug with hyphens only, must match folder name
|
||||
- `version` — valid [semver](https://semver.org/) string (e.g., `1.0.0`, `1.2.3-beta.1`)
|
||||
- `tags` — non-empty array of unique strings; use descriptive categories like `ai`, `llm`, `automation`, `workflow`, `low-code`, `database`, `monitoring`
|
||||
- You do **not** need to include `compose_url`, `env_url`, `documentation_url`, or `content_hash` — those are auto-generated by the CI build script
|
||||
- Do **not** include `$schema` in template-level `arcane.json`
|
||||
|
||||
#### `docker-compose.yml`
|
||||
|
||||
A valid Docker Compose file (version `3.8` or later). Follow these conventions:
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
my-service:
|
||||
image: ghcr.io/org/image:tag
|
||||
container_name: my-service
|
||||
hostname: my-service
|
||||
ports:
|
||||
- "${PORT:-8080}:8080"
|
||||
volumes:
|
||||
- my_data:/app/data
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- API_KEY=${API_KEY:-}
|
||||
|
||||
volumes:
|
||||
my_data:
|
||||
name: my_data
|
||||
```
|
||||
|
||||
**Conventions:**
|
||||
- File name is `docker-compose.yml` (not `compose.yml`)
|
||||
- Reference env vars using `${VAR:-default}` syntax with secure defaults where possible
|
||||
- Use `${VAR:?}` mandatory-variable syntax for values that must be user-provided and have no safe default (e.g., encryption keys)
|
||||
- Always declare volumes under a top-level `volumes:` key
|
||||
- Set `restart: unless-stopped`
|
||||
- Use `-` for environment variable prefixes, not `=` (e.g., `- API_KEY=${API_KEY:-}`)
|
||||
|
||||
#### `.env.example`
|
||||
|
||||
Documents all environment variables the compose file consumes. Include defaults, format hints, and comments:
|
||||
|
||||
```bash
|
||||
# ── Configuration ──────────────────────────────────────────────────────
|
||||
|
||||
# Host port for the service (default: 8080)
|
||||
PORT=8080
|
||||
|
||||
# API key for external service (required — generate a random key)
|
||||
API_KEY=your-api-key
|
||||
```
|
||||
|
||||
**Conventions:**
|
||||
- Comment sections with dividers for readability
|
||||
- Every `docker-compose.yml` variable should appear here
|
||||
- Show default values where applicable
|
||||
- Mark required variables with comments like `(required)`
|
||||
|
||||
#### `README.md`
|
||||
|
||||
Documents what the template does and how to use it. Include at minimum:
|
||||
|
||||
- One-line description of the template
|
||||
- Quick Start section with `cp .env.example .env`, env setup, and `docker compose up -d`
|
||||
- Environment variable reference table (Variable | Default | Description)
|
||||
- Any post-start verification (e.g., `curl` command for health check)
|
||||
|
||||
See the [LiteLLM template](templates/litellm/README.md) as a reference example.
|
||||
|
||||
### 4. Validate Locally
|
||||
|
||||
Before pushing, run the validation script to catch errors early:
|
||||
|
||||
```bash
|
||||
node scripts/build-registry.js --validate-only
|
||||
```
|
||||
|
||||
This checks every template directory for:
|
||||
- Valid `arcane.json` JSON syntax
|
||||
- Required fields: `id`, `name`, `description`, `version`, `author`, `tags`
|
||||
- `id` matches the folder name and is a valid slug (`^[a-z0-9-]+$`)
|
||||
- `version` is valid semver
|
||||
- `tags` is a non-empty array of unique strings
|
||||
- Required files present: `docker-compose.yml`, `.env.example`, `README.md`
|
||||
- No duplicate `id` values across templates
|
||||
|
||||
### 5. Push and Open a PR
|
||||
|
||||
```bash
|
||||
git add templates/<template-name>/
|
||||
git commit -m "feat: add <template-name> template"
|
||||
git push origin add-<template-name>
|
||||
```
|
||||
|
||||
Open a pull request against the `main` branch. The `Validate Templates` workflow runs automatically on any PR that changes paths under `templates/**`.
|
||||
|
||||
### 6. After Merge
|
||||
|
||||
Once the PR merges to `main`, the **Build and Deploy Registry** workflow triggers:
|
||||
|
||||
1. Runs `node scripts/build-registry.js` to generate `registry.json`
|
||||
2. Configures GitHub Pages
|
||||
3. Uploads the repository as a Pages artifact
|
||||
4. Deploys to GitHub Pages (~2 minutes total)
|
||||
|
||||
After deployment, the published registry is available at:
|
||||
|
||||
```
|
||||
https://<org>.github.io/arcane-repo/registry.json
|
||||
```
|
||||
|
||||
Replace `<org>` with the organization or owner name.
|
||||
|
||||
## Modifying an Existing Template
|
||||
|
||||
Edit any of the four required files in the template's directory:
|
||||
|
||||
- `arcane.json` — update metadata (version, description, tags)
|
||||
- `docker-compose.yml` — update service configuration
|
||||
- `.env.example` — add or update documented variables
|
||||
- `README.md` — update documentation
|
||||
|
||||
The `content_hash` is computed at build time from all four source files (sorted alphabetically: `arcane.json`, `docker-compose.yml`, `.env.example`, `README.md`), so any modification is automatically detected by CI. You do not need to update a hash manually.
|
||||
|
||||
Run local validation before pushing:
|
||||
|
||||
```bash
|
||||
node scripts/build-registry.js --validate-only
|
||||
```
|
||||
|
||||
## Removing a Template
|
||||
|
||||
Delete the template directory:
|
||||
|
||||
```bash
|
||||
rm -rf templates/<template-name>/
|
||||
git add -A
|
||||
git commit -m "feat: remove <template-name> template"
|
||||
```
|
||||
|
||||
Commit and push. The next CI run skips the removed directory — no other files need updating. The `registry.json` is rebuilt from whatever directories remain.
|
||||
|
||||
## CI Workflows
|
||||
|
||||
### Validate Templates (`validate.yml`)
|
||||
|
||||
- **Triggers on:** Pull requests to any branch, when files under `templates/**` change
|
||||
- **Steps:**
|
||||
1. Checkout code
|
||||
2. Set up Node.js 22
|
||||
3. Run `node scripts/build-registry.js --validate-only`
|
||||
- **Failing a PR:** If validation errors are found, the workflow exits with a non-zero code, marking the PR check as failed. Fix the reported issue and push again.
|
||||
|
||||
### Build and Deploy Registry (`deploy.yml`)
|
||||
|
||||
- **Triggers on:** Push to `main` that changes files under `templates/**`, `schema.json`, or `scripts/build-registry.js`
|
||||
- **Steps:**
|
||||
1. Checkout code
|
||||
2. Set up Node.js 22
|
||||
3. Run `node scripts/build-registry.js` (writes `registry.json`)
|
||||
4. Configure GitHub Pages
|
||||
5. Upload the repository as a Pages artifact
|
||||
6. Deploy to Pages
|
||||
|
||||
## Schema
|
||||
|
||||
The registry schema lives at [`schema.json`](schema.json) in the repository root. It defines two levels:
|
||||
|
||||
### Registry (top-level)
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|---------------|----------|----------|--------------------------------------------|
|
||||
| `name` | string | yes | Registry name |
|
||||
| `description` | string | yes | Registry description |
|
||||
| `version` | semver | yes | Registry version |
|
||||
| `author` | string | yes | Registry author |
|
||||
| `url` | URI | yes | Repository URL |
|
||||
| `templates` | array | yes | Array of `template` objects (min 1 item) |
|
||||
|
||||
### Template
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|---------------------|-------------|----------|--------------------------------------------------|
|
||||
| `id` | slug | yes | Unique identifier, matches folder name |
|
||||
| `name` | string | yes | Human-readable name |
|
||||
| `description` | string | yes | Detailed description |
|
||||
| `version` | semver | yes | Template version |
|
||||
| `author` | string | yes | Template author |
|
||||
| `compose_url` | URI | yes | Auto-generated raw GitHub URL to compose file |
|
||||
| `env_url` | URI | yes | Auto-generated raw GitHub URL to env example |
|
||||
| `documentation_url` | URI | yes | Auto-generated raw GitHub URL to README |
|
||||
| `content_hash` | SHA-256 hex | yes | Auto-generated hash of all source files |
|
||||
| `tags` | array | yes | Non-empty array of unique tags (letters, digits, hyphens) |
|
||||
|
||||
### Auto-Generated Fields
|
||||
|
||||
Template authors **do not write** these fields in `arcane.json`. The CI build script computes them:
|
||||
|
||||
- `compose_url` — `https://raw.githubusercontent.com/<owner>/<repo>/<branch>/templates/<id>/docker-compose.yml`
|
||||
- `env_url` — `https://raw.githubusercontent.com/<owner>/<repo>/<branch>/templates/<id>/.env.example`
|
||||
- `documentation_url` — `https://raw.githubusercontent.com/<owner>/<repo>/<branch>/templates/<id>/README.md`
|
||||
- `content_hash` — SHA-256 of the concatenation of all four source files sorted alphabetically
|
||||
|
||||
The build script resolves the repository owner and name from `GITHUB_REPOSITORY` in CI, or from `REPO_OWNER`/`REPO_NAME` environment variables locally.
|
||||
|
||||
## Validation Rules (from `build-registry.js`)
|
||||
|
||||
These are checked by the validation script and CI:
|
||||
|
||||
| Rule | Error level |
|
||||
|---------------------------------------------|-------------|
|
||||
| `templates/` directory must exist | error |
|
||||
| Each subdirectory must have `arcane.json` | error |
|
||||
| `arcane.json` must be valid JSON | error |
|
||||
| `id` must match folder name | error |
|
||||
| `id` must match slug pattern `/^[a-z0-9-]+$/` | error |
|
||||
| `version` must be valid semver | error |
|
||||
| `tags` must be a non-empty array | error |
|
||||
| `docker-compose.yml` must exist | error |
|
||||
| `.env.example` must exist | error |
|
||||
| `README.md` must exist | error |
|
||||
| No duplicate template `id` values | error |
|
||||
| Duplicate tags (in same template) | warning |
|
||||
|
||||
## License
|
||||
|
||||
By contributing, you agree that your contributions will be licensed under the MIT License (see [LICENSE](LICENSE) — if no LICENSE file exists, the repository defaults to MIT).
|
||||
Reference in New Issue
Block a user