@afoures/auto-release 0.2.11 → 0.3.0
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.
- package/README.md +30 -269
- package/dist/lib/change-file.mjs +4 -3
- package/dist/lib/commands/check.mjs +10 -10
- package/dist/lib/commands/generate-release-pr.mjs +22 -22
- package/dist/lib/commands/init.mjs +40 -199
- package/dist/lib/commands/list.mjs +10 -10
- package/dist/lib/commands/manual-release.mjs +54 -35
- package/dist/lib/commands/record-change.mjs +19 -19
- package/dist/lib/commands/tag-release-commit.mjs +36 -30
- package/dist/lib/config.d.mts +8 -2
- package/dist/lib/config.mjs +13 -13
- package/dist/lib/formatter.mjs +19 -18
- package/dist/lib/types.d.mts +11 -5
- package/dist/lib/utils/branch-protection.mjs +0 -3
- package/dist/lib/utils/git.mjs +1 -1
- package/dist/lib/utils/version.mjs +3 -3
- package/dist/lib/versioning/types.d.mts +4 -4
- package/docs/change-file-anatomy.md +31 -0
- package/docs/commands.md +80 -0
- package/docs/configuration.md +116 -0
- package/docs/lexicon.md +23 -0
- package/docs/recommended-usage.md +155 -0
- package/package.json +15 -14
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# auto-release
|
|
2
2
|
|
|
3
|
-
A release management tool inspired by Changesets and Release Please, designed for monorepos with
|
|
3
|
+
A release management tool inspired by Changesets and Release Please, designed for monorepos with project-centric versioning.
|
|
4
4
|
|
|
5
5
|
## Why auto-release?
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ Release management should be simple. `auto-release` lets you focus on building f
|
|
|
8
8
|
|
|
9
9
|
**Language agnostic**: Works with any project type. Built-in components for Node, Bun, Expo, and PHP projects, but you can add custom components for anything.
|
|
10
10
|
|
|
11
|
-
**Built for monorepos**: Each
|
|
11
|
+
**Built for monorepos**: Each project can have its own versioning strategy (semver, calver, marketing) and release independently.
|
|
12
12
|
|
|
13
13
|
**Developer-friendly**: Record changes with markdown files as you work. No complex conventions or strict commit messages required.
|
|
14
14
|
|
|
@@ -17,11 +17,13 @@ Release management should be simple. `auto-release` lets you focus on building f
|
|
|
17
17
|
## Quick Start
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
npx
|
|
20
|
+
npx @afoures/auto-release@latest init
|
|
21
21
|
# or
|
|
22
|
-
pnpx
|
|
22
|
+
pnpx @afoures/auto-release@latest init
|
|
23
23
|
# or
|
|
24
|
-
|
|
24
|
+
yarn dlx @afoures/auto-release@latest init
|
|
25
|
+
# or
|
|
26
|
+
bunx @afoures/auto-release@latest init
|
|
25
27
|
```
|
|
26
28
|
|
|
27
29
|
This creates `auto-release.config.ts` and sets up the `.changes` directory.
|
|
@@ -29,9 +31,13 @@ This creates `auto-release.config.ts` and sets up the `.changes` directory.
|
|
|
29
31
|
### Manual Installation
|
|
30
32
|
|
|
31
33
|
```bash
|
|
32
|
-
npm install auto-release
|
|
34
|
+
npm install @afoures/auto-release
|
|
35
|
+
# or
|
|
36
|
+
pnpm add @afoures/auto-release
|
|
37
|
+
# or
|
|
38
|
+
yarn add @afoures/auto-release
|
|
33
39
|
# or
|
|
34
|
-
|
|
40
|
+
bunx add @afoures/auto-release
|
|
35
41
|
```
|
|
36
42
|
|
|
37
43
|
Create `auto-release.config.ts`:
|
|
@@ -43,6 +49,13 @@ import { github } from 'auto-release/providers'
|
|
|
43
49
|
import { node } from 'auto-release/components'
|
|
44
50
|
|
|
45
51
|
export default define_config({
|
|
52
|
+
projects: {
|
|
53
|
+
'my-app': {
|
|
54
|
+
components: [node('packages/my-app')],
|
|
55
|
+
versioning: semver(),
|
|
56
|
+
changelog: 'CHANGELOG.md',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
46
59
|
git: {
|
|
47
60
|
platform: github({
|
|
48
61
|
token: process.env.GITHUB_TOKEN!,
|
|
@@ -51,275 +64,23 @@ export default define_config({
|
|
|
51
64
|
}),
|
|
52
65
|
target_branch: 'main',
|
|
53
66
|
},
|
|
54
|
-
apps: {
|
|
55
|
-
'my-app': {
|
|
56
|
-
components: [node('packages/my-app')],
|
|
57
|
-
versioning: semver(),
|
|
58
|
-
changelog: 'CHANGELOG.md',
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
67
|
})
|
|
62
68
|
```
|
|
63
69
|
|
|
64
|
-
##
|
|
65
|
-
|
|
66
|
-
### 1. Development
|
|
67
|
-
|
|
68
|
-
Make changes and record them:
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
|
-
auto-release record-change
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Commit everything including the change file:
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
git add .
|
|
78
|
-
git commit -m "feat: add new feature"
|
|
79
|
-
git push
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### 2. Generate Release PR
|
|
83
|
-
|
|
84
|
-
On `main` branch, CI should automatically run:
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
auto-release generate-release-pr
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
This creates/updates a release branch with:
|
|
91
|
-
- Updated versions in component files
|
|
92
|
-
- Generated changelog entries
|
|
93
|
-
- Change files removed
|
|
94
|
-
|
|
95
|
-
### 3. Test on Release Branch
|
|
96
|
-
|
|
97
|
-
CI on release branch runs:
|
|
98
|
-
- Tests and quality checks
|
|
99
|
-
- Build and deploy to test/staging environment
|
|
100
|
-
|
|
101
|
-
### 4. Merge Release PR
|
|
102
|
-
|
|
103
|
-
When ready, merge the release PR to `main`.
|
|
104
|
-
|
|
105
|
-
### 5. Tag and Deploy
|
|
106
|
-
|
|
107
|
-
CI on `main` runs:
|
|
108
|
-
|
|
109
|
-
```bash
|
|
110
|
-
auto-release tag-release-commit
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
This creates git tags for all releases, which can trigger deployment to pre-production and production.
|
|
114
|
-
|
|
115
|
-
## Commands
|
|
116
|
-
|
|
117
|
-
### `init`
|
|
118
|
-
|
|
119
|
-
Set up auto-release in your repository:
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
auto-release init
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
Interactively configures apps, versioning strategies, and git platform.
|
|
126
|
-
|
|
127
|
-
### `check`
|
|
128
|
-
|
|
129
|
-
Validate configuration and change files:
|
|
130
|
-
|
|
131
|
-
```bash
|
|
132
|
-
auto-release check
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
Use in CI to ensure everything is valid before merging.
|
|
136
|
-
|
|
137
|
-
### `record-change`
|
|
138
|
-
|
|
139
|
-
Create a new change file:
|
|
140
|
-
|
|
141
|
-
```bash
|
|
142
|
-
# Interactive
|
|
143
|
-
auto-release record-change
|
|
144
|
-
|
|
145
|
-
# Non-interactive
|
|
146
|
-
auto-release record-change --app my-app --type minor
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
### `list`
|
|
150
|
-
|
|
151
|
-
List all apps managed by `auto-release` with their current versions:
|
|
152
|
-
|
|
153
|
-
```bash
|
|
154
|
-
auto-release list
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
### `generate-release-pr`
|
|
158
|
-
|
|
159
|
-
Create or update release PRs:
|
|
160
|
-
|
|
161
|
-
```bash
|
|
162
|
-
# Preview changes
|
|
163
|
-
auto-release generate-release-pr --dry-run
|
|
164
|
-
|
|
165
|
-
# Create/update PRs
|
|
166
|
-
auto-release generate-release-pr
|
|
167
|
-
|
|
168
|
-
# Specific apps only
|
|
169
|
-
auto-release generate-release-pr --app my-app --app another-app
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### `tag-release-commit`
|
|
173
|
-
|
|
174
|
-
Create git tags and releases for version changes:
|
|
175
|
-
|
|
176
|
-
```bash
|
|
177
|
-
# Preview what would be tagged
|
|
178
|
-
auto-release tag-release-commit --dry-run
|
|
179
|
-
|
|
180
|
-
# Create tags and releases
|
|
181
|
-
auto-release tag-release-commit
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
Compares HEAD with HEAD^1 to detect version changes. Creates tags in format `app-name@version`.
|
|
185
|
-
|
|
186
|
-
### `manual-release`
|
|
187
|
-
|
|
188
|
-
Create a manual release using existing change files:
|
|
189
|
-
|
|
190
|
-
```bash
|
|
191
|
-
auto-release manual-release
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
Useful for local testing or emergency releases.
|
|
195
|
-
|
|
196
|
-
## Configuration
|
|
197
|
-
|
|
198
|
-
### Apps
|
|
199
|
-
|
|
200
|
-
The `apps` object defines each releasable unit:
|
|
201
|
-
|
|
202
|
-
```typescript
|
|
203
|
-
apps: {
|
|
204
|
-
'my-app': {
|
|
205
|
-
// Components: where versions are read/written
|
|
206
|
-
components: [
|
|
207
|
-
node('packages/my-app'),
|
|
208
|
-
node('packages/shared'),
|
|
209
|
-
],
|
|
210
|
-
|
|
211
|
-
// Versioning strategy
|
|
212
|
-
versioning: semver(),
|
|
213
|
-
|
|
214
|
-
// Changelog file path
|
|
215
|
-
changelog: 'apps/my-app/CHANGELOG.md',
|
|
216
|
-
},
|
|
217
|
-
}
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
### Versioning Strategies
|
|
221
|
-
|
|
222
|
-
```typescript
|
|
223
|
-
import { semver, calver, markver } from 'auto-release/versioning'
|
|
224
|
-
|
|
225
|
-
// Semantic versioning: 1.2.3
|
|
226
|
-
versioning: semver() // Change types: major, minor, patch
|
|
227
|
-
|
|
228
|
-
// Calendar versioning: 2025.1.2
|
|
229
|
-
versioning: calver() // Change types: feature, fix
|
|
230
|
-
|
|
231
|
-
// Marketing versioning: 1.0.0
|
|
232
|
-
versioning: markver() // Change types: marketing, feature, fix
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
### Git Platforms
|
|
236
|
-
|
|
237
|
-
#### GitHub
|
|
238
|
-
|
|
239
|
-
```typescript
|
|
240
|
-
import { github } from 'auto-release/providers'
|
|
241
|
-
|
|
242
|
-
git: {
|
|
243
|
-
platform: github({
|
|
244
|
-
token: process.env.GITHUB_TOKEN!,
|
|
245
|
-
owner: 'your-org',
|
|
246
|
-
repo: 'your-repo',
|
|
247
|
-
}),
|
|
248
|
-
target_branch: 'main',
|
|
249
|
-
}
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
#### GitLab
|
|
70
|
+
## Documentation
|
|
253
71
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
token: process.env.GITLAB_TOKEN!,
|
|
260
|
-
project_id: 'your-project-id',
|
|
261
|
-
}),
|
|
262
|
-
target_branch: 'main',
|
|
263
|
-
}
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
### Components
|
|
267
|
-
|
|
268
|
-
Components define version sources:
|
|
269
|
-
|
|
270
|
-
- **`node(path)`**: any node project with package.json
|
|
271
|
-
- **`bun(path)`**: any bun project with package.json
|
|
272
|
-
- **`expo(path)`**: any Expo project with package.json and app.json
|
|
273
|
-
- **`php(path)`**: any PHP project with composer.json
|
|
274
|
-
|
|
275
|
-
```typescript
|
|
276
|
-
import { node, expo, php } from 'auto-release/components'
|
|
277
|
-
|
|
278
|
-
components: [
|
|
279
|
-
node('packages/web'),
|
|
280
|
-
bun('packages/bff'),
|
|
281
|
-
expo('apps/mobile'),
|
|
282
|
-
php('packages/api'),
|
|
283
|
-
]
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
## Change Files
|
|
287
|
-
|
|
288
|
-
Change files are stored in `.changes/<app-name>/` with format:
|
|
289
|
-
|
|
290
|
-
```
|
|
291
|
-
<type>.<slug>.md
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
Examples:
|
|
295
|
-
- `.changes/my-app/major.add-authentication.md`
|
|
296
|
-
- `.changes/my-app/patch.fix-login-bug.md`
|
|
297
|
-
|
|
298
|
-
The change files folder can be customized.
|
|
299
|
-
|
|
300
|
-
### Format
|
|
301
|
-
|
|
302
|
-
**Simple** (title only):
|
|
303
|
-
|
|
304
|
-
```markdown
|
|
305
|
-
Fix authentication bug in login flow
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
**Detailed** (with description):
|
|
309
|
-
|
|
310
|
-
```markdown
|
|
311
|
-
This adds a comprehensive user profile page with:
|
|
312
|
-
- Avatar upload
|
|
313
|
-
- Bio and social links
|
|
314
|
-
- Privacy settings
|
|
315
|
-
```
|
|
72
|
+
- [Configuration](./docs/configuration.md)
|
|
73
|
+
- [Recommended usage](./docs/recommended-usage.md)
|
|
74
|
+
- [Change File anatomy](./docs/change-file-anatomy.md)
|
|
75
|
+
- [Commands](./docs/commands.md)
|
|
76
|
+
- [Lexicon](./docs/lexicon.md)
|
|
316
77
|
|
|
317
78
|
## Philosophy
|
|
318
79
|
|
|
319
|
-
Inspired by Changesets and Release Please, designed for
|
|
80
|
+
Inspired by Changesets and Release Please, designed for project-centric monorepos where:
|
|
320
81
|
|
|
321
|
-
- Multiple
|
|
322
|
-
- Change files are organized by
|
|
82
|
+
- Multiple projects release independently with different versioning strategies
|
|
83
|
+
- Change files are organized by project for clarity
|
|
323
84
|
- Release branches allow testing before production
|
|
324
85
|
- Deployment is integrated with the release process
|
|
325
86
|
|
|
@@ -327,4 +88,4 @@ Inspired by Changesets and Release Please, designed for app-centric monorepos wh
|
|
|
327
88
|
|
|
328
89
|
MIT
|
|
329
90
|
|
|
330
|
-
See [LICENSE](./LICENSE)
|
|
91
|
+
See [LICENSE](./LICENSE)
|
package/dist/lib/change-file.mjs
CHANGED
|
@@ -37,11 +37,12 @@ async function parse_change_file(path) {
|
|
|
37
37
|
const filename = basename(path);
|
|
38
38
|
const match = CHANGE_FILENAME_REGEX.exec(filename);
|
|
39
39
|
if (!match) return /* @__PURE__ */ new Error(`Invalid change filename format: ${path} (expected: <kind>.<slug>.md)`);
|
|
40
|
-
|
|
40
|
+
let file_content = await read_file(path);
|
|
41
|
+
file_content = file_content?.trim() ?? null;
|
|
41
42
|
if (file_content === null) return /* @__PURE__ */ new Error(`Change file is missing: ${path}`);
|
|
42
|
-
if (!file_content
|
|
43
|
+
if (!file_content) return /* @__PURE__ */ new Error("Change file is empty");
|
|
43
44
|
const [title, ...rest] = file_content.split("\n");
|
|
44
|
-
const text = `- ${title}
|
|
45
|
+
const text = [`- ${title}`, ...rest.map((line) => ` ${line}`)].join("\n");
|
|
45
46
|
return new ChangeFile({
|
|
46
47
|
slug: match.groups.slug,
|
|
47
48
|
kind: match.groups.kind,
|
|
@@ -6,10 +6,10 @@ import { find_change_files } from "../change-file.mjs";
|
|
|
6
6
|
import { join } from "node:path";
|
|
7
7
|
|
|
8
8
|
//#region src/lib/commands/check.ts
|
|
9
|
-
async function verify_component_version_consistency(
|
|
9
|
+
async function verify_component_version_consistency(project) {
|
|
10
10
|
const versions = /* @__PURE__ */ new Set();
|
|
11
11
|
const errors = [];
|
|
12
|
-
for (const component of
|
|
12
|
+
for (const component of project.components) for (const part of component.parts) {
|
|
13
13
|
const file_content = await read_file(part.file);
|
|
14
14
|
if (file_content === null) {
|
|
15
15
|
errors.push(`component ${component.root} has no version`);
|
|
@@ -19,14 +19,14 @@ async function verify_component_version_consistency(app) {
|
|
|
19
19
|
versions.add(version);
|
|
20
20
|
}
|
|
21
21
|
if (versions.size === 0) {
|
|
22
|
-
errors.push(`
|
|
22
|
+
errors.push(`project ${project.name} has no versions`);
|
|
23
23
|
return {
|
|
24
24
|
ok: false,
|
|
25
25
|
errors
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
if (versions.size > 1) {
|
|
29
|
-
errors.push(`
|
|
29
|
+
errors.push(`project ${project.name} has multiple versions: ${Array.from(versions).join(", ")}`);
|
|
30
30
|
return {
|
|
31
31
|
ok: false,
|
|
32
32
|
errors
|
|
@@ -34,9 +34,9 @@ async function verify_component_version_consistency(app) {
|
|
|
34
34
|
}
|
|
35
35
|
return { ok: true };
|
|
36
36
|
}
|
|
37
|
-
async function validate_changes_files_content(changes_dir,
|
|
37
|
+
async function validate_changes_files_content(changes_dir, project) {
|
|
38
38
|
const errors = [];
|
|
39
|
-
const change_files = await find_change_files(join(changes_dir,
|
|
39
|
+
const change_files = await find_change_files(join(changes_dir, project.name), { allowed_kinds: project.versioning.allowed_changes });
|
|
40
40
|
if (change_files.warnings.length > 0) for (const warning of change_files.warnings) errors.push(warning);
|
|
41
41
|
for (const change_file of change_files.list) if (change_file.summary.length === 0) errors.push(`change file ${change_file.filename} has no summary`);
|
|
42
42
|
if (errors.length > 0) return {
|
|
@@ -47,7 +47,7 @@ async function validate_changes_files_content(changes_dir, app) {
|
|
|
47
47
|
}
|
|
48
48
|
const check = create_command({
|
|
49
49
|
name: "check",
|
|
50
|
-
description: "Validate configuration,
|
|
50
|
+
description: "Validate configuration, versions, and change files",
|
|
51
51
|
schema: { config: {
|
|
52
52
|
type: "string",
|
|
53
53
|
description: "Path to config file"
|
|
@@ -63,10 +63,10 @@ const check = create_command({
|
|
|
63
63
|
const logger = create_logger();
|
|
64
64
|
const errors = [];
|
|
65
65
|
const config = context.config;
|
|
66
|
-
for (const
|
|
67
|
-
const component_validation = await verify_component_version_consistency(
|
|
66
|
+
for (const project of config.managed_projects) {
|
|
67
|
+
const component_validation = await verify_component_version_consistency(project);
|
|
68
68
|
if (!component_validation.ok) errors.push(...component_validation.errors);
|
|
69
|
-
const changes_validation = await validate_changes_files_content(config.changes_dir,
|
|
69
|
+
const changes_validation = await validate_changes_files_content(config.changes_dir, project);
|
|
70
70
|
if (!changes_validation.ok) errors.push(...changes_validation.errors);
|
|
71
71
|
}
|
|
72
72
|
const valid = errors.length === 0;
|
|
@@ -19,7 +19,7 @@ const generate_release_pr = create_command({
|
|
|
19
19
|
},
|
|
20
20
|
filter: {
|
|
21
21
|
type: "string",
|
|
22
|
-
description: "Only generate release PRs for the specified
|
|
22
|
+
description: "Only generate release PRs for the specified projects",
|
|
23
23
|
multiple: true
|
|
24
24
|
},
|
|
25
25
|
"dry-run": {
|
|
@@ -39,17 +39,17 @@ const generate_release_pr = create_command({
|
|
|
39
39
|
},
|
|
40
40
|
run: async ({ args: { filter, "dry-run": dry_run = false }, context: { config, root } }) => {
|
|
41
41
|
const logger = create_logger();
|
|
42
|
-
const
|
|
43
|
-
if (
|
|
42
|
+
const filtered_projects = filter ? config.managed_projects.filter((project) => filter.includes(project.name)) : config.managed_projects;
|
|
43
|
+
if (filtered_projects.length === 0) return {
|
|
44
44
|
status: "success",
|
|
45
|
-
message: "No
|
|
45
|
+
message: "No projects to release"
|
|
46
46
|
};
|
|
47
|
-
for (const
|
|
48
|
-
const changes_dir = join(config.changes_dir,
|
|
49
|
-
const changes = await find_change_files(changes_dir, { allowed_kinds:
|
|
47
|
+
for (const project of filtered_projects) {
|
|
48
|
+
const changes_dir = join(config.changes_dir, project.name);
|
|
49
|
+
const changes = await find_change_files(changes_dir, { allowed_kinds: project.versioning.allowed_changes });
|
|
50
50
|
if (changes.warnings.length > 0) for (const warning of changes.warnings) logger.warn(warning);
|
|
51
|
-
const current_version = await compute_current_version(
|
|
52
|
-
const next_version =
|
|
51
|
+
const current_version = await compute_current_version(project, { get_file_content: (file_path) => read_file(file_path) }) ?? project.versioning.initial_version;
|
|
52
|
+
const next_version = project.versioning.bump({
|
|
53
53
|
version: current_version,
|
|
54
54
|
changes: changes.list,
|
|
55
55
|
date: /* @__PURE__ */ new Date()
|
|
@@ -61,23 +61,23 @@ const generate_release_pr = create_command({
|
|
|
61
61
|
changes_by_kind.set(change.kind, existing);
|
|
62
62
|
}
|
|
63
63
|
const message_lines = [];
|
|
64
|
-
const display_map =
|
|
64
|
+
const display_map = project.versioning.display_map;
|
|
65
65
|
for (const [kind, kind_changes] of changes_by_kind.entries()) {
|
|
66
66
|
const label = display_map[kind]?.plural ?? display_map[kind]?.singular ?? kind;
|
|
67
67
|
message_lines.push(`\n${label}:`);
|
|
68
|
-
for (const change of kind_changes) message_lines.push(`
|
|
68
|
+
for (const change of kind_changes) message_lines.push(` ${change.summary}`);
|
|
69
69
|
}
|
|
70
|
-
logger.note(`Release ${
|
|
70
|
+
logger.note(`Release ${project.name} ${next_version}`, message_lines.join("\n"));
|
|
71
71
|
if (dry_run) continue;
|
|
72
72
|
await delete_all_files_from_folder(changes_dir);
|
|
73
|
-
for (const component of
|
|
73
|
+
for (const component of project.components) for (const part of component.parts) {
|
|
74
74
|
const initial_content = await read_file(part.file);
|
|
75
75
|
if (initial_content === null) continue;
|
|
76
76
|
const updated_content = part.update_version(initial_content, next_version);
|
|
77
77
|
await write_file(part.file, updated_content);
|
|
78
78
|
}
|
|
79
|
-
const formatter =
|
|
80
|
-
const initial_changelog_content = await read_file(
|
|
79
|
+
const formatter = project.versioning.formatter;
|
|
80
|
+
const initial_changelog_content = await read_file(project.changelog);
|
|
81
81
|
const changelog_as_mdast = parse_markdown(initial_changelog_content ?? "");
|
|
82
82
|
const changelog = formatter.transform_markdown(changelog_as_mdast, initial_changelog_content ?? "");
|
|
83
83
|
const updated_changelog_content = formatter.format_changelog({
|
|
@@ -85,25 +85,25 @@ const generate_release_pr = create_command({
|
|
|
85
85
|
releases: [{
|
|
86
86
|
version: next_version,
|
|
87
87
|
changes: changes.list
|
|
88
|
-
}, ...changelog.releases.filter((release) => release.version !== next_version)].sort((a, b) =>
|
|
89
|
-
}, {
|
|
90
|
-
await write_file(
|
|
88
|
+
}, ...changelog.releases.filter((release) => release.version !== next_version)].sort((a, b) => project.versioning.compare(b.version, a.version))
|
|
89
|
+
}, { project: { name: project.name } });
|
|
90
|
+
await write_file(project.changelog, updated_changelog_content);
|
|
91
91
|
const file_operations = await diff(root);
|
|
92
92
|
await reset(root);
|
|
93
93
|
const platform = config.git.platform;
|
|
94
|
-
const release_branch_name = `${config.git.default_release_branch_prefix}/${
|
|
94
|
+
const release_branch_name = `${config.git.default_release_branch_prefix}/${project.name}`;
|
|
95
95
|
await platform.create_or_update_branch({
|
|
96
96
|
branch_name: release_branch_name,
|
|
97
97
|
base_branch_name: config.git.target_branch,
|
|
98
98
|
file_operations,
|
|
99
|
-
commit_message: `chore: prepare release ${
|
|
99
|
+
commit_message: `chore: prepare release ${project.name}@${next_version}`
|
|
100
100
|
});
|
|
101
101
|
await platform.create_or_update_pull_request({
|
|
102
102
|
head_branch_name: release_branch_name,
|
|
103
103
|
base_branch_name: config.git.target_branch,
|
|
104
|
-
title: `release: ${
|
|
104
|
+
title: `release: ${project.name}@${next_version}`,
|
|
105
105
|
body: formatter.generate_pr_body({
|
|
106
|
-
|
|
106
|
+
project: { name: project.name },
|
|
107
107
|
current_version,
|
|
108
108
|
next_version,
|
|
109
109
|
changes: changes.list
|