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