Skip to content

Contributing

kneshi edited this page May 8, 2026 · 4 revisions

Contributing

This page covers the repo's automated contributor flow: how dependency updates land, what commit prefixes do, and how a tagged release is produced.

Dependency updates

Article30 keeps its dependencies current automatically via Dependabot. Routine bumps don't need a maintainer's attention; majors do.

Configured surface

.github/dependabot.yml declares four updates: entries:

Ecosystem Directory Group(s)
npm / production-deps, dev-deps (split)
github-actions / actions
docker /backend docker-base
docker /frontend docker-base

All four entries share:

  • Schedule: weekly, Monday morning, one consolidated batch.
  • Cooldown: 3 days from publish before any bump is picked up. Filters supply-chain attacks that get yanked within 24-48 h. Cooldown applies to version updates only; security updates ship immediately.
  • Groups: scope update-types: [minor, patch]. Major bumps fall outside the groups by design and surface as individual PRs for human review.
  • Conventional Commits: chore(deps): bump foo for production npm, chore(deps-dev): bump foo for dev npm, chore(ci): bump foo for github-actions, chore(docker): bump foo for docker base images.

The npm production / dev split exists so a regression scopes immediately, production-dep failures are higher-severity than dev-dep failures and shouldn't share a PR.

Auto-merge

.github/workflows/dependabot-auto-merge.yml approves and queues gh pr merge --auto --squash for any Dependabot PR whose update type is minor or patch. Major bumps are left open for manual review.

Auto-merge does not mean auto-bypass-CI. The --auto flag queues the merge until the required CI checks all pass: Lint, Format & Audit, Typecheck & Build, Tests, E2E (Playwright), Docker Build. If CI fails on a grouped PR, the merge stays queued; nothing lands until either Dependabot's next rebase or a human closes the PR.

Conventional Commits

The repo uses @commitlint/config-conventional (the standard Angular preset). The husky commit-msg hook validates locally; the Commitlint CI job re-validates the PR commit range.

Prefix Bump CHANGELOG section
feat: minor (1.2.0 -> 1.3.0) "Features"
fix: patch (1.2.0 -> 1.2.1) "Bug Fixes"
feat!: / BREAKING CHANGE: footer major (1.2.0 -> 2.0.0) "BREAKING CHANGES"
perf: patch "Performance Improvements"
revert: depends on what's reverted "Reverts"
docs:, chore:, style:, test:, refactor:, ci:, build: none not in CHANGELOG

Scopes (the parens in feat(backend): ...) are free-form. The repo conventionally uses backend, frontend, shared, ci, deps, release, wiki, changelog.

Examples:

  • feat(backend): add bulk export endpoint for treatments -> minor bump
  • fix(frontend): correct DSR deadline calculation off-by-one -> patch bump
  • feat(backend)!: replace cookie auth with JWT -> major bump (the ! is the marker)
  • chore(deps): bump express from 4.18 to 4.19 -> no bump (Dependabot's standard prefix)

Releases

Article30 ships SemVer-compliant releases driven by release-please over Conventional Commits. Every release publishes multi-arch Docker images for backend and frontend to GitHub Container Registry.

How a release happens

Operators consume the published images via the canonical docker compose --env-file .env.prod up -d documented in Production - Deploy from GHCR. The release pipeline:

conventional-commit PR
        │
        ▼
   merge to main
        │
        ▼
release-please-action (.github/workflows/release-please.yml)
opens / updates "chore(main): release X.Y.Z" PR
        │
human reviews + merges release PR
        │
        ▼
release-please tags vX.Y.Z + creates GitHub Release
        │
        ▼
release-publish.yml (.github/workflows/release-publish.yml)
matrix-builds backend + frontend, multi-arch,
pushes to:
  ghcr.io/ipsec-dev/article30/backend
  ghcr.io/ipsec-dev/article30/frontend
tags: X.Y.Z, X.Y, X, latest

Failure modes & recovery

No release PR appears after a feat:/fix: lands on main.

  • Check the workflow run at Actions > Release Please. If the run failed, the logs say why.
  • If commits are using non-conventional prefixes (Add X instead of feat: add X), release-please ignores them. Land one new conventional commit on main to trigger the next run.

Workspace package versions drifted (version-sync.spec.ts fails).

  • Run git diff backend/package.json frontend/package.json shared/package.json package.json to find the divergent file.
  • The node-workspace plugin in release-please-config.json should keep them in lockstep. If a developer hand-edited one workspace's version, revert it; release-please will re-bump on the next release PR.

Manually triggering a release

release-please.yml declares both push: branches: [main] and workflow_dispatch: triggers. To force a run when the automatic trigger isn't producing a PR:

gh workflow run release-please.yml

There is no UI for forcing release-please to bump differently than what it computes from commits, its bump is deterministic from the conventional-commit history since the last vX.Y.Z tag. To override on a one-off basis, edit the open release PR's package.json/CHANGELOG.md before merging; release-please respects manual edits to its release PRs.

Clone this wiki locally