httpcat-cli 0.2.8-rc.1 → 0.2.9-rc.1
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/.github/workflows/release.yml +152 -85
- package/.github/workflows/sync-version.yml +71 -16
- package/package.json +1 -1
|
@@ -96,6 +96,18 @@ jobs:
|
|
|
96
96
|
if (context.eventName === 'push' && context.payload.before) {
|
|
97
97
|
console.log(`Analyzing commits in this push (${context.payload.before}..${context.sha})...`);
|
|
98
98
|
try {
|
|
99
|
+
// First, verify both commits exist
|
|
100
|
+
try {
|
|
101
|
+
await github.rest.repos.getCommit({
|
|
102
|
+
owner: context.repo.owner,
|
|
103
|
+
repo: context.repo.repo,
|
|
104
|
+
ref: context.payload.before
|
|
105
|
+
});
|
|
106
|
+
} catch (e) {
|
|
107
|
+
console.log(`⚠️ Base commit ${context.payload.before} not found (may have been squashed/rebased), falling back to last release`);
|
|
108
|
+
throw new Error(`Base commit not found: ${e.message}`);
|
|
109
|
+
}
|
|
110
|
+
|
|
99
111
|
const response = await github.rest.repos.compareCommits({
|
|
100
112
|
owner: context.repo.owner,
|
|
101
113
|
repo: context.repo.repo,
|
|
@@ -117,36 +129,29 @@ jobs:
|
|
|
117
129
|
}
|
|
118
130
|
}
|
|
119
131
|
} catch (e) {
|
|
120
|
-
console.log(`⚠️ Could not compare commits in push, falling back to last release
|
|
132
|
+
console.log(`⚠️ Could not compare commits in push (${e.message}), falling back to last release`);
|
|
121
133
|
// Fallback to comparing with last release tag
|
|
122
134
|
if (lastTag) {
|
|
123
|
-
let baseSha;
|
|
124
135
|
try {
|
|
125
|
-
|
|
136
|
+
// Use tag name directly - GitHub API resolves it to commit SHA
|
|
137
|
+
const response = await github.rest.repos.compareCommits({
|
|
126
138
|
owner: context.repo.owner,
|
|
127
139
|
repo: context.repo.repo,
|
|
128
|
-
|
|
140
|
+
base: lastTag,
|
|
141
|
+
head: context.sha
|
|
129
142
|
});
|
|
130
|
-
|
|
143
|
+
compareData = response.data;
|
|
131
144
|
} catch (e2) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
}
|
|
145
|
+
console.log(`⚠️ Tag comparison failed: ${e2.message}, using main branch`);
|
|
146
|
+
// Final fallback to main branch
|
|
147
|
+
const response = await github.rest.repos.compareCommits({
|
|
148
|
+
owner: context.repo.owner,
|
|
149
|
+
repo: context.repo.repo,
|
|
150
|
+
base: 'main',
|
|
151
|
+
head: context.sha
|
|
152
|
+
});
|
|
153
|
+
compareData = response.data;
|
|
142
154
|
}
|
|
143
|
-
const response = await github.rest.repos.compareCommits({
|
|
144
|
-
owner: context.repo.owner,
|
|
145
|
-
repo: context.repo.repo,
|
|
146
|
-
base: baseSha || 'main',
|
|
147
|
-
head: context.sha
|
|
148
|
-
});
|
|
149
|
-
compareData = response.data;
|
|
150
155
|
} else {
|
|
151
156
|
// No last tag and push comparison failed - default to patch
|
|
152
157
|
// We can't reliably determine which commits to analyze without a baseline
|
|
@@ -159,33 +164,25 @@ jobs:
|
|
|
159
164
|
} else if (lastTag) {
|
|
160
165
|
// For other events (like workflow_dispatch), compare with last release
|
|
161
166
|
console.log(`Last release tag: ${lastTag}`);
|
|
162
|
-
let baseSha;
|
|
163
167
|
try {
|
|
164
|
-
|
|
168
|
+
// Use tag name directly - GitHub API resolves it to commit SHA
|
|
169
|
+
const response = await github.rest.repos.compareCommits({
|
|
165
170
|
owner: context.repo.owner,
|
|
166
171
|
repo: context.repo.repo,
|
|
167
|
-
|
|
172
|
+
base: lastTag,
|
|
173
|
+
head: context.sha
|
|
168
174
|
});
|
|
169
|
-
|
|
175
|
+
compareData = response.data;
|
|
170
176
|
} catch (e) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
baseSha = null;
|
|
180
|
-
}
|
|
177
|
+
console.log(`⚠️ Tag comparison failed: ${e.message}, using main branch`);
|
|
178
|
+
const response = await github.rest.repos.compareCommits({
|
|
179
|
+
owner: context.repo.owner,
|
|
180
|
+
repo: context.repo.repo,
|
|
181
|
+
base: 'main',
|
|
182
|
+
head: context.sha
|
|
183
|
+
});
|
|
184
|
+
compareData = response.data;
|
|
181
185
|
}
|
|
182
|
-
const response = await github.rest.repos.compareCommits({
|
|
183
|
-
owner: context.repo.owner,
|
|
184
|
-
repo: context.repo.repo,
|
|
185
|
-
base: baseSha || 'main',
|
|
186
|
-
head: context.sha
|
|
187
|
-
});
|
|
188
|
-
compareData = response.data;
|
|
189
186
|
} else {
|
|
190
187
|
// No last tag and not a push event - default to patch
|
|
191
188
|
// For workflow_dispatch or other events without a tag, we can't reliably
|
|
@@ -325,40 +322,103 @@ jobs:
|
|
|
325
322
|
const currentTag = 'v${{ steps.version.outputs.version }}';
|
|
326
323
|
|
|
327
324
|
// Get commits since last release
|
|
325
|
+
let commits;
|
|
328
326
|
let baseSha;
|
|
329
|
-
|
|
327
|
+
|
|
328
|
+
// For push events, prefer using context.payload.before if available
|
|
329
|
+
// This ensures we only get commits from the current push/merge
|
|
330
|
+
if (context.eventName === 'push' && context.payload.before) {
|
|
331
|
+
console.log(`Using push event comparison (${context.payload.before}..${context.sha})`);
|
|
330
332
|
try {
|
|
331
|
-
const
|
|
333
|
+
const response = await github.rest.repos.compareCommits({
|
|
332
334
|
owner: context.repo.owner,
|
|
333
335
|
repo: context.repo.repo,
|
|
334
|
-
|
|
336
|
+
base: context.payload.before,
|
|
337
|
+
head: context.sha
|
|
335
338
|
});
|
|
336
|
-
|
|
339
|
+
commits = response.data;
|
|
340
|
+
baseSha = context.payload.before;
|
|
341
|
+
console.log(`Found ${commits.commits.length} commits in this push`);
|
|
337
342
|
} catch (e) {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
343
|
+
console.log(`⚠️ Push comparison failed: ${e.message}, falling back to tag comparison`);
|
|
344
|
+
// Fall through to tag-based comparison
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// If push comparison didn't work or wasn't available, try tag-based comparison
|
|
349
|
+
if (!commits) {
|
|
350
|
+
if (lastTag) {
|
|
351
|
+
console.log(`Comparing with last tag ${lastTag}`);
|
|
352
|
+
|
|
353
|
+
try {
|
|
354
|
+
// Use the tag name directly - GitHub API will resolve it to the commit SHA
|
|
355
|
+
// This handles both lightweight and annotated tags correctly
|
|
356
|
+
const response = await github.rest.repos.compareCommits({
|
|
357
|
+
owner: context.repo.owner,
|
|
358
|
+
repo: context.repo.repo,
|
|
359
|
+
base: lastTag, // Use tag name directly, API resolves to commit
|
|
360
|
+
head: context.sha
|
|
361
|
+
});
|
|
362
|
+
commits = response.data;
|
|
363
|
+
baseSha = lastTag; // Store tag name for changelog link
|
|
364
|
+
console.log(`Found ${commits.commits.length} commits since ${lastTag}`);
|
|
365
|
+
} catch (e) {
|
|
366
|
+
console.log(`⚠️ Tag comparison failed: ${e.message}`);
|
|
367
|
+
console.log(`Error details: ${e.response?.data?.message || e.message}`);
|
|
368
|
+
|
|
369
|
+
// Try to get the actual commit SHA from the tag as fallback
|
|
370
|
+
try {
|
|
371
|
+
const { data: commitData } = await github.rest.repos.getCommit({
|
|
372
|
+
owner: context.repo.owner,
|
|
373
|
+
repo: context.repo.repo,
|
|
374
|
+
ref: lastTag
|
|
375
|
+
});
|
|
376
|
+
const tagCommitSha = commitData.sha;
|
|
377
|
+
console.log(`Resolved tag ${lastTag} to commit ${tagCommitSha}, retrying comparison...`);
|
|
378
|
+
|
|
379
|
+
const response = await github.rest.repos.compareCommits({
|
|
380
|
+
owner: context.repo.owner,
|
|
381
|
+
repo: context.repo.repo,
|
|
382
|
+
base: tagCommitSha,
|
|
383
|
+
head: context.sha
|
|
384
|
+
});
|
|
385
|
+
commits = response.data;
|
|
386
|
+
baseSha = tagCommitSha;
|
|
387
|
+
console.log(`Found ${commits.commits.length} commits since ${lastTag}`);
|
|
388
|
+
} catch (e2) {
|
|
389
|
+
console.log(`⚠️ Commit SHA comparison also failed: ${e2.message}`);
|
|
390
|
+
// Fall through to main branch comparison
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// If tag comparison failed or no tag exists, compare with main branch
|
|
396
|
+
if (!commits) {
|
|
397
|
+
try {
|
|
398
|
+
const { data: branchData } = await github.rest.repos.getBranch({
|
|
399
|
+
owner: context.repo.owner,
|
|
400
|
+
repo: context.repo.repo,
|
|
401
|
+
branch: 'main'
|
|
402
|
+
});
|
|
403
|
+
baseSha = branchData.commit.sha;
|
|
404
|
+
console.log(`Comparing with main branch (${baseSha})`);
|
|
405
|
+
|
|
406
|
+
const response = await github.rest.repos.compareCommits({
|
|
407
|
+
owner: context.repo.owner,
|
|
408
|
+
repo: context.repo.repo,
|
|
409
|
+
base: baseSha,
|
|
410
|
+
head: context.sha
|
|
411
|
+
});
|
|
412
|
+
commits = response.data;
|
|
413
|
+
console.log(`Found ${commits.commits.length} commits since main branch HEAD`);
|
|
414
|
+
} catch (e) {
|
|
415
|
+
console.log(`⚠️ Main branch comparison also failed: ${e.message}`);
|
|
416
|
+
console.log(`Using empty commit list - release notes will be minimal`);
|
|
417
|
+
commits = { commits: [] };
|
|
418
|
+
baseSha = null;
|
|
419
|
+
}
|
|
345
420
|
}
|
|
346
|
-
} else {
|
|
347
|
-
// Get the first commit or main branch
|
|
348
|
-
const { data: branchData } = await github.rest.repos.getBranch({
|
|
349
|
-
owner: context.repo.owner,
|
|
350
|
-
repo: context.repo.repo,
|
|
351
|
-
branch: 'main'
|
|
352
|
-
});
|
|
353
|
-
baseSha = branchData.commit.sha;
|
|
354
421
|
}
|
|
355
|
-
|
|
356
|
-
const { data: commits } = await github.rest.repos.compareCommits({
|
|
357
|
-
owner: context.repo.owner,
|
|
358
|
-
repo: context.repo.repo,
|
|
359
|
-
base: baseSha,
|
|
360
|
-
head: context.sha
|
|
361
|
-
});
|
|
362
422
|
|
|
363
423
|
// Categorize commits
|
|
364
424
|
const features = [];
|
|
@@ -367,21 +427,25 @@ jobs:
|
|
|
367
427
|
const chore = [];
|
|
368
428
|
const breaking = [];
|
|
369
429
|
|
|
370
|
-
|
|
371
|
-
const
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
430
|
+
if (commits && commits.commits && commits.commits.length > 0) {
|
|
431
|
+
for (const commit of commits.commits) {
|
|
432
|
+
const message = commit.commit.message;
|
|
433
|
+
const firstLine = message.split('\n')[0];
|
|
434
|
+
|
|
435
|
+
if (firstLine.match(/^BREAKING/)) {
|
|
436
|
+
breaking.push(`- ${firstLine.replace(/^BREAKING[:\s]+/i, '')}`);
|
|
437
|
+
} else if (firstLine.match(/^feat(ure)?[(:]/i)) {
|
|
438
|
+
features.push(`- ${firstLine.replace(/^feat(ure)?[(:]\s*/i, '')}`);
|
|
439
|
+
} else if (firstLine.match(/^fix[(]/i)) {
|
|
440
|
+
fixes.push(`- ${firstLine.replace(/^fix[(]\s*/i, '')}`);
|
|
441
|
+
} else if (firstLine.match(/^doc(s)?[(]/i)) {
|
|
442
|
+
docs.push(`- ${firstLine.replace(/^doc(s)?[(]\s*/i, '')}`);
|
|
443
|
+
} else if (!firstLine.match(/^(chore|ci|test|build)[(:]/i)) {
|
|
444
|
+
chore.push(`- ${firstLine}`);
|
|
445
|
+
}
|
|
384
446
|
}
|
|
447
|
+
} else {
|
|
448
|
+
console.log('⚠️ No commits found for release notes - using minimal release notes');
|
|
385
449
|
}
|
|
386
450
|
|
|
387
451
|
let notes = `## 🎉 Release ${{ steps.version.outputs.version }}\n\n`;
|
|
@@ -414,10 +478,13 @@ jobs:
|
|
|
414
478
|
notes += `brew upgrade httpcat\n`;
|
|
415
479
|
notes += `\`\`\`\n\n`;
|
|
416
480
|
notes += `---\n\n`;
|
|
417
|
-
|
|
481
|
+
|
|
482
|
+
// Generate changelog link - use lastTag if available, otherwise use main
|
|
483
|
+
const changelogBase = lastTag || 'main';
|
|
484
|
+
notes += `**Full Changelog**: https://github.com/${{ github.repository }}/compare/${changelogBase}...${currentTag}`;
|
|
418
485
|
|
|
419
486
|
core.setOutput('notes', notes);
|
|
420
|
-
console.log('Generated release notes');
|
|
487
|
+
console.log('✅ Generated release notes');
|
|
421
488
|
|
|
422
489
|
# Job 2: Build and test
|
|
423
490
|
test:
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
name: Sync Version to Develop
|
|
2
2
|
|
|
3
|
-
# This workflow runs after a release to
|
|
3
|
+
# This workflow runs after a release to reset develop to match main and sync the version
|
|
4
4
|
on:
|
|
5
5
|
release:
|
|
6
6
|
types: [published]
|
|
7
7
|
|
|
8
8
|
jobs:
|
|
9
9
|
sync-version:
|
|
10
|
-
name:
|
|
10
|
+
name: Reset develop to match main
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
permissions:
|
|
13
13
|
contents: write
|
|
@@ -25,32 +25,87 @@ jobs:
|
|
|
25
25
|
# Remove 'v' prefix if present
|
|
26
26
|
VERSION="${VERSION#v}"
|
|
27
27
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
28
|
-
echo "✅ Version
|
|
28
|
+
echo "✅ Version from release: $VERSION"
|
|
29
29
|
|
|
30
30
|
- name: Checkout develop branch
|
|
31
31
|
run: |
|
|
32
32
|
git checkout develop
|
|
33
33
|
git pull origin develop
|
|
34
34
|
|
|
35
|
-
- name:
|
|
35
|
+
- name: Check for new commits in develop
|
|
36
|
+
id: check-commits
|
|
36
37
|
run: |
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
echo "
|
|
38
|
+
# Check if develop has commits that aren't in main
|
|
39
|
+
COMMITS_AHEAD=$(git rev-list --count origin/main..HEAD 2>/dev/null || echo "0")
|
|
40
|
+
echo "commits_ahead=$COMMITS_AHEAD" >> $GITHUB_OUTPUT
|
|
41
|
+
|
|
42
|
+
if [ "$COMMITS_AHEAD" -gt 0 ]; then
|
|
43
|
+
echo "ℹ️ Develop has $COMMITS_AHEAD commit(s) not in main"
|
|
44
|
+
echo "These will be preserved by rebasing onto main"
|
|
45
|
+
else
|
|
46
|
+
echo "✅ Develop has no new commits - can fast-forward to main"
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
- name: Rebase develop onto main
|
|
50
|
+
run: |
|
|
51
|
+
echo "Updating develop to include latest from main..."
|
|
52
|
+
git fetch origin main
|
|
53
|
+
|
|
54
|
+
# Check if we can fast-forward (no new commits in develop)
|
|
55
|
+
COMMITS_AHEAD="${{ steps.check-commits.outputs.commits_ahead }}"
|
|
56
|
+
|
|
57
|
+
if [ "$COMMITS_AHEAD" -eq 0 ]; then
|
|
58
|
+
# Fast-forward: just move develop to main
|
|
59
|
+
echo "Fast-forwarding develop to main..."
|
|
60
|
+
git reset --hard origin/main
|
|
61
|
+
else
|
|
62
|
+
# Rebase: replay develop's commits on top of main
|
|
63
|
+
echo "Rebasing develop onto main..."
|
|
64
|
+
git rebase origin/main || {
|
|
65
|
+
echo "⚠️ Rebase conflict detected - this shouldn't happen if develop was properly merged"
|
|
66
|
+
echo "Falling back to reset (this will discard develop-only commits)"
|
|
67
|
+
git rebase --abort 2>/dev/null || true
|
|
68
|
+
git reset --hard origin/main
|
|
69
|
+
}
|
|
70
|
+
fi
|
|
71
|
+
echo "✅ Develop updated to include latest from main"
|
|
72
|
+
|
|
73
|
+
- name: Verify package.json version
|
|
74
|
+
run: |
|
|
75
|
+
CURRENT_VERSION=$(node -p "require('./package.json').version")
|
|
76
|
+
RELEASE_VERSION="${{ steps.version.outputs.version }}"
|
|
77
|
+
|
|
78
|
+
echo "Current version in package.json: $CURRENT_VERSION"
|
|
79
|
+
echo "Release version: $RELEASE_VERSION"
|
|
80
|
+
|
|
81
|
+
if [ "$CURRENT_VERSION" != "$RELEASE_VERSION" ]; then
|
|
82
|
+
echo "Updating package.json version..."
|
|
83
|
+
npm version "$RELEASE_VERSION" --no-git-tag-version --allow-same-version
|
|
84
|
+
git add package.json
|
|
85
|
+
git commit -m "chore: sync version to $RELEASE_VERSION" || echo "No changes to commit"
|
|
86
|
+
else
|
|
87
|
+
echo "✅ Version already matches"
|
|
88
|
+
fi
|
|
40
89
|
|
|
41
|
-
- name:
|
|
90
|
+
- name: Push to develop
|
|
42
91
|
run: |
|
|
43
|
-
VERSION="${{ steps.version.outputs.version }}"
|
|
44
92
|
git config user.name "github-actions[bot]"
|
|
45
93
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
46
|
-
git add package.json
|
|
47
94
|
|
|
48
|
-
# Check if there are changes to
|
|
49
|
-
if git diff --
|
|
50
|
-
echo "✅
|
|
95
|
+
# Check if there are any changes to push
|
|
96
|
+
if git diff --quiet origin/develop HEAD; then
|
|
97
|
+
echo "✅ No changes to push (develop already up to date)"
|
|
51
98
|
else
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
99
|
+
COMMITS_AHEAD="${{ steps.check-commits.outputs.commits_ahead }}"
|
|
100
|
+
if [ "$COMMITS_AHEAD" -eq 0 ]; then
|
|
101
|
+
# Fast-forward push (no force needed)
|
|
102
|
+
echo "Pushing fast-forward update..."
|
|
103
|
+
git push origin develop
|
|
104
|
+
else
|
|
105
|
+
# Rebase requires force push (but this is safe after rebase)
|
|
106
|
+
echo "Pushing rebased develop branch..."
|
|
107
|
+
git push origin develop --force-with-lease
|
|
108
|
+
fi
|
|
109
|
+
echo "✅ Develop updated and pushed"
|
|
55
110
|
fi
|
|
56
111
|
|