@regardio/dev 1.24.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/README.md +2 -2
  2. package/dist/bin/ship/hotfix.bin.mjs +140 -0
  3. package/dist/bin/ship/production.bin.mjs +120 -0
  4. package/dist/bin/ship/staging.bin.mjs +70 -0
  5. package/dist/bin/ship/utils-BQ-JZ2D5.mjs +45 -0
  6. package/dist/playwright/index.d.mts +24 -0
  7. package/dist/playwright/index.mjs +61 -0
  8. package/dist/vitest/node.d.mts +22 -0
  9. package/dist/vitest/node.mjs +28 -0
  10. package/dist/vitest/react.d.mts +22 -0
  11. package/dist/vitest/react.mjs +28 -0
  12. package/docs/en/README.md +95 -0
  13. package/docs/en/agents.md +57 -0
  14. package/docs/en/standards/api.md +324 -0
  15. package/docs/en/standards/coding.md +144 -0
  16. package/docs/en/standards/commits.md +111 -0
  17. package/docs/en/standards/documentation.md +173 -0
  18. package/docs/en/standards/naming.md +180 -0
  19. package/docs/en/standards/principles.md +84 -0
  20. package/docs/en/standards/react.md +246 -0
  21. package/docs/en/standards/sql.md +258 -0
  22. package/docs/en/standards/testing.md +139 -0
  23. package/docs/en/standards/writing.md +119 -0
  24. package/docs/en/tools/biome.md +89 -0
  25. package/docs/en/tools/commitlint.md +92 -0
  26. package/docs/en/tools/dependencies.md +116 -0
  27. package/docs/en/tools/husky.md +90 -0
  28. package/docs/en/tools/markdownlint.md +84 -0
  29. package/docs/en/tools/playwright.md +117 -0
  30. package/docs/en/tools/releases.md +242 -0
  31. package/docs/en/tools/typescript.md +89 -0
  32. package/docs/en/tools/vitest.md +146 -0
  33. package/package.json +57 -70
  34. package/src/biome/preset.json +3 -0
  35. package/templates/changeset/README.md +14 -0
  36. package/templates/changeset/config.json +11 -0
  37. package/templates/github/release.yml +77 -0
  38. package/dist/bin/exec/clean.d.ts +0 -3
  39. package/dist/bin/exec/clean.d.ts.map +0 -1
  40. package/dist/bin/exec/clean.js +0 -25
  41. package/dist/bin/exec/clean.test.d.ts +0 -2
  42. package/dist/bin/exec/clean.test.d.ts.map +0 -1
  43. package/dist/bin/exec/clean.test.js +0 -45
  44. package/dist/bin/exec/husky.d.ts +0 -3
  45. package/dist/bin/exec/husky.d.ts.map +0 -1
  46. package/dist/bin/exec/husky.js +0 -9
  47. package/dist/bin/exec/p.d.ts +0 -3
  48. package/dist/bin/exec/p.d.ts.map +0 -1
  49. package/dist/bin/exec/p.js +0 -8
  50. package/dist/bin/exec/s.d.ts +0 -3
  51. package/dist/bin/exec/s.d.ts.map +0 -1
  52. package/dist/bin/exec/s.js +0 -8
  53. package/dist/bin/exec/tsc.d.ts +0 -3
  54. package/dist/bin/exec/tsc.d.ts.map +0 -1
  55. package/dist/bin/exec/tsc.js +0 -8
  56. package/dist/bin/lint/biome.d.ts +0 -3
  57. package/dist/bin/lint/biome.d.ts.map +0 -1
  58. package/dist/bin/lint/biome.js +0 -8
  59. package/dist/bin/lint/commit.d.ts +0 -3
  60. package/dist/bin/lint/commit.d.ts.map +0 -1
  61. package/dist/bin/lint/commit.js +0 -8
  62. package/dist/bin/lint/md.d.ts +0 -3
  63. package/dist/bin/lint/md.d.ts.map +0 -1
  64. package/dist/bin/lint/md.js +0 -16
  65. package/dist/bin/lint/package.d.ts +0 -4
  66. package/dist/bin/lint/package.d.ts.map +0 -1
  67. package/dist/bin/lint/package.js +0 -81
  68. package/dist/bin/lint/package.test.d.ts +0 -2
  69. package/dist/bin/lint/package.test.d.ts.map +0 -1
  70. package/dist/bin/lint/package.test.js +0 -65
  71. package/dist/bin/ship/hotfix.d.ts +0 -3
  72. package/dist/bin/ship/hotfix.d.ts.map +0 -1
  73. package/dist/bin/ship/hotfix.js +0 -141
  74. package/dist/bin/ship/production.d.ts +0 -3
  75. package/dist/bin/ship/production.d.ts.map +0 -1
  76. package/dist/bin/ship/production.js +0 -124
  77. package/dist/bin/ship/staging.d.ts +0 -3
  78. package/dist/bin/ship/staging.d.ts.map +0 -1
  79. package/dist/bin/ship/staging.js +0 -51
  80. package/dist/bin/ship/utils.d.ts +0 -9
  81. package/dist/bin/ship/utils.d.ts.map +0 -1
  82. package/dist/bin/ship/utils.js +0 -63
  83. package/dist/bin/ship/utils.test.d.ts +0 -2
  84. package/dist/bin/ship/utils.test.d.ts.map +0 -1
  85. package/dist/bin/ship/utils.test.js +0 -127
  86. package/dist/config.test.d.ts +0 -2
  87. package/dist/config.test.d.ts.map +0 -1
  88. package/dist/config.test.js +0 -101
  89. package/dist/playwright/index.d.ts +0 -10
  90. package/dist/playwright/index.d.ts.map +0 -1
  91. package/dist/playwright/index.js +0 -42
  92. package/dist/playwright/index.test.d.ts +0 -2
  93. package/dist/playwright/index.test.d.ts.map +0 -1
  94. package/dist/playwright/index.test.js +0 -55
  95. package/dist/testing/setup-react.d.ts +0 -2
  96. package/dist/testing/setup-react.d.ts.map +0 -1
  97. package/dist/testing/setup-react.js +0 -1
  98. package/dist/vitest/node.d.ts +0 -22
  99. package/dist/vitest/node.d.ts.map +0 -1
  100. package/dist/vitest/node.js +0 -16
  101. package/dist/vitest/react.d.ts +0 -17
  102. package/dist/vitest/react.d.ts.map +0 -1
  103. package/dist/vitest/react.js +0 -12
  104. package/src/bin/exec/clean.test.ts +0 -63
  105. package/src/bin/exec/clean.ts +0 -36
  106. package/src/bin/exec/husky.ts +0 -14
  107. package/src/bin/exec/p.ts +0 -13
  108. package/src/bin/exec/s.ts +0 -13
  109. package/src/bin/exec/tsc.ts +0 -13
  110. package/src/bin/lint/biome.ts +0 -13
  111. package/src/bin/lint/commit.ts +0 -13
  112. package/src/bin/lint/md.ts +0 -28
  113. package/src/bin/lint/package.test.ts +0 -83
  114. package/src/bin/lint/package.ts +0 -108
  115. package/src/bin/ship/hotfix.ts +0 -241
  116. package/src/bin/ship/production.ts +0 -240
  117. package/src/bin/ship/staging.ts +0 -108
  118. package/src/bin/ship/utils.test.ts +0 -178
  119. package/src/bin/ship/utils.ts +0 -109
  120. package/src/config.test.ts +0 -129
  121. package/src/markdownlint/markdownlint-cli2.jsonc +0 -9
  122. package/src/playwright/index.test.ts +0 -73
  123. package/src/playwright/index.ts +0 -63
  124. package/src/templates/release.yml +0 -128
  125. package/src/testing/setup-react.ts +0 -8
  126. package/src/vitest/node.ts +0 -25
  127. package/src/vitest/react.ts +0 -19
  128. /package/{src → templates}/sqlfluff/setup.cfg +0 -0
@@ -0,0 +1,116 @@
1
+ ---
2
+
3
+ title: Dependency Handling
4
+ type: guide
5
+ status: published
6
+ summary: Safe dependency updates and supply-chain controls for Regardio workspaces
7
+ related: [releases, typescript, vitest]
8
+ locale: en-US
9
+ ---
10
+
11
+ # Dependency Handling
12
+
13
+ Dependency update workflow and supply-chain controls for Regardio workspaces. Automated updates are combined with pnpm guardrails; the lockfile is authoritative.
14
+
15
+ ## Update workflow
16
+
17
+ - Use `pnpm ncu` to prepare workspace dependency upgrades
18
+ - Install through `pnpm` so workspace-level safety settings are applied
19
+ - Run the normal verification flow after updates:
20
+
21
+ The root `ncu` script uses a 1-day cooldown so it does not propose versions that are newer than the workspace release-age policy.
22
+
23
+ ```bash
24
+ pnpm audit
25
+ pnpm build
26
+ pnpm lint
27
+ pnpm test
28
+ pnpm typecheck
29
+ ```
30
+
31
+ For larger automated upgrade passes, use the existing safety wrapper:
32
+
33
+ ```bash
34
+ pnpm safe-upgrade
35
+ ```
36
+
37
+ ## Workspace safety settings
38
+
39
+ The root `pnpm-workspace.yaml` defines the main supply-chain controls.
40
+
41
+ ### Allow-listed dependency builds
42
+
43
+ Regardio keeps dependency build scripts restricted through `onlyBuiltDependencies`.
44
+
45
+ This means dependencies cannot start running build or postinstall steps unless they are already trusted and listed explicitly. If a package that previously needed no build step suddenly adds one in a compromised release, pnpm will not execute it automatically.
46
+
47
+ When a legitimate dependency genuinely needs a build step, add it deliberately to the allow-list and review why it is required.
48
+
49
+ ### Block exotic transitive dependencies
50
+
51
+ ```yaml
52
+ blockExoticSubdeps: true
53
+ ```
54
+
55
+ This prevents transitive dependencies from resolving through git URLs, tarballs, or other non-registry sources.
56
+
57
+ ### Delay newly published versions
58
+
59
+ ```yaml
60
+ minimumReleaseAge: 1440
61
+ ```
62
+
63
+ We wait 24 hours before pnpm may install a newly published version. This gives time for compromised packages to be detected and removed before they reach the workspace.
64
+
65
+ The root `ncu` script mirrors this with `--cooldown 1`, which helps align version selection with the install policy. pnpm still remains the authoritative enforcement point during installation.
66
+
67
+ ### Prevent trust downgrades
68
+
69
+ ```yaml
70
+ trustPolicy: no-downgrade
71
+ ```
72
+
73
+ If a package release becomes less trustworthy than earlier releases, pnpm rejects the installation instead of silently accepting the downgrade.
74
+
75
+ `npm-check-updates` does not enforce trust policy, build-script allow-lists, or exotic transitive source restrictions. Those safeguards only take effect when `pnpm install` resolves and installs dependencies.
76
+
77
+ ## Lockfile discipline
78
+
79
+ - Commit `pnpm-lock.yaml`
80
+ - Review lockfile changes together with manifest changes
81
+ - Prefer normal installs over ad hoc per-package package manager commands so the workspace lock remains authoritative
82
+
83
+ ## Reviewing dependency updates
84
+
85
+ When an automated update lands, review:
86
+
87
+ - whether the package is direct or transitive
88
+ - whether the update adds or changes a build requirement
89
+ - whether the package affects runtime, build tooling, or release tooling
90
+ - whether overrides should be added for newly disclosed vulnerabilities
91
+
92
+ ## Shipping dependency changes
93
+
94
+ Dependency updates follow the same release gates as any other change.
95
+
96
+ - verify locally before shipping
97
+ - keep changelog subjects clear when a release is primarily dependency maintenance
98
+ - use provenance when publishing public packages
99
+
100
+ ## When to make an exception
101
+
102
+ Exceptions should stay explicit and rare.
103
+
104
+ Examples:
105
+
106
+ - adding a package to `onlyBuiltDependencies`
107
+ - introducing a workspace override for a vulnerable transitive dependency
108
+ - reducing the release-age delay for a security-critical emergency update
109
+
110
+ When an exception is necessary, document the reason in the change itself so later readers can understand why the safer default was not enough.
111
+
112
+ Related documents:
113
+
114
+ - [Release Workflow](./releases.md) — Automated release process for Regardio packages
115
+ - [Testing Approach](../standards/testing.md) — Testing philosophy and patterns for Regardio projects
116
+ - [TypeScript Configuration](./typescript.md) — TypeScript setup and configuration for Regardio projects
@@ -0,0 +1,90 @@
1
+ ---
2
+
3
+ title: Husky
4
+ type: guide
5
+ status: published
6
+ summary: Git hooks for quality gates
7
+ related: [commitlint, biome]
8
+ locale: en-US
9
+ ---
10
+
11
+ # Husky
12
+
13
+ Runs quality checks at commit time via Git hooks. Configured through `@regardio/dev`; bypass only in genuine emergencies.
14
+
15
+ ## Setup
16
+
17
+ Husky is configured automatically via the `prepare` script:
18
+
19
+ ```json
20
+ {
21
+ "scripts": {
22
+ "prepare": "exec-husky"
23
+ }
24
+ }
25
+ ```
26
+
27
+ This runs after `pnpm install` and sets up the `.husky` directory.
28
+
29
+ ## Hooks
30
+
31
+ ### commit-msg
32
+
33
+ Validates commit messages against conventional commit format:
34
+
35
+ ```bash
36
+ #!/bin/sh
37
+ pnpm lint-commit --edit $1
38
+ ```
39
+
40
+ ### pre-commit (optional)
41
+
42
+ Run linting before commit:
43
+
44
+ ```bash
45
+ #!/bin/sh
46
+ pnpm lint
47
+ ```
48
+
49
+ ## CLI Wrapper
50
+
51
+ Use `exec-husky` instead of `husky` directly. This wrapper handles monorepo scenarios correctly.
52
+
53
+ ## Bypassing Hooks
54
+
55
+ In rare cases where you need to skip hooks:
56
+
57
+ ```bash
58
+ git commit --no-verify -m "emergency fix"
59
+ ```
60
+
61
+ Use sparingly and only when absolutely necessary.
62
+
63
+ ## Troubleshooting
64
+
65
+ ### Hooks not running
66
+
67
+ Ensure Husky is installed:
68
+
69
+ ```bash
70
+ pnpm install
71
+ ```
72
+
73
+ Check that `.husky` directory exists and contains hook files.
74
+
75
+ ### Permission denied
76
+
77
+ Make hooks executable:
78
+
79
+ ```bash
80
+ chmod +x .husky/*
81
+ ```
82
+
83
+ Related documents:
84
+
85
+ - [Commitlint](./commitlint.md) — Commit message validation
86
+ - [Biome](./biome.md) — Linting and formatting
87
+
88
+ ### Resources
89
+
90
+ - [Husky Documentation](https://typicode.github.io/husky/)
@@ -0,0 +1,84 @@
1
+ ---
2
+
3
+ title: Markdownlint
4
+ type: guide
5
+ status: published
6
+ summary: Linting and formatting for Markdown files
7
+ related: [biome]
8
+ locale: en-US
9
+ ---
10
+
11
+ # Markdownlint
12
+
13
+ Lints Markdown structure and formatting. Rules are centralized in `@regardio/dev`; use the `lint-md` wrapper instead of calling the tool directly.
14
+
15
+ ## Configuration
16
+
17
+ Create `.markdownlint.json` in your package root:
18
+
19
+ ```json
20
+ {
21
+ "extends": "@regardio/dev/markdownlint"
22
+ }
23
+ ```
24
+
25
+ ## Scripts
26
+
27
+ ```json
28
+ {
29
+ "scripts": {
30
+ "fix:md": "lint-md --fix \"**/*.md\" \"**/*.mdx\" \"!**/node_modules/**\" \"!**/dist/**\"",
31
+ "lint:md": "lint-md \"**/*.md\" \"**/*.mdx\" \"!**/node_modules/**\" \"!**/dist/**\""
32
+ }
33
+ }
34
+ ```
35
+
36
+ ## CLI Wrapper
37
+
38
+ Use `lint-md` instead of `markdownlint-cli2` directly:
39
+
40
+ ```bash
41
+ lint-md "**/*.md" # Check all Markdown files
42
+ lint-md --fix "**/*.md" # Auto-fix issues
43
+ ```
44
+
45
+ ## Key Rules
46
+
47
+ | Rule | Description |
48
+ |------|-------------|
49
+ | MD001 | Heading levels increment by one |
50
+ | MD003 | Consistent heading style (ATX) |
51
+ | MD009 | No trailing spaces |
52
+ | MD012 | No multiple consecutive blank lines |
53
+ | MD022 | Headings surrounded by blank lines |
54
+ | MD032 | Lists surrounded by blank lines |
55
+ | MD041 | First line should be a top-level heading |
56
+
57
+ ## Ignoring Rules
58
+
59
+ For specific files or sections:
60
+
61
+ ```markdown
62
+ <!-- markdownlint-disable MD013 -->
63
+ This line can be very long without triggering a warning.
64
+ <!-- markdownlint-enable MD013 -->
65
+ ```
66
+
67
+ Or in config for specific files:
68
+
69
+ ```json
70
+ {
71
+ "extends": "@regardio/dev/markdownlint",
72
+ "ignores": ["CHANGELOG.md"]
73
+ }
74
+ ```
75
+
76
+ Related documents:
77
+
78
+ - [Documentation](../standards/documentation.md) — Structure and conventions
79
+ - [Biome](./biome.md) — Fast, unified linting and formatting
80
+
81
+ ### Resources
82
+
83
+ - [Markdownlint Rules](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md)
84
+ - [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2)
@@ -0,0 +1,117 @@
1
+ ---
2
+
3
+ title: Playwright
4
+ type: guide
5
+ status: published
6
+ summary: End-to-end testing for web applications
7
+ related: [vitest]
8
+ locale: en-US
9
+ ---
10
+
11
+ # Playwright
12
+
13
+ End-to-end testing for web applications. Prefer role-based, accessible selectors. Use E2E tests for critical user workflows, not as a substitute for unit or integration tests.
14
+
15
+ ## Configuration
16
+
17
+ ```typescript
18
+ // playwright.config.ts
19
+ import { defineConfig, devices } from '@playwright/test';
20
+ import { buildPlaywrightBaseConfig } from '@regardio/dev/playwright';
21
+
22
+ export default defineConfig(
23
+ buildPlaywrightBaseConfig({
24
+ appPort: 5100,
25
+ appUrl: 'http://localhost:5100',
26
+ devices,
27
+ webServerCommand: 'vite preview',
28
+ }),
29
+ );
30
+ ```
31
+
32
+ ## Scripts
33
+
34
+ ```json
35
+ {
36
+ "scripts": {
37
+ "test:e2e": "playwright test"
38
+ }
39
+ }
40
+ ```
41
+
42
+ ## Running Tests
43
+
44
+ ```bash
45
+ pnpm test:e2e # Run all E2E tests
46
+ pnpm playwright test --ui # Interactive UI mode
47
+ pnpm playwright test --debug # Debug mode with inspector
48
+ pnpm playwright show-report # View HTML report
49
+ ```
50
+
51
+ ## Writing Tests
52
+
53
+ ```typescript
54
+ import { test, expect } from '@playwright/test';
55
+
56
+ test('user can submit contact form', async ({ page }) => {
57
+ await page.goto('/contact');
58
+
59
+ await page.getByLabel('Email').fill('user@example.com');
60
+ await page.getByLabel('Message').fill('Hello!');
61
+ await page.getByRole('button', { name: 'Submit' }).click();
62
+
63
+ await expect(page.getByText('Message sent')).toBeVisible();
64
+ });
65
+ ```
66
+
67
+ ## Best Practices
68
+
69
+ ### Use Role-Based Selectors
70
+
71
+ ```typescript
72
+ // Preferred - accessible and resilient
73
+ await page.getByRole('button', { name: 'Submit' });
74
+ await page.getByLabel('Email');
75
+
76
+ // Avoid - brittle
77
+ await page.locator('.submit-btn');
78
+ await page.locator('#email-input');
79
+ ```
80
+
81
+ ### Add data-test Attributes
82
+
83
+ For elements without accessible names:
84
+
85
+ ```tsx
86
+ <div data-test="user-avatar">{avatar}</div>
87
+ ```
88
+
89
+ ```typescript
90
+ await page.getByTestId('user-avatar');
91
+ ```
92
+
93
+ ### Page Object Pattern
94
+
95
+ For complex pages, use page objects:
96
+
97
+ ```typescript
98
+ class LoginPage {
99
+ constructor(private page: Page) {}
100
+
101
+ async login(email: string, password: string) {
102
+ await this.page.getByLabel('Email').fill(email);
103
+ await this.page.getByLabel('Password').fill(password);
104
+ await this.page.getByRole('button', { name: 'Sign in' }).click();
105
+ }
106
+ }
107
+ ```
108
+
109
+ Related documents:
110
+
111
+ - [Testing Approach](../standards/testing.md) — Testing philosophy and patterns for Regardio projects
112
+ - [Vitest](./vitest.md) — Unit and integration testing for TypeScript projects
113
+
114
+ ### Resources
115
+
116
+ - [Playwright Documentation](https://playwright.dev/)
117
+ - [Best Practices](https://playwright.dev/docs/best-practices)
@@ -0,0 +1,242 @@
1
+ ---
2
+
3
+ title: Release Workflow
4
+ type: guide
5
+ status: published
6
+ summary: GitLab-flow release process with Changesets for Regardio packages
7
+ related: [commitlint]
8
+ locale: en-US
9
+ ---
10
+
11
+ # Release Workflow
12
+
13
+ Branch-based release workflow for Regardio packages. `main` → `staging` → `production`. Versioning is driven by [Changesets](https://github.com/changesets/changesets); quality gates run locally before any branch promotion.
14
+
15
+ ## Overview
16
+
17
+ Branches mirror deployment environments:
18
+
19
+ ```text
20
+ main → staging (optional) → production
21
+ ```
22
+
23
+ - **`main`** — active development, always deployable. Authors add a changeset (`pnpm changeset`) alongside each version-worthy change.
24
+ - **`staging`** — optional validation environment. No versioning happens here.
25
+ - **`production`** — versioned, published code only.
26
+
27
+ Changesets decide what bumps. When `ship-production` runs, it consumes every pending changeset, bumps affected packages, rewrites each package's `CHANGELOG.md`, and commits the result on `main` before merging to `production`. CI on `production` runs `changeset publish` to push the new versions to npm.
28
+
29
+ ## How It Works
30
+
31
+ ### Design principles
32
+
33
+ 1. **Branches mirror environments.** `staging` reflects what is deployed to the staging server (when used); `production` always reflects what is published to npm. There is never ambiguity about what is running where.
34
+ 2. **Changesets drive versioning.** A bump is declared in a `.changeset/*.md` file alongside the code change, not chosen at ship time. Every published version corresponds to a set of consumed changesets.
35
+ 3. **Version numbers are a production guarantee.** Bumps are applied only at `ship-production` time. This means every version tag in git and every release on npm corresponds to code that has been validated and shipped.
36
+ 4. **Staging is optional.** You can ship directly from `main` to `production`. Use `ship-staging` when you want to test changes in a staging environment first. Either way, `staging` is automatically synced with `production` after each ship.
37
+ 5. **Tests are a local gate, not a CI gate.** Quality checks (`build`, `typecheck`, `test`) run on your machine before any commit is made. Broken code cannot enter the repository. CI only runs `build` and `publish`.
38
+ 6. **You always land back on `main`.** Every command returns you to `main` when it finishes.
39
+
40
+ ### Full flow diagram
41
+
42
+ ```text
43
+ pnpm changeset (on main, alongside your change)
44
+ ┌──────────────────────────┐
45
+ │ write .changeset/<x>.md │
46
+ main ───────────────┤ commit + push ├──► main
47
+ └──────────────────────────┘
48
+
49
+ ship-staging (OPTIONAL)
50
+ ┌──────────────────────────┐
51
+ main ───────────────┤ quality checks pass ├──► staging (pushed)
52
+ │ ff-merge main → staging │
53
+ └──────────────────────────┘
54
+
55
+ (validated in staging)
56
+
57
+
58
+ ship-production
59
+ ┌──────────────────────────┐
60
+ │ quality checks on main │
61
+ │ pnpm changeset version │
62
+ main ───────────────┤ bumps + CHANGELOG.md ├──► production
63
+ │ chore(release): ... │
64
+ │ ff-merge main → prod │
65
+ │ ff-merge prod → staging │
66
+ │ sync back to main │
67
+ └──────────────────────────┘
68
+
69
+ (CI: pnpm changeset publish → npm + git tags)
70
+
71
+ production
72
+
73
+
74
+ ship-hotfix start fix-name
75
+ ┌──────────────────────────┐
76
+ production ─────────┤ create hotfix/fix-name ├──► hotfix/fix-name
77
+ └──────────────────────────┘
78
+
79
+ (author fixes + pnpm changeset)
80
+
81
+ ship-hotfix finish
82
+ ┌──────────────────────────┐
83
+ │ quality checks │
84
+ │ pnpm changeset version │
85
+ hotfix/fix-name ────┤ bumps + CHANGELOG.md ├──► production → staging → main
86
+ │ merge to production │
87
+ │ propagate to staging │
88
+ │ propagate to main │
89
+ └──────────────────────────┘
90
+ ```
91
+
92
+ ### What each branch represents at any point in time
93
+
94
+ | Branch | Contains | Version bumped? |
95
+ |--------|----------|-----------------|
96
+ | `main` | All committed, tested work + pending `.changeset/*.md` files | Only after `ship-production` / `ship-hotfix finish` |
97
+ | `staging` | Synced from `production` after each ship, or from `main` via `ship-staging` | After a ship propagates |
98
+ | `production` | Only shipped, versioned releases | Yes — always |
99
+
100
+ ### CI role
101
+
102
+ CI is intentionally minimal. It does not re-run tests. On push to `production` it:
103
+
104
+ 1. Installs dependencies and builds
105
+ 2. Runs `pnpm changeset publish` — publishes every workspace package whose current version is not yet on npm, skipping `private: true` packages, and creates git tags per published package
106
+ 3. Pushes the tags
107
+
108
+ ## Commands
109
+
110
+ | Command | Usage | Purpose |
111
+ |---------|-------|---------|
112
+ | `pnpm changeset` | interactive | Declare a version bump alongside your change |
113
+ | `ship-staging` | `ship-staging` | (Optional) Deploy changes to staging for testing |
114
+ | `ship-production` | `ship-production` | Consume changesets, merge main → production, trigger publish |
115
+ | `ship-hotfix start <name>` | `ship-hotfix start <name>` | Create a hotfix branch from production |
116
+ | `ship-hotfix finish` | `ship-hotfix finish` | Consume changesets, propagate hotfix through production → staging → main |
117
+
118
+ Bump types (`patch` / `minor` / `major`) are no longer passed on the command line — they come from the changeset files.
119
+
120
+ ## Typical Release Flow
121
+
122
+ ### 1. Author a change with a changeset
123
+
124
+ On `main`:
125
+
126
+ ```bash
127
+ # make your code change
128
+ pnpm changeset # choose packages, bump type, write a one-line description
129
+ git add .
130
+ git commit -m "feat: ..."
131
+ git push
132
+ ```
133
+
134
+ A file like `.changeset/lively-otters-hop.md` is committed with the change.
135
+
136
+ ### 2. Ship to production
137
+
138
+ ```bash
139
+ pnpm ship:production
140
+ ```
141
+
142
+ This will:
143
+
144
+ 1. Guard: must be on `main`, working tree clean
145
+ 2. Fetch and verify `staging` + `production` branches exist
146
+ 3. Show commits to be shipped, report pending changeset count, ask for confirmation
147
+ 4. Run full quality suite on `main` — aborts on failure
148
+ 5. Run `pnpm changeset version` — bumps versions, rewrites `CHANGELOG.md` per package, deletes consumed changeset files
149
+ 6. Format modified files
150
+ 7. Commit with `chore(release): version packages` on `main`
151
+ 8. Fast-forward merge `main` into `production` and push
152
+ 9. Sync `staging` with `production`
153
+ 10. Return to `main`
154
+
155
+ CI on `production` runs `pnpm changeset publish` to push the new versions to npm and create tags.
156
+
157
+ ### Option: Test in staging first
158
+
159
+ ```bash
160
+ pnpm ship:staging
161
+ ```
162
+
163
+ Deploys `main` to `staging` without touching versions. Useful for validating in a staging environment before shipping to production.
164
+
165
+ ## Hotfix Flow
166
+
167
+ For urgent fixes that must go directly to production:
168
+
169
+ ```bash
170
+ pnpm ship:hotfix start fix-auth-bug
171
+ # apply your fix
172
+ pnpm changeset # describe the fix and the bump
173
+ git add . && git commit -m "fix: ..."
174
+ pnpm ship:hotfix finish
175
+ ```
176
+
177
+ `finish` consumes the pending changeset, bumps the version, then merges `hotfix → production → staging → main` and deletes the hotfix branch. CI publishes from `production`.
178
+
179
+ ## Adoption
180
+
181
+ Install `@regardio/dev` and:
182
+
183
+ 1. **Initialize Changesets** — copy the template:
184
+
185
+ ```bash
186
+ cp -r node_modules/@regardio/dev/templates/changeset .changeset
187
+ ```
188
+
189
+ 2. **Add the scripts to `package.json`**:
190
+
191
+ ```json
192
+ {
193
+ "scripts": {
194
+ "changeset": "changeset",
195
+ "changeset:publish": "changeset publish",
196
+ "changeset:version": "changeset version",
197
+ "ship:hotfix": "ship-hotfix",
198
+ "ship:production": "ship-production",
199
+ "ship:staging": "ship-staging"
200
+ }
201
+ }
202
+ ```
203
+
204
+ 3. **Create the branches**:
205
+
206
+ ```bash
207
+ git checkout -b staging && git push -u origin staging
208
+ git checkout -b production && git push -u origin production
209
+ git checkout main
210
+ ```
211
+
212
+ 4. **Copy the release workflow** for your forge:
213
+
214
+ ```bash
215
+ mkdir -p .github/workflows
216
+ cp node_modules/@regardio/dev/templates/github/release.yml .github/workflows/release.yml
217
+ ```
218
+
219
+ 5. **First publish of any new package must be done locally**:
220
+
221
+ ```bash
222
+ pnpm build && npm publish --access public
223
+ ```
224
+
225
+ ## Quality Gates
226
+
227
+ Every ship command enforces the same gates — no broken code reaches any environment:
228
+
229
+ ```bash
230
+ pnpm build # Must succeed
231
+ pnpm typecheck # Must succeed
232
+ pnpm test # Must succeed
233
+ ```
234
+
235
+ ## Private Packages
236
+
237
+ Packages that should never be published to npm must set `"private": true` in `package.json`. `changeset publish` skips them automatically. The git flow (`ship-staging`, `ship-production`, `ship-hotfix`) works identically for private packages — changesets, version bumps, and branch promotion all continue as normal; only the npm publish step is skipped.
238
+
239
+ Related documents:
240
+
241
+ - [Commit Conventions](../standards/commits.md) — Conventional commits for consistent history
242
+ - [Commitlint](./commitlint.md) — Commit message validation