Skip to content

Contributing

Daniel Hokanson edited this page Aug 30, 2026 · 3 revisions

The project-wide contributor guide is CONTRIBUTING.md in the umbrella repo, with per-repo specifics (build instructions, test commands) in each sibling repo's own CONTRIBUTING.md. Behaviour expectations are in the Code of Conduct. Forge is licensed Apache 2.0.

Where to file it

Open issues and PRs in the repo that owns the affected code — see the repo table on Home. Cross-cutting design discussion belongs on the umbrella repo, where the specs live.

Getting set up

git clone https://github.com/armoryworks/forge.git
cd forge
./bootstrap.sh        # clones the sibling repos INSIDE this checkout

bootstrap.ps1 is the PowerShell equivalent. Two things the script's name does not tell you: the siblings are cloned inside the umbrella checkout rather than beside it — deliberate, because the compose build contexts resolve relative to that layout — and forge-db is not among them. If you are touching the schema, clone it yourself.

For a running, hot-reloading stack, see Developer Setup. ./setup.sh --source is a production-shaped build from source, not a development inner loop.

Branch model

PRs target main in the repo that owns the code. That is the branch CI runs on, and no develop branch exists on any of the repos. Branch names are feature/*, fix/* or chore/*; commit subjects are imperative; one logical change per PR; UI changes carry a screenshot.

The umbrella CONTRIBUTING.md is stale on exactly this point — it says PRs target develop, and it twice refers to EF migrations, which no longer exist. The per-repo CONTRIBUTING.md files are the better first read.

Before you push

Forge enforces its standards mechanically, so running the gates locally saves a round trip. See Architecture § Standards are enforced for how the ratchet works.

Run what CI runs, in the order CI runs it. Both sequences contain a step that is easy to omit and that test alone will never surface.

forge-ui

npm ci
npm run lint            # hard ceiling on total warnings — a warning-level regression fails
npm run lint:i18n
npm run lint:standards
npm run build           # a gate in its own right
npm run test -- --watch=false

npm run build matters because spec files compile under a separate tsconfig the production build never sees, so a green test run can sit on top of a broken build. Translations live only at public/assets/i18n/{en,es}.json, with enforced 1:1 key parity between locales. A new user-facing string means a key in both files.

forge-api

dotnet build --configuration Release -warnaserror   # compiler warnings break CI
dotnet test  --configuration Release
dotnet test  --filter Architecture                  # standards + capability-gate tests

The Release build with warnings-as-errors comes before the tests, and dotnet test alone will not surface what it catches.

CodeQL runs on both repos, and Playwright runs nightly rather than per-PR. Which suites need Docker, and the escape hatch for the ones that do, is on Developer Setup.

Things that will get a PR sent back

  • Adding an EF Core migration. The schema is owned by forge-db as desired-state SQL — see Architecture. There are no migrations to add.
  • Calling DateTime.UtcNow directly. Inject IClock.
  • A new controller with no capability attribute. An architecture test enforces gating by reflection; see Capability Gating.
  • Hardcoded colours, console.log, or inline templates in new UI files. The lint ratchet allows existing debt to sit but will not accept new debt.
  • Improving a ratcheted file without regenerating its baseline. Improvements fail the check until you rerun with the baseline-update environment variable and commit the rewritten baseline in the same commit. Baselines are never hand-edited upward.
  • Opening the PR against develop. There is no such branch.

Reporting a security issue

Do not open a public issue for a security problem. Report it privately to the maintainer address named in the Code of Conduct, and give the project time to ship a fix before disclosing.

Licensing, for contributors and for adopters

Forge is Apache 2.0 and there is no CLA — contributions are inbound-equals-outbound under §5 of the licence. Redistribution carries the usual obligation to ship LICENSE and NOTICE. The Apache grant covers the code and not the Forge and Armory Works marks, which matters if you intend to ship a rebuild under your own branding — see Customizing an Install for what the product supports and treat the name as a separate question.

Two bundled dependencies carry revenue-triggered commercial terms rather than plain permissive ones — QuestPDF (Community licence, with a paid licence required above a revenue threshold) and SixLabors.ImageSharp (a split licence, Apache-2.0 only if you qualify). The qualifying clauses often resolve in a self-hosting operator's favour, which is exactly why it is worth checking rather than assuming. Optional Ollama models carry their own licences too.

Writing docs

Docs are part of the change, not a follow-up. Read Documentation Map for where a new document belongs and what frontmatter it needs — placement is enforced by tooling.

Clone this wiki locally