Contributing and migration workflow
Day-to-day contribution
- Branch from
mainusing branch naming. - Make changes; keep docs and
.github/labeler.ymlin sync when you add projects or change conventions. - Open a pull request; CI runs monorepo lint and
nx affectedbuild and tests (see CI/CD). Use a Conventional Commits title. - After merge, releases are driven by tags, not by committing build artifacts to
main.
PR title (Conventional Commits)
Use type(optional-scope): description. The scope is optional. Mark breaking changes with ! in the PR title, for example feat!: description or feat(scope)!: description. The squash commit uses only the PR title, so a BREAKING CHANGE: footer in the PR description will not be included. See the Conventional Commits specification.
| Type | Meaning | Example |
|---|---|---|
feat | Add a feature | feat(theme): add event filters |
fix | Fix a bug | fix(plugin): handle empty response |
perf | Improve performance | perf(blocks): reduce render work |
revert | Revert a change | revert: remove event filters |
docs | Documentation only | docs: clarify local setup |
style | Formatting or style change | style: normalize spacing |
refactor | Restructure code without behavior change | refactor(plugin): simplify query setup |
test | Add or update tests | test(theme): cover event filters |
build | Build system or dependency change | build: update build tooling |
ci | CI configuration or scripts | ci: validate pull request titles |
chore | Maintenance tasks | chore: update development dependencies |
When opening a PR:
- Treat the prefilled title as a draft and edit it to match the change.
- Fix the title on the PR page; do not add a commit just to change it.
- Once the repository admin configures squash merging to use the PR title, that title becomes the commit message on
main. The title check does not block merging untilValidate PR titleis required in themainbranch ruleset or protection settings (see CI/CD).
After checking out a branch
Build output (dist/ and similar artifacts) is not committed to the repository. Whenever you check out or pull a branch—especially when reviewing a pull request—refresh dependencies and rebuild so your local environment matches that branch:
pnpm install
pnpm buildRun both from the monorepo root. To rebuild only the project you are reviewing:
pnpm install
npx nx run <project-name>:buildAdding a new repository (greenfield)
Prefer the generators so structure matches standards:
npx nx generate monorepo:theme
# or
npx nx generate monorepo:plugin
pnpm installThen implement features, add docs/index.md for the docs site, and register paths in .github/labeler.yml if needed.
Importing an existing repository (history preservation)
Warning: Import and history rewriting steps must not be run against the original standalone repository. Work from a new clone of the monorepo or a dedicated migration branch.
Preconditions
Coordinate with maintainers before large imports:
- Development freeze on the source repo (optional but recommended) so the import has a clear cut-over commit.
- Final release from the legacy repo if consumers need a last semver from the old remote.
- Access to create tags and run CI in this monorepo.
1. Import Git history (nx import)
npx nx import <git-repository-url> <destination-path>Example:
npx nx import https://github.com/bcgov/design-system-wordpress-theme themes/design-system-wordpress-themeComplete the wizard; history for the subtree is preserved in the monorepo.
2. Align structure with monorepo standards
After import, the tree often needs to match generator output:
- Temporarily rename the imported directory (for example prefix with
_) so generators can write a fresh folder. - Run the appropriate generator (
monorepo:themeormonorepo:plugin) with the same slug as the imported project. - Copy generated files into the renamed import directory, overwriting where appropriate (some hosts block bulk overwrites in the IDE; use the filesystem if needed).
- Remove the empty generator-only directory; restore the imported directory name.
- Use Git to revert any overwrite that should stay legacy (for example real version numbers instead of generator defaults).
- Reconcile runtime dependencies before testing:
- For a child theme, make the parent consistent across
style.css(Template:),.wp-env.json, andproject.json(builddependency andimplicitDependencies). - If templates use blocks from a monorepo plugin, add the plugin to
.wp-env.json, activate it in the environment lifecycle scripts, and add the plugin toimplicitDependencies. - Compare generated browser-test configuration with existing suites. Prefer shared helpers from
@bcew-monorepo/e2ewhen applicable, then regenerate and verify screenshot baselines.
- For a child theme, make the parent consistent across
- Remove redundant per-repo files that now belong at the root (see Shared tooling):
.github/(per-package workflows)dist// build output- Duplicate
.gitignore,.markdownlint*,CODEOWNERSif superseded by monorepo policy composer.lockat package level when the monorepo standard is root + package resolution (follow team practice). A local Composer install may recreate a package-level lockfile; do not commit it.
- Commit the migration; run
pnpm composer-install,npx nx run <project>:build, andpnpm lint.
Tag namespacing after migration
First release from the monorepo must use the Nx project name and tag format:
<nx-project-name>/v<semver>Legacy tags from the old repository are not reused as-is; document mapping for consumers if needed.
Branch naming
Use documented conventions (feature/…, fix/…, chore/…, etc.) so reviewers and automation stay consistent.
Checklist (migration)
After migration: cut over and archive
Once the checklist above is done in the monorepo, retire the standalone GitHub repo. Do not keep developing there.
Recommended order
- Update the standalone README — short notice that the project moved, with a link to the monorepo path (and this docs site if useful).
- Archive the standalone repo on GitHub (do not delete it).
Archiving makes the repo read-only (no new issues, PRs, or pushes). You do not need separate steps to close PRs, lock branches, or migrate issues.
How to archive
On the standalone repository:
- Settings → scroll to Danger Zone.
- Archive this repository → confirm.
History, old releases, and tags stay available for reference. Prefer archive over delete.
After migration: renaming
Import often keeps the legacy folder name. Changing that name (and CSS/JS/PHP that only live in code) is a separate cutover. It is not the temporary _ prefix in Align structure with monorepo standards.
Follow Renaming a plugin or theme: local test, then blog_gov_bc_ca on your branch before the PR.