-
Notifications
You must be signed in to change notification settings - Fork 1
Development Workflow
This page covers branches, commit conventions, and the pull request flow. It is for anyone about to make a change, and it is the page to read before your first pull request.
CONTRIBUTING.md in the repository is the authoritative version of this policy. This page adds the detail that helps in practice.
Two long-lived branches, recorded in ADR-0003.
main is the default and release branch. It moves only through promotion pull requests from dev and through hotfixes. What is on main is what the project considers releasable.
dev is the integration branch. Every feature, fix, and docs pull request targets dev. Opening one against main is the most common first-time mistake.
feature branch ──PR──> dev ──promotion PR──> main ──tag──> release
Feature branches use a type/short-description shape, matching the branches in use: feat/emr-app, chore/dependency-security-sweep, hotfix/audit-event-timestamps.
Both branches are protected by repository rulesets rather than classic branch protection, because rulesets are auditable, exportable as JSON, and apply consistently to administrators.
Enforced by commitlint through the commit-msg hook locally and by the PR governance workflow in CI. The single source of truth is commitlint.config.cjs; the CI job reads that file at runtime so the two gates cannot drift apart.
Types
build chore ci docs feat fix perf refactor revert style test
Scopes
web api database fhir types ui lib repo ci docs
Header maximum length is 100 characters.
feat(api): add Patient read endpoint
fix(database): make AuditEvent actor index case-insensitive
docs(repo): clarify release promotion flow
chore(repo): promote dev to main - patient scheduling MVP
The scope is required in the PR title. Commitlint accepts a scopeless commit locally, but the PR-title check runs with
requireScope: true. A title likefeat: add patient searchpasses every local hook and reds the pull request. Always writetype(scope): subjectin the title.
Note that the comment block in .github/PULL_REQUEST_TEMPLATE.md lists the scopes without ui. commitlint.config.cjs is the authoritative list and does include ui.
Installed by the prepare script on pnpm install.
| Hook | Runs |
|---|---|
pre-commit |
lint-staged: Prettier on staged formattable files, secretlint over a wider set including config, shell, env-shaped, TOML, XML, and plist files |
commit-msg |
commitlint --edit |
pre-push |
pnpm run lint && pnpm run type-check |
Do not bypass them. If a hook is wrong, fix the hook in a pull request.
Scoped to what you changed:
pnpm --filter <workspace> lint
pnpm --filter <workspace> type-check
pnpm --filter <workspace> test
pnpm turbo run build --filter=<workspace> # if the change affects build outputOr the whole gate, which is slower:
pnpm verify- Target
dev. - Title is
type(scope): subjectwith a scope from the list. - Fill in the template: the checklist, current behaviour, new behaviour and how you verified it, and the linked issue.
- Keep it focused. Unrelated cleanups belong in their own pull request.
- The
CI Requiredaggregate check must be green before merge.
Two rules the template asks you to confirm, because they are the ones that cause real harm:
- No real patient data anywhere in the diff, screenshots, or logs.
- No applied Prisma migration was edited. See Upgrades and migrations.
If your change reverses or significantly extends a recorded architectural decision, include a new ADR in the same pull request. Do not edit the old one; mark it superseded and link forward. See ADR index.
When dev is in a state worth releasing, open a pull request from dev to main titled:
chore(repo): promote dev to main - <summary>
Wait for CI Required, then merge without squashing, so the commit history from dev is preserved.
The commit-message validation job skips promotion pull requests, because they replay history that was already linted when it merged to dev. The title check still runs.
- Branch from
main. - Open a pull request targeting
mainwith a normal conventional title. - After merge, back-merge
mainintodevimmediately, or the fix will be lost or reintroduced by the next promotion.
GitHub reads some files from the default branch regardless of which branch you edit. Change them on dev like everything else and let promotion carry them; never patch them on main alone.
| File | Why |
|---|---|
.github/dependabot.yml |
Dependabot reads only the default branch copy. A dev-only edit does nothing and a divergent copy conflicts on every promotion. |
.github/workflows/** |
Scheduled and default-branch triggers run from main. |
.github/CODEOWNERS |
Review routing should not depend on the target branch. |
.github/ISSUE_TEMPLATE/** |
Issue forms are served from the default branch. |
.github/PULL_REQUEST_TEMPLATE.md |
Served from the default branch. |
SECURITY.md |
The Security tab reads the default branch copy. |
Use a git worktree per concurrent workstream. The repository is already set up this way, with sibling directories for the branches in flight.
git worktree add ../openrunic-my-feature -b feat/my-feature devTwo things to watch. Only one git process should touch a worktree at a time. And bare npx tsc or npx eslint can resolve wrongly in a worktree; use the workspace scripts through pnpm instead.
- Bugs: use the bug report template and fill in reproduction and environment. If the bug involves real data, reproduce it with synthetic data first and report that.
- Features: open an issue with the feature template before writing significant code, so scope can be agreed first.
- Security vulnerabilities: never a public issue. See Security policy.
There is no CLA and no sign-off requirement. Submitting a contribution means it is your own work, or you have the right to submit it, and that it is provided under AGPL-3.0-only.
openrunic is an open-source operating system for human health. Pre-alpha: do not run it in production, and never put real patient data into it.
Repository · Licence (AGPL-3.0-only) · Security policy · Contributing · Code of conduct
Where this wiki and the repository disagree, the repository is right.