@auto-engineer/release-automation 0.24.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/CHANGELOG.md +26 -0
- package/LICENSE +10 -0
- package/README.md +560 -0
- package/dist/bin/release-automation.d.ts +3 -0
- package/dist/bin/release-automation.d.ts.map +1 -0
- package/dist/bin/release-automation.js +7 -0
- package/dist/bin/release-automation.js.map +1 -0
- package/dist/src/cli/commands/check.d.ts +3 -0
- package/dist/src/cli/commands/check.d.ts.map +1 -0
- package/dist/src/cli/commands/check.js +77 -0
- package/dist/src/cli/commands/check.js.map +1 -0
- package/dist/src/cli/commands/generate.d.ts +3 -0
- package/dist/src/cli/commands/generate.d.ts.map +1 -0
- package/dist/src/cli/commands/generate.js +100 -0
- package/dist/src/cli/commands/generate.js.map +1 -0
- package/dist/src/cli/commands/index.d.ts +3 -0
- package/dist/src/cli/commands/index.d.ts.map +1 -0
- package/dist/src/cli/commands/index.js +3 -0
- package/dist/src/cli/commands/index.js.map +1 -0
- package/dist/src/cli/index.d.ts +2 -0
- package/dist/src/cli/index.d.ts.map +1 -0
- package/dist/src/cli/index.js +15 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/cli/utils/exit-codes.d.ts +11 -0
- package/dist/src/cli/utils/exit-codes.d.ts.map +1 -0
- package/dist/src/cli/utils/exit-codes.js +10 -0
- package/dist/src/cli/utils/exit-codes.js.map +1 -0
- package/dist/src/cli/utils/index.d.ts +3 -0
- package/dist/src/cli/utils/index.d.ts.map +1 -0
- package/dist/src/cli/utils/index.js +3 -0
- package/dist/src/cli/utils/index.js.map +1 -0
- package/dist/src/cli/utils/logger.d.ts +6 -0
- package/dist/src/cli/utils/logger.d.ts.map +1 -0
- package/dist/src/cli/utils/logger.js +17 -0
- package/dist/src/cli/utils/logger.js.map +1 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +3 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lib/changelog/generator.d.ts +10 -0
- package/dist/src/lib/changelog/generator.d.ts.map +1 -0
- package/dist/src/lib/changelog/generator.js +47 -0
- package/dist/src/lib/changelog/generator.js.map +1 -0
- package/dist/src/lib/changelog/index.d.ts +3 -0
- package/dist/src/lib/changelog/index.d.ts.map +1 -0
- package/dist/src/lib/changelog/index.js +3 -0
- package/dist/src/lib/changelog/index.js.map +1 -0
- package/dist/src/lib/changelog/providers/anthropic-api.d.ts +9 -0
- package/dist/src/lib/changelog/providers/anthropic-api.d.ts.map +1 -0
- package/dist/src/lib/changelog/providers/anthropic-api.js +77 -0
- package/dist/src/lib/changelog/providers/anthropic-api.js.map +1 -0
- package/dist/src/lib/changelog/providers/claude-cli.d.ts +7 -0
- package/dist/src/lib/changelog/providers/claude-cli.d.ts.map +1 -0
- package/dist/src/lib/changelog/providers/claude-cli.js +63 -0
- package/dist/src/lib/changelog/providers/claude-cli.js.map +1 -0
- package/dist/src/lib/changelog/providers/index.d.ts +4 -0
- package/dist/src/lib/changelog/providers/index.d.ts.map +1 -0
- package/dist/src/lib/changelog/providers/index.js +4 -0
- package/dist/src/lib/changelog/providers/index.js.map +1 -0
- package/dist/src/lib/changelog/providers/simple.d.ts +7 -0
- package/dist/src/lib/changelog/providers/simple.d.ts.map +1 -0
- package/dist/src/lib/changelog/providers/simple.js +33 -0
- package/dist/src/lib/changelog/providers/simple.js.map +1 -0
- package/dist/src/lib/changeset/index.d.ts +4 -0
- package/dist/src/lib/changeset/index.d.ts.map +1 -0
- package/dist/src/lib/changeset/index.js +4 -0
- package/dist/src/lib/changeset/index.js.map +1 -0
- package/dist/src/lib/changeset/parser.d.ts +18 -0
- package/dist/src/lib/changeset/parser.d.ts.map +1 -0
- package/dist/src/lib/changeset/parser.js +52 -0
- package/dist/src/lib/changeset/parser.js.map +1 -0
- package/dist/src/lib/changeset/semver.d.ts +15 -0
- package/dist/src/lib/changeset/semver.d.ts.map +1 -0
- package/dist/src/lib/changeset/semver.js +29 -0
- package/dist/src/lib/changeset/semver.js.map +1 -0
- package/dist/src/lib/changeset/writer.d.ts +17 -0
- package/dist/src/lib/changeset/writer.d.ts.map +1 -0
- package/dist/src/lib/changeset/writer.js +33 -0
- package/dist/src/lib/changeset/writer.js.map +1 -0
- package/dist/src/lib/config/index.d.ts +3 -0
- package/dist/src/lib/config/index.d.ts.map +1 -0
- package/dist/src/lib/config/index.js +2 -0
- package/dist/src/lib/config/index.js.map +1 -0
- package/dist/src/lib/config/loader.d.ts +23 -0
- package/dist/src/lib/config/loader.d.ts.map +1 -0
- package/dist/src/lib/config/loader.js +89 -0
- package/dist/src/lib/config/loader.js.map +1 -0
- package/dist/src/lib/config/types.d.ts +6 -0
- package/dist/src/lib/config/types.d.ts.map +1 -0
- package/dist/src/lib/config/types.js +2 -0
- package/dist/src/lib/config/types.js.map +1 -0
- package/dist/src/lib/git/commits.d.ts +33 -0
- package/dist/src/lib/git/commits.d.ts.map +1 -0
- package/dist/src/lib/git/commits.js +174 -0
- package/dist/src/lib/git/commits.js.map +1 -0
- package/dist/src/lib/git/index.d.ts +2 -0
- package/dist/src/lib/git/index.d.ts.map +1 -0
- package/dist/src/lib/git/index.js +2 -0
- package/dist/src/lib/git/index.js.map +1 -0
- package/dist/src/lib/index.d.ts +6 -0
- package/dist/src/lib/index.d.ts.map +1 -0
- package/dist/src/lib/index.js +6 -0
- package/dist/src/lib/index.js.map +1 -0
- package/dist/src/lib/packages/discovery.d.ts +18 -0
- package/dist/src/lib/packages/discovery.d.ts.map +1 -0
- package/dist/src/lib/packages/discovery.js +76 -0
- package/dist/src/lib/packages/discovery.js.map +1 -0
- package/dist/src/lib/packages/index.d.ts +2 -0
- package/dist/src/lib/packages/index.d.ts.map +1 -0
- package/dist/src/lib/packages/index.js +2 -0
- package/dist/src/lib/packages/index.js.map +1 -0
- package/dist/src/types/index.d.ts +54 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +2 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +66 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# @auto-engineer/release-automation
|
|
2
|
+
|
|
3
|
+
## 0.24.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`9f33c48`](https://github.com/BeOnAuto/auto-engineer/commit/9f33c48a5e345b4e0735951c2b77d47d5e936d78) Thanks [@github-actions[bot]](https://github.com/github-actions%5Bbot%5D)! - - **packages/narrative**: adds id field to data
|
|
8
|
+
- **cli**: consolidate servers onto single port
|
|
9
|
+
- **pipeline**: add getHttpServer() method to PipelineServer
|
|
10
|
+
- **cli**: update package.json exports for server and add types
|
|
11
|
+
- **cli**: update Ketchup Plan and streamline startServer implementation
|
|
12
|
+
|
|
13
|
+
## 0.23.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- [#40](https://github.com/BeOnAuto/auto-engineer/pull/40) [`c7e4f17`](https://github.com/BeOnAuto/auto-engineer/commit/c7e4f1774937ead19fe46e9d3ca19208cbc24f16) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **global**: create @auto-engineer/release-automation package
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- [`48a1981`](https://github.com/BeOnAuto/auto-engineer/commit/48a1981f2ea9e345a62f1cedd646016a9fb5ace0) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - Consolidated CI jobs for more efficient build and release processes
|
|
22
|
+
- Fixed binary linking issue in release automation that could prevent proper package publishing
|
|
23
|
+
|
|
24
|
+
- [#40](https://github.com/BeOnAuto/auto-engineer/pull/40) [`c7e4f17`](https://github.com/BeOnAuto/auto-engineer/commit/c7e4f1774937ead19fe46e9d3ca19208cbc24f16) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **global**: add explicit exit 0 to pre-push hook
|
|
25
|
+
|
|
26
|
+
- [`42ad1e5`](https://github.com/BeOnAuto/auto-engineer/commit/42ad1e5bb31b89b56b920ed84a151a7c68dd2e5b) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - Fixed an issue where special characters in commit messages could break Slack notifications
|
package/LICENSE
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Elastic License 2.0
|
|
2
|
+
|
|
3
|
+
Copyright 2024 Sam Hatoum
|
|
4
|
+
|
|
5
|
+
This software and associated documentation files (the "Software") are licensed under the Elastic License 2.0 (the "License"). You may not use this file except in compliance with the License.
|
|
6
|
+
|
|
7
|
+
You may obtain a copy of the License at:
|
|
8
|
+
https://www.elastic.co/licensing/elastic-license
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
# @auto-engineer/release-automation
|
|
2
|
+
|
|
3
|
+
Automated release management with changesets and conventional commits.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ **Automated changeset generation** from conventional commits
|
|
8
|
+
- ✅ **AI-powered changelogs** with Claude CLI, Anthropic API, or simple fallback
|
|
9
|
+
- ✅ **Git hook integration** for pre-push automation
|
|
10
|
+
- ✅ **GitHub Actions support** for CI/CD workflows
|
|
11
|
+
- ✅ **Configurable** via environment variables or config files
|
|
12
|
+
- ✅ **OSS-friendly** with free tier AI options and simple fallback
|
|
13
|
+
- ✅ **Library + CLI** - use programmatically or from command line
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm add -D @auto-engineer/release-automation
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### CLI Usage
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Generate changeset from conventional commits
|
|
27
|
+
release-automation generate
|
|
28
|
+
|
|
29
|
+
# Preview without creating file
|
|
30
|
+
release-automation generate --dry-run
|
|
31
|
+
|
|
32
|
+
# Check if changesets exist
|
|
33
|
+
release-automation check --verbose
|
|
34
|
+
|
|
35
|
+
# Force simple changelog (no AI)
|
|
36
|
+
release-automation generate --provider simple
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Library Usage
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import {
|
|
43
|
+
getCommitsSinceLastChangeset,
|
|
44
|
+
parseConventionalCommits,
|
|
45
|
+
determineBumpType,
|
|
46
|
+
generateChangelog,
|
|
47
|
+
createChangesetFile,
|
|
48
|
+
discoverPackages,
|
|
49
|
+
} from '@auto-engineer/release-automation';
|
|
50
|
+
|
|
51
|
+
// Get commits since last changeset
|
|
52
|
+
const commitHashes = getCommitsSinceLastChangeset();
|
|
53
|
+
|
|
54
|
+
// Parse conventional commits
|
|
55
|
+
const commits = parseConventionalCommits(commitHashes);
|
|
56
|
+
|
|
57
|
+
// Determine semver bump type
|
|
58
|
+
const bumpType = determineBumpType(commits); // 'major' | 'minor' | 'patch'
|
|
59
|
+
|
|
60
|
+
// Generate AI changelog
|
|
61
|
+
const description = await generateChangelog(commits);
|
|
62
|
+
|
|
63
|
+
// Discover packages from changeset config
|
|
64
|
+
const packages = await discoverPackages();
|
|
65
|
+
|
|
66
|
+
// Create changeset file
|
|
67
|
+
createChangesetFile({ bumpType, commits, description }, packages);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## CLI Commands
|
|
71
|
+
|
|
72
|
+
### `generate`
|
|
73
|
+
|
|
74
|
+
Generate changeset from conventional commits.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
release-automation generate [options]
|
|
78
|
+
|
|
79
|
+
Options:
|
|
80
|
+
--since <ref> Git reference to compare against
|
|
81
|
+
--provider <type> Changelog provider (claude-cli|anthropic-api|simple|auto) (default: "auto")
|
|
82
|
+
--no-amend Do not amend the last commit
|
|
83
|
+
--dry-run Preview changeset without creating file
|
|
84
|
+
--config <path> Path to release config file
|
|
85
|
+
--changeset-dir <path> Changeset directory (default: .changeset)
|
|
86
|
+
--packages <names> Comma-separated package names (overrides config)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Exit codes:**
|
|
90
|
+
- `0` - Success
|
|
91
|
+
- `1` - General error
|
|
92
|
+
- `10` - No changesets found (with `--require-changesets`)
|
|
93
|
+
- `11` - No commits to process
|
|
94
|
+
- `12` - No conventional commits found
|
|
95
|
+
- `20` - Configuration error
|
|
96
|
+
- `30` - Git error
|
|
97
|
+
|
|
98
|
+
### `check`
|
|
99
|
+
|
|
100
|
+
Check for pending changesets or commits that need changesets.
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
release-automation check [options]
|
|
104
|
+
|
|
105
|
+
Options:
|
|
106
|
+
--since <ref> Check commits since this reference
|
|
107
|
+
-v, --verbose Show detailed information
|
|
108
|
+
--require-changesets Exit with error if no changesets exist
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Configuration
|
|
112
|
+
|
|
113
|
+
### Environment Variables
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Enable/disable features
|
|
117
|
+
AUTO_CHANGESET_ENABLED=true|false # Enable auto-changeset (default: true)
|
|
118
|
+
AUTO_CHANGESET_AMEND=true|false # Auto-amend commits (default: true)
|
|
119
|
+
|
|
120
|
+
# Changelog generation
|
|
121
|
+
AUTO_CHANGESET_PROVIDER=auto|claude-cli|anthropic-api|simple # Provider (default: auto)
|
|
122
|
+
ANTHROPIC_API_KEY=sk-ant-... # For anthropic-api provider
|
|
123
|
+
|
|
124
|
+
# Paths
|
|
125
|
+
AUTO_CHANGESET_CONFIG_PATH=.changeset/config.json # Changeset config path
|
|
126
|
+
AUTO_CHANGESET_DIR=.changeset # Changeset directory
|
|
127
|
+
|
|
128
|
+
# Package discovery
|
|
129
|
+
AUTO_CHANGESET_PACKAGES=@pkg/a,@pkg/b # Override package discovery
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Config File
|
|
133
|
+
|
|
134
|
+
Create `.release-automation.json`:
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"changesetConfigPath": ".changeset/config.json",
|
|
139
|
+
"changelogProvider": "auto",
|
|
140
|
+
"autoAmend": true,
|
|
141
|
+
"changesetDir": ".changeset"
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Or add to `package.json`:
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"releaseAutomation": {
|
|
150
|
+
"changelogProvider": "auto",
|
|
151
|
+
"autoAmend": true
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Changelog Providers
|
|
157
|
+
|
|
158
|
+
The package tries providers in order until one succeeds:
|
|
159
|
+
|
|
160
|
+
### 1. Claude CLI (Fastest)
|
|
161
|
+
|
|
162
|
+
Requires `claude` in PATH.
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
# Check availability
|
|
166
|
+
which claude
|
|
167
|
+
|
|
168
|
+
# Install Claude CLI
|
|
169
|
+
# See: https://docs.anthropic.com/claude/docs/claude-cli
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### 2. Anthropic API
|
|
173
|
+
|
|
174
|
+
Requires `ANTHROPIC_API_KEY` environment variable.
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Free tier:** $5 credit = 5000+ changeset generations (at ~$0.001 each)
|
|
181
|
+
|
|
182
|
+
**Get API key:** https://console.anthropic.com
|
|
183
|
+
|
|
184
|
+
### 3. Simple Fallback
|
|
185
|
+
|
|
186
|
+
Always available. Formats commit messages into bullet points:
|
|
187
|
+
|
|
188
|
+
- Groups by type (feat, fix, others)
|
|
189
|
+
- Adds scope formatting
|
|
190
|
+
- Limits to 5 items
|
|
191
|
+
|
|
192
|
+
## Git Hook Integration
|
|
193
|
+
|
|
194
|
+
Add to `.husky/pre-push`:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
#!/bin/sh
|
|
198
|
+
|
|
199
|
+
# Check if enabled
|
|
200
|
+
if [ "${AUTO_CHANGESET_ENABLED:-true}" = "false" ]; then
|
|
201
|
+
echo "⏭️ Auto-changeset disabled"
|
|
202
|
+
exit 0
|
|
203
|
+
fi
|
|
204
|
+
|
|
205
|
+
# Generate changesets
|
|
206
|
+
pnpm release-automation generate
|
|
207
|
+
|
|
208
|
+
# Check exit code
|
|
209
|
+
EXIT_CODE=$?
|
|
210
|
+
if [ $EXIT_CODE -ne 0 ] && [ $EXIT_CODE -ne 11 ] && [ $EXIT_CODE -ne 12 ]; then
|
|
211
|
+
echo "❌ Failed to generate changeset"
|
|
212
|
+
exit $EXIT_CODE
|
|
213
|
+
fi
|
|
214
|
+
|
|
215
|
+
# Amend commit if configured
|
|
216
|
+
if [ "${AUTO_CHANGESET_AMEND:-true}" = "true" ]; then
|
|
217
|
+
if [ -n "$(git status --porcelain .changeset/*.md 2>/dev/null)" ]; then
|
|
218
|
+
git add .changeset/*.md
|
|
219
|
+
git commit --amend --no-edit --no-verify
|
|
220
|
+
echo "✅ Changesets added to commit!"
|
|
221
|
+
fi
|
|
222
|
+
fi
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## GitHub Actions Integration
|
|
226
|
+
|
|
227
|
+
```yaml
|
|
228
|
+
- name: Check for changesets
|
|
229
|
+
id: check_changesets
|
|
230
|
+
run: |
|
|
231
|
+
if pnpm release-automation check --require-changesets; then
|
|
232
|
+
echo "has_changesets=true" >> $GITHUB_OUTPUT
|
|
233
|
+
else
|
|
234
|
+
EXIT_CODE=$?
|
|
235
|
+
if [ $EXIT_CODE -eq 10 ]; then
|
|
236
|
+
echo "has_changesets=false" >> $GITHUB_OUTPUT
|
|
237
|
+
else
|
|
238
|
+
exit $EXIT_CODE
|
|
239
|
+
fi
|
|
240
|
+
fi
|
|
241
|
+
|
|
242
|
+
- name: Version packages
|
|
243
|
+
if: steps.check_changesets.outputs.has_changesets == 'true'
|
|
244
|
+
run: |
|
|
245
|
+
pnpm changeset version
|
|
246
|
+
git add .
|
|
247
|
+
git commit -m "chore: version packages"
|
|
248
|
+
git push
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Library API
|
|
252
|
+
|
|
253
|
+
### Git Operations
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
import {
|
|
257
|
+
getCommitsSinceLastChangeset,
|
|
258
|
+
getCommitsInRange,
|
|
259
|
+
getAllCommits,
|
|
260
|
+
getCommitsSinceLastTag,
|
|
261
|
+
getLastChangesetCommit,
|
|
262
|
+
getLastReleaseTag,
|
|
263
|
+
getCommitMessage,
|
|
264
|
+
isGitRepository,
|
|
265
|
+
} from '@auto-engineer/release-automation';
|
|
266
|
+
|
|
267
|
+
// Get commits since last changeset
|
|
268
|
+
const commits = getCommitsSinceLastChangeset('.changeset');
|
|
269
|
+
|
|
270
|
+
// Get commits in range
|
|
271
|
+
const commits = getCommitsInRange('v1.0.0', 'HEAD');
|
|
272
|
+
|
|
273
|
+
// Check if in git repo
|
|
274
|
+
if (isGitRepository()) {
|
|
275
|
+
// ...
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Conventional Commit Parsing
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
import {
|
|
283
|
+
parseConventionalCommit,
|
|
284
|
+
parseConventionalCommits,
|
|
285
|
+
isConventionalCommit,
|
|
286
|
+
extractBreakingChange,
|
|
287
|
+
} from '@auto-engineer/release-automation';
|
|
288
|
+
|
|
289
|
+
// Parse single commit
|
|
290
|
+
const commit = parseConventionalCommit('abc123');
|
|
291
|
+
|
|
292
|
+
// Parse multiple commits
|
|
293
|
+
const commits = parseConventionalCommits(['abc123', 'def456']);
|
|
294
|
+
|
|
295
|
+
// Validate format
|
|
296
|
+
if (isConventionalCommit('feat(cli): add feature')) {
|
|
297
|
+
// Valid
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Check for breaking changes
|
|
301
|
+
if (extractBreakingChange('feat!: breaking change')) {
|
|
302
|
+
// Has breaking change
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Semver Logic
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
import {
|
|
310
|
+
determineBumpType,
|
|
311
|
+
hasBreakingChanges,
|
|
312
|
+
hasFeatures,
|
|
313
|
+
} from '@auto-engineer/release-automation';
|
|
314
|
+
|
|
315
|
+
const commits = parseConventionalCommits(hashes);
|
|
316
|
+
|
|
317
|
+
// Determine bump type (major > minor > patch)
|
|
318
|
+
const bumpType = determineBumpType(commits);
|
|
319
|
+
|
|
320
|
+
// Check for breaking changes
|
|
321
|
+
if (hasBreakingChanges(commits)) {
|
|
322
|
+
// Major version bump
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Check for features
|
|
326
|
+
if (hasFeatures(commits)) {
|
|
327
|
+
// Minor version bump
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Changelog Generation
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
import { generateChangelog } from '@auto-engineer/release-automation';
|
|
335
|
+
|
|
336
|
+
const commits = parseConventionalCommits(hashes);
|
|
337
|
+
|
|
338
|
+
// Generate with auto provider selection
|
|
339
|
+
const changelog = await generateChangelog(commits);
|
|
340
|
+
|
|
341
|
+
// Force specific provider
|
|
342
|
+
const changelog = await generateChangelog(commits, {
|
|
343
|
+
changelogProvider: 'simple',
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
// Use Anthropic API
|
|
347
|
+
const changelog = await generateChangelog(commits, {
|
|
348
|
+
changelogProvider: 'anthropic-api',
|
|
349
|
+
anthropicApiKey: 'sk-ant-...',
|
|
350
|
+
});
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Package Discovery
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
import {
|
|
357
|
+
discoverPackages,
|
|
358
|
+
readChangesetConfig,
|
|
359
|
+
getFixedGroupPackages,
|
|
360
|
+
} from '@auto-engineer/release-automation';
|
|
361
|
+
|
|
362
|
+
// Discover from changeset config
|
|
363
|
+
const packages = await discoverPackages('.changeset/config.json');
|
|
364
|
+
|
|
365
|
+
// Read config
|
|
366
|
+
const config = await readChangesetConfig();
|
|
367
|
+
|
|
368
|
+
// Get fixed group packages
|
|
369
|
+
const packages = getFixedGroupPackages(config);
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Changeset Writer
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
import {
|
|
376
|
+
createChangesetFile,
|
|
377
|
+
generateChangesetFrontmatter,
|
|
378
|
+
generateChangesetFilename,
|
|
379
|
+
} from '@auto-engineer/release-automation';
|
|
380
|
+
|
|
381
|
+
// Create changeset file
|
|
382
|
+
const result = createChangesetFile(
|
|
383
|
+
{
|
|
384
|
+
bumpType: 'minor',
|
|
385
|
+
commits,
|
|
386
|
+
description: 'Changelog content',
|
|
387
|
+
},
|
|
388
|
+
['@pkg/a', '@pkg/b'],
|
|
389
|
+
'.changeset'
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
console.log(result.filename); // 'auto-a1b2c3d4.md'
|
|
393
|
+
console.log(result.path); // '/path/to/.changeset/auto-a1b2c3d4.md'
|
|
394
|
+
|
|
395
|
+
// Generate frontmatter
|
|
396
|
+
const frontmatter = generateChangesetFrontmatter(
|
|
397
|
+
['@pkg/a', '@pkg/b'],
|
|
398
|
+
'minor'
|
|
399
|
+
);
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### Configuration Loading
|
|
403
|
+
|
|
404
|
+
```typescript
|
|
405
|
+
import { loadConfig } from '@auto-engineer/release-automation';
|
|
406
|
+
|
|
407
|
+
// Load from all sources (env, file, defaults)
|
|
408
|
+
const config = await loadConfig();
|
|
409
|
+
|
|
410
|
+
// Override specific values
|
|
411
|
+
const config = await loadConfig({
|
|
412
|
+
changelogProvider: 'simple',
|
|
413
|
+
autoAmend: false,
|
|
414
|
+
});
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
## Conventional Commit Format
|
|
418
|
+
|
|
419
|
+
This package follows the [Conventional Commits](https://www.conventionalcommits.org/) specification:
|
|
420
|
+
|
|
421
|
+
```
|
|
422
|
+
<type>(<scope>): <subject>
|
|
423
|
+
|
|
424
|
+
[optional body]
|
|
425
|
+
|
|
426
|
+
[optional footer]
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
**Types:**
|
|
430
|
+
- `feat` - New feature (minor bump)
|
|
431
|
+
- `fix` - Bug fix (patch bump)
|
|
432
|
+
- `docs` - Documentation changes
|
|
433
|
+
- `style` - Code style changes (formatting, etc)
|
|
434
|
+
- `refactor` - Code refactoring
|
|
435
|
+
- `perf` - Performance improvements
|
|
436
|
+
- `test` - Test changes
|
|
437
|
+
- `build` - Build system changes
|
|
438
|
+
- `ci` - CI configuration changes
|
|
439
|
+
- `chore` - Other changes
|
|
440
|
+
- `revert` - Revert previous commit
|
|
441
|
+
|
|
442
|
+
**Breaking changes:**
|
|
443
|
+
- Add `!` after type: `feat!: breaking change`
|
|
444
|
+
- Add footer: `BREAKING CHANGE: description`
|
|
445
|
+
|
|
446
|
+
## Examples
|
|
447
|
+
|
|
448
|
+
### Example 1: Basic Usage
|
|
449
|
+
|
|
450
|
+
```bash
|
|
451
|
+
# Make some commits
|
|
452
|
+
git commit -m "feat(cli): add new command"
|
|
453
|
+
git commit -m "fix(server): resolve connection issue"
|
|
454
|
+
|
|
455
|
+
# Generate changeset
|
|
456
|
+
pnpm release-automation generate
|
|
457
|
+
|
|
458
|
+
# Output:
|
|
459
|
+
# ✅ Found 2 valid conventional commit(s)
|
|
460
|
+
# 📊 Determined version bump: minor
|
|
461
|
+
# ✨ Generating changelog...
|
|
462
|
+
# ✅ Created changeset: auto-a1b2c3d4.md
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### Example 2: Dry Run
|
|
466
|
+
|
|
467
|
+
```bash
|
|
468
|
+
pnpm release-automation generate --dry-run
|
|
469
|
+
|
|
470
|
+
# Output:
|
|
471
|
+
# 📋 Changeset Preview:
|
|
472
|
+
# ---
|
|
473
|
+
# Bump type: minor
|
|
474
|
+
# Packages: @auto-engineer/cli, @auto-engineer/server
|
|
475
|
+
#
|
|
476
|
+
# Changelog:
|
|
477
|
+
# - Added new command functionality
|
|
478
|
+
# - Fixed connection stability issues
|
|
479
|
+
# ---
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
### Example 3: CI/CD Check
|
|
483
|
+
|
|
484
|
+
```bash
|
|
485
|
+
# Check if changesets exist (for CI)
|
|
486
|
+
pnpm release-automation check --require-changesets
|
|
487
|
+
|
|
488
|
+
# Exit code 0 if changesets exist
|
|
489
|
+
# Exit code 10 if no changesets
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
## Troubleshooting
|
|
493
|
+
|
|
494
|
+
### "No conventional commits found"
|
|
495
|
+
|
|
496
|
+
Ensure commits follow the format:
|
|
497
|
+
|
|
498
|
+
```bash
|
|
499
|
+
# ✅ Good
|
|
500
|
+
git commit -m "feat(cli): add feature"
|
|
501
|
+
git commit -m "fix: bug fix"
|
|
502
|
+
|
|
503
|
+
# ❌ Bad
|
|
504
|
+
git commit -m "added feature"
|
|
505
|
+
git commit -m "WIP"
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### "Failed to discover packages"
|
|
509
|
+
|
|
510
|
+
Check that `.changeset/config.json` exists and has a `fixed` array:
|
|
511
|
+
|
|
512
|
+
```json
|
|
513
|
+
{
|
|
514
|
+
"fixed": [["@auto-engineer/*", "create-auto-app"]]
|
|
515
|
+
}
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
### "Claude CLI not found"
|
|
519
|
+
|
|
520
|
+
Install Claude CLI or set `ANTHROPIC_API_KEY`:
|
|
521
|
+
|
|
522
|
+
```bash
|
|
523
|
+
# Option 1: Install Claude CLI
|
|
524
|
+
# See: https://docs.anthropic.com/claude/docs/claude-cli
|
|
525
|
+
|
|
526
|
+
# Option 2: Use Anthropic API
|
|
527
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
528
|
+
|
|
529
|
+
# Option 3: Use simple mode
|
|
530
|
+
pnpm release-automation generate --provider simple
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
## Development
|
|
534
|
+
|
|
535
|
+
```bash
|
|
536
|
+
# Install dependencies
|
|
537
|
+
pnpm install
|
|
538
|
+
|
|
539
|
+
# Build
|
|
540
|
+
pnpm build
|
|
541
|
+
|
|
542
|
+
# Run tests (when implemented)
|
|
543
|
+
pnpm test
|
|
544
|
+
|
|
545
|
+
# Type check
|
|
546
|
+
pnpm type-check
|
|
547
|
+
|
|
548
|
+
# Watch mode
|
|
549
|
+
pnpm test:watch
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
## License
|
|
553
|
+
|
|
554
|
+
MIT
|
|
555
|
+
|
|
556
|
+
## Related
|
|
557
|
+
|
|
558
|
+
- [Changesets](https://github.com/changesets/changesets)
|
|
559
|
+
- [Conventional Commits](https://www.conventionalcommits.org/)
|
|
560
|
+
- [Anthropic API](https://docs.anthropic.com/)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-automation.d.ts","sourceRoot":"","sources":["../../bin/release-automation.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-automation.js","sourceRoot":"","sources":["../../bin/release-automation.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACnC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/check.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,YAAY,SA4DrB,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { getCommitsSinceLastChangeset, isGitRepository, loadConfig, parseConventionalCommits, } from '../../lib/index.js';
|
|
5
|
+
import { EXIT_CODE, logError, logInfo, logSuccess } from '../utils/index.js';
|
|
6
|
+
export const checkCommand = new Command('check')
|
|
7
|
+
.description('Check for pending changesets or commits that need changesets')
|
|
8
|
+
.option('--since <ref>', 'Check commits since this reference')
|
|
9
|
+
.option('-v, --verbose', 'Show detailed information')
|
|
10
|
+
.option('--require-changesets', 'Exit with error if no changesets exist')
|
|
11
|
+
.action(async (options) => {
|
|
12
|
+
try {
|
|
13
|
+
// Check if we're in a git repository
|
|
14
|
+
if (!isGitRepository()) {
|
|
15
|
+
logError('Not a git repository');
|
|
16
|
+
process.exit(EXIT_CODE.GIT_ERROR);
|
|
17
|
+
}
|
|
18
|
+
// Load configuration
|
|
19
|
+
const config = await loadConfig();
|
|
20
|
+
// Check for existing changesets
|
|
21
|
+
const changesetPath = join(process.cwd(), config.changesetDir);
|
|
22
|
+
const hasChangesets = checkForChangesets(changesetPath);
|
|
23
|
+
if (options.verbose) {
|
|
24
|
+
if (hasChangesets) {
|
|
25
|
+
logSuccess('Changesets exist');
|
|
26
|
+
listChangesets(changesetPath);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
logInfo('No changesets found');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Check for commits that need changesets
|
|
33
|
+
const commitHashes = getCommitsSinceLastChangeset(config.changesetDir);
|
|
34
|
+
const commits = parseConventionalCommits(commitHashes);
|
|
35
|
+
if (options.verbose) {
|
|
36
|
+
if (commits.length > 0) {
|
|
37
|
+
logInfo(`Found ${commits.length} commit(s) that may need changesets`);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
logInfo('No commits need changesets');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Exit based on options
|
|
44
|
+
if (options.requireChangesets) {
|
|
45
|
+
if (!hasChangesets) {
|
|
46
|
+
logError('No changesets found (use --require-changesets)');
|
|
47
|
+
process.exit(EXIT_CODE.NO_CHANGESETS);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (hasChangesets) {
|
|
51
|
+
logSuccess('Changesets detected');
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
logInfo('No changesets to process');
|
|
55
|
+
}
|
|
56
|
+
process.exit(EXIT_CODE.SUCCESS);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
logError(`Failed to check changesets: ${error.message}`);
|
|
60
|
+
process.exit(EXIT_CODE.ERROR);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
function checkForChangesets(changesetPath) {
|
|
64
|
+
if (!existsSync(changesetPath)) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
const files = readdirSync(changesetPath).filter((f) => f.endsWith('.md') && f !== 'README.md');
|
|
68
|
+
return files.length > 0;
|
|
69
|
+
}
|
|
70
|
+
function listChangesets(changesetPath) {
|
|
71
|
+
const files = readdirSync(changesetPath).filter((f) => f.endsWith('.md') && f !== 'README.md');
|
|
72
|
+
console.log(`\nChangesets (${files.length}):`);
|
|
73
|
+
for (const file of files) {
|
|
74
|
+
console.log(` - ${file}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=check.js.map
|