Skip to content

Commit 651fb5a

Browse files
test(ci): add comprehensive release notes testing workflow
- Create test scenarios for basic, breaking changes, and comprehensive commits - Implement commit categorization validation logic - Add template generation and content validation tests - Include automatic cleanup of test artifacts - Support multiple test scenarios with configurable parameters - Generate test artifacts for debugging and verification
1 parent 85395f7 commit 651fb5a

File tree

1 file changed

+374
-0
lines changed

1 file changed

+374
-0
lines changed
Lines changed: 374 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,374 @@
1+
name: Test Release Notes Generation
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
test_scenario:
7+
description: 'Test scenario to run'
8+
required: true
9+
default: 'basic'
10+
type: choice
11+
options:
12+
- basic
13+
- with_breaking_changes
14+
- comprehensive
15+
target_branch:
16+
description: 'Target branch for testing (default: current branch)'
17+
required: false
18+
type: string
19+
20+
jobs:
21+
test-release-notes:
22+
runs-on: ubuntu-latest
23+
permissions:
24+
contents: write
25+
pull-requests: read
26+
27+
steps:
28+
- name: Checkout code
29+
uses: actions/checkout@v4
30+
with:
31+
fetch-depth: 0
32+
ref: ${{ github.event.inputs.target_branch || github.ref }}
33+
34+
- name: Setup Node.js
35+
uses: actions/setup-node@v4
36+
with:
37+
node-version: '20'
38+
39+
- name: Create test commits for scenario
40+
run: |
41+
# Configure git for test commits
42+
git config user.name "Test Release Notes"
43+
git config user.email "test@create-polyglot.dev"
44+
45+
# Create a test branch
46+
TEST_BRANCH="test-release-notes-$(date +%s)"
47+
git checkout -b "$TEST_BRANCH"
48+
49+
# Create test commits based on scenario
50+
case "${{ github.event.inputs.test_scenario }}" in
51+
"basic")
52+
echo "# Test feature" > test-feature.md
53+
git add test-feature.md
54+
git commit -m "feat: add new test feature for users"
55+
56+
echo "# Test fix" > test-fix.md
57+
git add test-fix.md
58+
git commit -m "fix: resolve issue with test functionality"
59+
60+
echo "# Test docs" > test-docs.md
61+
git add test-docs.md
62+
git commit -m "docs: update README with test information"
63+
;;
64+
65+
"with_breaking_changes")
66+
echo "# Breaking feature" > breaking-feature.md
67+
git add breaking-feature.md
68+
git commit -m "feat!: change API structure (breaking change)"
69+
70+
echo "# Regular fix" > regular-fix.md
71+
git add regular-fix.md
72+
git commit -m "fix: patch minor bug in CLI"
73+
74+
echo "# Chore" > chore-update.md
75+
git add chore-update.md
76+
git commit -m "chore: update build dependencies"
77+
;;
78+
79+
"comprehensive")
80+
# Features
81+
echo "# New feature 1" > feature1.md
82+
git add feature1.md
83+
git commit -m "feat(cli): add Kong API gateway support"
84+
85+
echo "# New feature 2" > feature2.md
86+
git add feature2.md
87+
git commit -m "feat(templates): implement Go service template"
88+
89+
# Bug fixes
90+
echo "# Bug fix 1" > bugfix1.md
91+
git add bugfix1.md
92+
git commit -m "fix(docker): resolve port binding issues"
93+
94+
echo "# Bug fix 2" > bugfix2.md
95+
git add bugfix2.md
96+
git commit -m "fix: patch service discovery problems"
97+
98+
# Breaking change
99+
echo "# Breaking change" > breaking.md
100+
git add breaking.md
101+
git commit -m "feat!: restructure service configuration format"
102+
103+
# Documentation
104+
echo "# Docs update" > docs.md
105+
git add docs.md
106+
git commit -m "docs: add comprehensive API documentation"
107+
108+
# Dependencies
109+
echo "# Deps update" > deps.md
110+
git add deps.md
111+
git commit -m "deps: bump chalk to v5.6.2 for security fix"
112+
113+
# Internal changes
114+
echo "# Test update" > test.md
115+
git add test.md
116+
git commit -m "test: add integration tests for CLI commands"
117+
118+
echo "# CI update" > ci.md
119+
git add ci.md
120+
git commit -m "ci: improve GitHub Actions workflow performance"
121+
122+
# Other
123+
echo "# Other change" > other.md
124+
git add other.md
125+
git commit -m "update project configuration for better DX"
126+
;;
127+
esac
128+
129+
# Create a test tag
130+
TEST_TAG="v0.0.0-test-$(date +%s)"
131+
git tag "$TEST_TAG"
132+
133+
# Export variables for next steps
134+
echo "TEST_BRANCH=$TEST_BRANCH" >> $GITHUB_ENV
135+
echo "TEST_TAG=$TEST_TAG" >> $GITHUB_ENV
136+
137+
# Get the previous tag for comparison
138+
PREVIOUS_TAG=$(git tag --sort=-version:refname | grep -v "$TEST_TAG" | head -n 1)
139+
if [ -z "$PREVIOUS_TAG" ]; then
140+
PREVIOUS_TAG=$(git rev-list --max-parents=0 HEAD)
141+
fi
142+
echo "PREVIOUS_TAG=$PREVIOUS_TAG" >> $GITHUB_ENV
143+
144+
- name: Test categorization logic
145+
run: |
146+
# Simulate the categorization logic from the main workflow
147+
declare -a features=()
148+
declare -a bugfixes=()
149+
declare -a breaking=()
150+
declare -a documentation=()
151+
declare -a internal=()
152+
declare -a dependencies=()
153+
declare -a other=()
154+
155+
# Get commits for testing
156+
COMMITS=$(git log $PREVIOUS_TAG..$TEST_TAG --pretty=format:"%h|%s|%an" --no-merges)
157+
158+
echo "=== Testing Commit Categorization ==="
159+
echo "Commits to categorize:"
160+
echo "$COMMITS"
161+
echo ""
162+
163+
# Categorize commits (same logic as main workflow)
164+
while IFS='|' read -r hash subject author; do
165+
if [[ -z "$hash" ]]; then continue; fi
166+
167+
lower_subject=$(echo "$subject" | tr '[:upper:]' '[:lower:]')
168+
169+
echo "Processing: $subject"
170+
171+
if [[ $lower_subject =~ ^feat(\(.*\))?!: ]] || [[ $lower_subject =~ breaking ]]; then
172+
breaking+=("- $subject ([${hash}](https://github.com/${{ github.repository }}/commit/${hash})) by @${author}")
173+
echo " → Categorized as: BREAKING CHANGE"
174+
elif [[ $lower_subject =~ ^feat(\(.*\))?: ]] || [[ $lower_subject =~ ^add ]] || [[ $lower_subject =~ ^implement ]]; then
175+
features+=("- $subject ([${hash}](https://github.com/${{ github.repository }}/commit/${hash})) by @${author}")
176+
echo " → Categorized as: FEATURE"
177+
elif [[ $lower_subject =~ ^fix(\(.*\))?: ]] || [[ $lower_subject =~ ^bug ]] || [[ $lower_subject =~ ^patch ]]; then
178+
bugfixes+=("- $subject ([${hash}](https://github.com/${{ github.repository }}/commit/${hash})) by @${author}")
179+
echo " → Categorized as: BUG FIX"
180+
elif [[ $lower_subject =~ ^docs(\(.*\))?: ]] || [[ $lower_subject =~ documentation ]] || [[ $lower_subject =~ readme ]]; then
181+
documentation+=("- $subject ([${hash}](https://github.com/${{ github.repository }}/commit/${hash})) by @${author}")
182+
echo " → Categorized as: DOCUMENTATION"
183+
elif [[ $lower_subject =~ ^chore(\(.*\))?: ]] || [[ $lower_subject =~ ^ci(\(.*\))?: ]] || [[ $lower_subject =~ ^test(\(.*\))?: ]] || [[ $lower_subject =~ ^refactor(\(.*\))?: ]]; then
184+
internal+=("- $subject ([${hash}](https://github.com/${{ github.repository }}/commit/${hash})) by @${author}")
185+
echo " → Categorized as: INTERNAL"
186+
elif [[ $lower_subject =~ ^deps(\(.*\))?: ]] || [[ $lower_subject =~ dependencies ]] || [[ $lower_subject =~ package ]] || [[ $lower_subject =~ bump ]]; then
187+
dependencies+=("- $subject ([${hash}](https://github.com/${{ github.repository }}/commit/${hash})) by @${author}")
188+
echo " → Categorized as: DEPENDENCIES"
189+
else
190+
other+=("- $subject ([${hash}](https://github.com/${{ github.repository }}/commit/${hash})) by @${author}")
191+
echo " → Categorized as: OTHER"
192+
fi
193+
echo ""
194+
done <<< "$COMMITS"
195+
196+
# Save results
197+
printf '%s\n' "${features[@]}" > features.txt
198+
printf '%s\n' "${bugfixes[@]}" > bugfixes.txt
199+
printf '%s\n' "${breaking[@]}" > breaking.txt
200+
printf '%s\n' "${documentation[@]}" > documentation.txt
201+
printf '%s\n' "${internal[@]}" > internal.txt
202+
printf '%s\n' "${dependencies[@]}" > dependencies.txt
203+
printf '%s\n' "${other[@]}" > other.txt
204+
205+
# Display categorization results
206+
echo "=== Categorization Results ==="
207+
echo "Features ($(wc -l < features.txt)):"
208+
cat features.txt | head -5
209+
echo ""
210+
echo "Bug Fixes ($(wc -l < bugfixes.txt)):"
211+
cat bugfixes.txt | head -5
212+
echo ""
213+
echo "Breaking Changes ($(wc -l < breaking.txt)):"
214+
cat breaking.txt | head -5
215+
echo ""
216+
echo "Documentation ($(wc -l < documentation.txt)):"
217+
cat documentation.txt | head -5
218+
echo ""
219+
echo "Internal ($(wc -l < internal.txt)):"
220+
cat internal.txt | head -5
221+
echo ""
222+
echo "Dependencies ($(wc -l < dependencies.txt)):"
223+
cat dependencies.txt | head -5
224+
echo ""
225+
echo "Other ($(wc -l < other.txt)):"
226+
cat other.txt | head -5
227+
228+
- name: Test template generation
229+
run: |
230+
# Test the template substitution logic
231+
echo "=== Testing Template Generation ==="
232+
233+
# Read template
234+
TEMPLATE=$(cat .github/release-notes-template.md)
235+
236+
# Read categorized sections
237+
FEATURES=$(cat features.txt || echo "No new features in this release.")
238+
BUGFIXES=$(cat bugfixes.txt || echo "No bug fixes in this release.")
239+
BREAKING=$(cat breaking.txt || echo "No breaking changes in this release.")
240+
DOCUMENTATION=$(cat documentation.txt || echo "No documentation changes in this release.")
241+
INTERNAL=$(cat internal.txt || echo "No internal changes in this release.")
242+
DEPENDENCIES=$(cat dependencies.txt || echo "No dependency updates in this release.")
243+
OTHER=$(cat other.txt || echo "No other changes in this release.")
244+
245+
# Get contributors
246+
CONTRIBUTORS=$(git log $PREVIOUS_TAG..$TEST_TAG --pretty=format:"%an" --no-merges | sort -u | sed 's/^/- @/' | tr '\n' '\n')
247+
248+
# Replace placeholders
249+
NOTES="$TEMPLATE"
250+
NOTES="${NOTES//\{version\}/0.0.0-test}"
251+
NOTES="${NOTES//\{features\}/$FEATURES}"
252+
NOTES="${NOTES//\{bugfixes\}/$BUGFIXES}"
253+
NOTES="${NOTES//\{breaking\}/$BREAKING}"
254+
NOTES="${NOTES//\{documentation\}/$DOCUMENTATION}"
255+
NOTES="${NOTES//\{internal\}/$INTERNAL}"
256+
NOTES="${NOTES//\{dependencies\}/$DEPENDENCIES}"
257+
NOTES="${NOTES//\{other\}/$OTHER}"
258+
NOTES="${NOTES//\{compare_url\}/https://github.com/${{ github.repository }}/compare/$PREVIOUS_TAG...$TEST_TAG}"
259+
NOTES="${NOTES//\{contributors\}/$CONTRIBUTORS}"
260+
NOTES="${NOTES//\{commits\}/[View all commits](https://github.com/${{ github.repository }}/compare/$PREVIOUS_TAG...$TEST_TAG)}"
261+
NOTES="${NOTES//\{upgrade_notes\}/<!-- Add any upgrade notes or migration steps here -->}"
262+
NOTES="${NOTES//\{known_issues\}/<!-- Add any known issues or caveats here -->}"
263+
264+
# Save generated notes
265+
echo "$NOTES" > test-release-notes.md
266+
267+
echo "✅ Template generation completed successfully!"
268+
echo ""
269+
echo "=== Generated Release Notes Preview ==="
270+
head -50 test-release-notes.md
271+
272+
- name: Validate generated content
273+
run: |
274+
echo "=== Validating Generated Content ==="
275+
276+
# Check if file was created
277+
if [[ ! -f test-release-notes.md ]]; then
278+
echo "❌ Release notes file was not generated"
279+
exit 1
280+
fi
281+
282+
# Check if template placeholders were replaced
283+
if grep -q "{version}" test-release-notes.md; then
284+
echo "❌ Version placeholder was not replaced"
285+
exit 1
286+
fi
287+
288+
if grep -q "{compare_url}" test-release-notes.md; then
289+
echo "❌ Compare URL placeholder was not replaced"
290+
exit 1
291+
fi
292+
293+
# Check for expected sections
294+
sections=("Features Added" "Bug Fixes" "Breaking Changes" "Documentation" "Internal/DevOps" "Dependencies" "Other Changes")
295+
for section in "${sections[@]}"; do
296+
if ! grep -q "$section" test-release-notes.md; then
297+
echo "❌ Missing section: $section"
298+
exit 1
299+
fi
300+
done
301+
302+
# Check scenario-specific content
303+
case "${{ github.event.inputs.test_scenario }}" in
304+
"basic")
305+
if ! grep -q "add new test feature" test-release-notes.md; then
306+
echo "❌ Expected feature commit not found in basic scenario"
307+
exit 1
308+
fi
309+
;;
310+
"with_breaking_changes")
311+
if ! grep -q "change API structure" test-release-notes.md; then
312+
echo "❌ Expected breaking change not found"
313+
exit 1
314+
fi
315+
;;
316+
"comprehensive")
317+
if ! grep -q "Kong API gateway" test-release-notes.md; then
318+
echo "❌ Expected comprehensive feature not found"
319+
exit 1
320+
fi
321+
;;
322+
esac
323+
324+
echo "✅ All validations passed!"
325+
326+
- name: Cleanup test artifacts
327+
if: always()
328+
run: |
329+
echo "=== Cleaning up test artifacts ==="
330+
331+
# Remove test tag if it exists
332+
if git tag -l | grep -q "$TEST_TAG"; then
333+
git tag -d "$TEST_TAG" || echo "Failed to delete test tag (non-critical)"
334+
fi
335+
336+
# Switch back to original branch and delete test branch
337+
git checkout "${{ github.event.inputs.target_branch || github.ref_name }}" || git checkout main
338+
if git branch | grep -q "$TEST_BRANCH"; then
339+
git branch -D "$TEST_BRANCH" || echo "Failed to delete test branch (non-critical)"
340+
fi
341+
342+
echo "✅ Cleanup completed"
343+
344+
- name: Upload test results
345+
uses: actions/upload-artifact@v4
346+
if: always()
347+
with:
348+
name: release-notes-test-results-${{ github.event.inputs.test_scenario }}
349+
path: |
350+
test-release-notes.md
351+
features.txt
352+
bugfixes.txt
353+
breaking.txt
354+
documentation.txt
355+
internal.txt
356+
dependencies.txt
357+
other.txt
358+
retention-days: 7
359+
360+
- name: Test summary
361+
run: |
362+
echo "=== Test Summary ==="
363+
echo "✅ Scenario: ${{ github.event.inputs.test_scenario }}"
364+
echo "✅ Commit categorization working correctly"
365+
echo "✅ Template generation successful"
366+
echo "✅ Content validation passed"
367+
echo "✅ All test artifacts uploaded"
368+
echo ""
369+
echo "🎉 Release notes generation system is working correctly!"
370+
echo ""
371+
echo "Next steps:"
372+
echo "1. Review the generated release notes in the artifacts"
373+
echo "2. Test the actual workflow with a real release"
374+
echo "3. Make any necessary adjustments to categorization rules"

0 commit comments

Comments
 (0)