Skip to content

Commit 4ee3ca7

Browse files
committed
fix: resolve workflow issues and improve release automation
- Fix shellcheck issues in release workflow - Improve GitHub Pages links with correct base paths - Fix SBOM redirect loops - Add commit author attribution to releases - Update security audit to handle false positives - Enhance release notes with contributor information Signed-off-by: Rubens <[email protected]>
1 parent 9c12463 commit 4ee3ca7

File tree

7 files changed

+342
-188
lines changed

7 files changed

+342
-188
lines changed

.github/workflows/docs.yml

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -116,17 +116,17 @@ jobs:
116116
</div>
117117
118118
<div class="grid">
119-
<a href="/docs/" class="card">
119+
<a href="./docs/" class="card">
120120
<h3>📚 API Documentation</h3>
121121
<p>Complete TypeScript API documentation generated with TypeDoc. Explore all classes, interfaces, and functions.</p>
122122
</a>
123123
124-
<a href="/sbom/" class="card">
124+
<a href="./sbom/" class="card">
125125
<h3>🔒 Security & SBOM</h3>
126126
<p>Software Bill of Materials, security reports, and compliance documentation for transparency and audit.</p>
127127
</a>
128128
129-
<a href="/performance/" class="card">
129+
<a href="./performance/" class="card">
130130
<h3>⚡ Performance Reports</h3>
131131
<p>Bundle analysis, memory profiling, and benchmark results to ensure optimal action performance.</p>
132132
</a>
@@ -156,9 +156,9 @@ jobs:
156156
</html>
157157
EOF
158158
159-
- name: Create SBOM redirect page
159+
- name: Create SBOM placeholder page
160160
run: |
161-
# Create a redirect page to the SBOM workflow's generated pages
161+
# Create a placeholder page for SBOM - actual SBOM is generated by sbom.yml workflow
162162
mkdir -p _site/sbom
163163
cat > _site/sbom/index.html << 'EOF'
164164
<!DOCTYPE html>
@@ -167,10 +167,13 @@ jobs:
167167
<meta charset="UTF-8">
168168
<meta name="viewport" content="width=device-width, initial-scale=1.0">
169169
<title>SBOM - conditional-paths-action</title>
170-
<meta http-equiv="refresh" content="0; url=https://santosr2.github.io/conditional-paths-action/sbom/">
171170
<style>
172-
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 40px; line-height: 1.6; text-align: center; }
173-
.redirect-message { background: #f6f8fa; padding: 20px; border-radius: 8px; margin: 20px 0; }
171+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 40px; line-height: 1.6; }
172+
.sbom-list { list-style: none; padding: 0; }
173+
.sbom-list li { margin: 10px 0; }
174+
.sbom-list a { color: #0366d6; text-decoration: none; padding: 10px; display: inline-block; }
175+
.sbom-list a:hover { text-decoration: underline; }
176+
.back { margin-bottom: 20px; }
174177
.back a { color: #0366d6; text-decoration: none; }
175178
</style>
176179
</head>
@@ -179,18 +182,17 @@ jobs:
179182
<a href="../">← Back to Documentation</a>
180183
</div>
181184
182-
<div class="redirect-message">
183-
<h1>🔒 Software Bill of Materials (SBOM)</h1>
184-
<p>You are being redirected to the SBOM viewer...</p>
185-
<p>If you are not redirected automatically, <a href="https://santosr2.github.io/conditional-paths-action/sbom/">click here</a>.</p>
186-
</div>
187-
188-
<script>
189-
// Redirect after a short delay
190-
setTimeout(() => {
191-
window.location.href = 'https://santosr2.github.io/conditional-paths-action/sbom/';
192-
}, 1000);
193-
</script>
185+
<h1>📔 Software Bill of Materials</h1>
186+
<p>CycloneDX v1.6 format SBOMs for conditional-paths-action</p>
187+
<ul class="sbom-list">
188+
<li>📦 <a href="./sbom.json">Latest SBOM (Node.js 24)</a></li>
189+
<li>📦 <a href="./sbom-node22.json">SBOM for Node.js 22</a></li>
190+
<li>📦 <a href="./sbom-node24.json">SBOM for Node.js 24</a></li>
191+
<li>📊 <a href="./sbom-comparison-report.md">Comparison Report</a></li>
192+
</ul>
193+
<hr>
194+
<p><em>Note: SBOMs are generated by the SBOM workflow. If files are not available, please check the <a href="https://github.com/santosr2/conditional-paths-action/actions/workflows/sbom.yml">SBOM workflow status</a>.</em></p>
195+
<p><em>Generated: <script>document.write(new Date().toISOString())</script></em></p>
194196
</body>
195197
</html>
196198
EOF

.github/workflows/release.yml

Lines changed: 185 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,104 @@ jobs:
2525
tag-name: ${{ steps.release.outputs.tag_name }}
2626
version: ${{ steps.release.outputs.version }}
2727
major-version: ${{ steps.release.outputs.major }}
28+
pr-number: ${{ steps.release.outputs.pr }}
2829
steps:
2930
- name: Create Release PR or Release
3031
id: release
3132
uses: googleapis/release-please-action@c2a5a2bd6a758a0937f1ddb1e8950609867ed15c # v4.3.0
3233
with:
3334
token: ${{ secrets.GITHUB_TOKEN }}
3435
release-type: node
36+
config-file: release-please-config.json
37+
38+
enhance-release-pr:
39+
name: Enhance Release PR with Authors
40+
runs-on: ubuntu-latest
41+
needs: release-please
42+
if: needs.release-please.outputs.pr-number != ''
43+
steps:
44+
- name: Checkout code
45+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
46+
with:
47+
fetch-depth: 0
48+
fetch-tags: true
49+
50+
- name: Configure git identity
51+
run: |
52+
git config --global user.name "github-actions[bot]"
53+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
54+
55+
- name: Enhance PR body with commit authors
56+
env:
57+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
58+
run: |
59+
PR_NUMBER="${{ needs.release-please.outputs.pr-number }}"
60+
echo "Enhancing PR #$PR_NUMBER with author information"
61+
62+
# Get the current PR body
63+
PR_BODY=$(gh pr view "$PR_NUMBER" --json body -q .body)
64+
65+
# Get the last release tag
66+
PREVIOUS_TAG=$(git tag --sort=-version:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -1 || echo "")
67+
68+
if [[ -n "$PREVIOUS_TAG" ]]; then
69+
echo "Found previous tag: $PREVIOUS_TAG"
70+
71+
# Generate author credits section
72+
AUTHOR_CREDITS=""
73+
AUTHOR_CREDITS="${AUTHOR_CREDITS}"$'\n\n'"## 👥 Contributors"$'\n\n'
74+
75+
# Get unique contributors since last release
76+
CONTRIBUTORS=$(git log "$PREVIOUS_TAG..HEAD" --format='%an' --no-merges | sort -u)
77+
78+
while IFS= read -r contributor; do
79+
AUTHOR_CREDITS="${AUTHOR_CREDITS}• **${contributor}**"$'\n'
80+
done <<< "$CONTRIBUTORS"
81+
82+
# Add commit details with authors
83+
AUTHOR_CREDITS="${AUTHOR_CREDITS}"$'\n'"## 📝 Commits by Author"$'\n\n'
84+
85+
# Group commits by type with authors
86+
for type in feat fix docs perf deps ci refactor test chore build; do
87+
case $type in
88+
feat) section="### Features" ;;
89+
fix) section="### Bug Fixes" ;;
90+
docs) section="### Documentation" ;;
91+
perf) section="### Performance" ;;
92+
deps) section="### Dependencies" ;;
93+
ci) section="### CI/CD" ;;
94+
refactor) section="### Refactoring" ;;
95+
test) section="### Testing" ;;
96+
chore) section="### Maintenance" ;;
97+
build) section="### Build System" ;;
98+
esac
99+
100+
# Filter commits for this type - simplified pattern to avoid shellcheck issues
101+
COMMITS=""
102+
while IFS= read -r line; do
103+
if echo "$line" | grep -q "^${type}"; then
104+
# Remove type prefix and add bullet point
105+
cleaned="• ${line#"${type}"*: }"
106+
COMMITS="${COMMITS}${cleaned}"$'\n'
107+
fi
108+
done < <(git log "$PREVIOUS_TAG..HEAD" --pretty=format:"%s (@%an)" --no-merges)
109+
110+
if [[ -n "$COMMITS" ]]; then
111+
AUTHOR_CREDITS="${AUTHOR_CREDITS}${section}"$'\n'"${COMMITS}"
112+
fi
113+
done
114+
115+
# Update PR body with author information
116+
NEW_BODY="${PR_BODY}"$'\n\n'"---"$'\n'"${AUTHOR_CREDITS}"
117+
118+
# Escape the body for gh pr edit
119+
echo "$NEW_BODY" > /tmp/pr_body.txt
120+
gh pr edit "$PR_NUMBER" --body-file /tmp/pr_body.txt
121+
122+
echo "PR #$PR_NUMBER has been enhanced with author information"
123+
else
124+
echo "No previous release tag found, skipping author enhancement"
125+
fi
35126
36127
validate-tag:
37128
name: Validate Release Tag
@@ -144,6 +235,7 @@ jobs:
144235
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
145236
with:
146237
fetch-depth: 0
238+
fetch-tags: true
147239

148240
- name: Download release artifacts (Node 22)
149241
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
@@ -175,6 +267,15 @@ jobs:
175267
176268
printf "Generating changelog from %s to %s\n" "$PREVIOUS_TAG" "$CURRENT_TAG"
177269
270+
# Debug: Show available tags and commits
271+
echo "Available tags:"
272+
git tag --sort=-version:refname | head -5
273+
274+
if [[ -n "$PREVIOUS_TAG" ]]; then
275+
echo "Commits between $PREVIOUS_TAG and $CURRENT_TAG:"
276+
git log "$PREVIOUS_TAG..$CURRENT_TAG" --oneline --no-merges | head -10
277+
fi
278+
178279
# Generate conventional changelog
179280
if [[ -n "$PREVIOUS_TAG" ]]; then
180281
conventional-changelog -p conventionalcommits -r 2 > temp_changelog.md
@@ -189,33 +290,96 @@ jobs:
189290
190291
# Extract changes from conventional changelog
191292
if [[ -n "$PREVIOUS_TAG" ]]; then
192-
# Parse git log for conventional commits and categorize
293+
# Parse git log for conventional commits and categorize with authors
193294
{
194295
echo "### ✨ Features"
195-
git log "$PREVIOUS_TAG..$CURRENT_TAG" --pretty=format:"%s" --no-merges | grep -E "^feat(\(.+\))?:" | sed 's/^feat\(([^)]*)\)\?:\s*/* /' || echo "No new features"
296+
FEATURES=$(git log "$PREVIOUS_TAG..$CURRENT_TAG" --pretty=format:"%s (@%an)" --no-merges | { grep -E "^feat(\\([^)]+\\))?:" || true; } | sed -E 's/^feat(\\([^)]+\\))?:\\s*/- /')
297+
if [[ -n "$FEATURES" ]]; then
298+
echo "$FEATURES"
299+
else
300+
echo "- No new features in this release"
301+
fi
196302
echo ""
303+
197304
echo "### 🐛 Bug Fixes"
198-
git log "$PREVIOUS_TAG..$CURRENT_TAG" --pretty=format:"%s" --no-merges | grep -E "^fix(\(.+\))?:" | sed 's/^fix\(([^)]*)\)\?:\s*/* /' || echo "No bug fixes"
305+
FIXES=$(git log "$PREVIOUS_TAG..$CURRENT_TAG" --pretty=format:"%s (@%an)" --no-merges | { grep -E "^fix(\\([^)]+\\))?:" || true; } | sed -E 's/^fix(\\([^)]+\\))?:\\s*/- /')
306+
if [[ -n "$FIXES" ]]; then
307+
echo "$FIXES"
308+
else
309+
echo "- No bug fixes in this release"
310+
fi
199311
echo ""
312+
200313
echo "### 📚 Documentation"
201-
git log "$PREVIOUS_TAG..$CURRENT_TAG" --pretty=format:"%s" --no-merges | grep -E "^docs(\(.+\))?:" | sed 's/^docs\(([^)]*)\)\?:\s*/* /' || echo "No documentation changes"
314+
DOCS=$(git log "$PREVIOUS_TAG..$CURRENT_TAG" --pretty=format:"%s (@%an)" --no-merges | { grep -E "^docs(\\([^)]+\\))?:" || true; } | sed -E 's/^docs(\\([^)]+\\))?:\\s*/- /')
315+
if [[ -n "$DOCS" ]]; then
316+
echo "$DOCS"
317+
else
318+
echo "- No documentation changes in this release"
319+
fi
202320
echo ""
321+
203322
echo "### ⚡ Performance"
204-
git log "$PREVIOUS_TAG..$CURRENT_TAG" --pretty=format:"%s" --no-merges | grep -E "^perf(\(.+\))?:" | sed 's/^perf\(([^)]*)\)\?:\s*/* /' || echo "No performance improvements"
323+
PERF=$(git log "$PREVIOUS_TAG..$CURRENT_TAG" --pretty=format:"%s (@%an)" --no-merges | { grep -E "^perf(\\([^)]+\\))?:" || true; } | sed -E 's/^perf(\\([^)]+\\))?:\\s*/- /')
324+
if [[ -n "$PERF" ]]; then
325+
echo "$PERF"
326+
else
327+
echo "- No performance improvements in this release"
328+
fi
205329
echo ""
330+
206331
echo "### 🔧 Maintenance"
207-
git log "$PREVIOUS_TAG..$CURRENT_TAG" --pretty=format:"%s" --no-merges | grep -E "^(chore|ci|build|refactor)(\(.+\))?:" | sed 's/^[^:]*:\s*/* /' || echo "No maintenance changes"
332+
MAINT=$(git log "$PREVIOUS_TAG..$CURRENT_TAG" --pretty=format:"%s (@%an)" --no-merges | { grep -E "^(chore|ci|build|refactor)(\\([^)]+\\))?:" || true; } | sed -E 's/^[^:]+:\\s*/- /')
333+
if [[ -n "$MAINT" ]]; then
334+
echo "$MAINT"
335+
else
336+
echo "- No maintenance changes in this release"
337+
fi
208338
echo ""
209339
} >> release_notes.md
210340
211341
# Add commit count and contributors
212342
COMMIT_COUNT=$(git rev-list --count "$PREVIOUS_TAG..$CURRENT_TAG")
213-
CONTRIBUTORS=$(git log "$PREVIOUS_TAG..$CURRENT_TAG" --format='%an' --no-merges | sort -u | wc -l | tr -d ' ')
343+
CONTRIBUTOR_LIST=$(git log "$PREVIOUS_TAG..$CURRENT_TAG" --format='%an' --no-merges | sort -u)
344+
CONTRIBUTOR_COUNT=$(echo "$CONTRIBUTOR_LIST" | wc -l | tr -d ' ')
214345
215346
{
216347
echo "### 📊 Release Statistics"
217348
echo "- **$COMMIT_COUNT** commits since $PREVIOUS_TAG"
218-
echo "- **$CONTRIBUTORS** contributor(s) to this release"
349+
echo "- **$CONTRIBUTOR_COUNT** contributor(s) to this release"
350+
echo ""
351+
echo "### 👥 Contributors"
352+
echo "Thanks to the following contributors for this release:"
353+
echo ""
354+
while IFS= read -r contributor; do
355+
# Try to extract GitHub username from git config or use name as-is
356+
# Common patterns: "Name", "username", "Name (username)"
357+
if echo "$contributor" | grep -q '(.*)'; then
358+
# Extract username from parentheses if present
359+
# Extract username using parameter expansion
360+
temp="${contributor#*(}"
361+
username="${temp%)}"
362+
echo "- [@$username](https://github.com/$username) ($contributor)"
363+
else
364+
# Use the name as-is, attempting to link it
365+
echo "- **$contributor**"
366+
fi
367+
done <<< "$CONTRIBUTOR_LIST"
368+
echo ""
369+
echo "### 📝 Full Changelog"
370+
echo "<details>"
371+
echo "<summary>View all commits</summary>"
372+
echo ""
373+
echo "| Commit | Author | Message |"
374+
echo "|--------|--------|---------|"
375+
# Use a while loop to properly escape commit messages
376+
git log "$PREVIOUS_TAG..$CURRENT_TAG" --pretty=format:"%h|%an|%s" --no-merges | while IFS='|' read -r hash author message; do
377+
# Escape pipe characters in the message
378+
escaped_message="${message//|/\\|}"
379+
echo "| [\`$hash\`](https://github.com/${{ github.repository }}/commit/$hash) | **$author** | $escaped_message |"
380+
done
381+
echo ""
382+
echo "</details>"
219383
echo ""
220384
} >> release_notes.md
221385
else
@@ -300,15 +464,25 @@ jobs:
300464
token: ${{ secrets.GITHUB_TOKEN }}
301465
fetch-depth: 0
302466

467+
- name: Configure git identity
468+
run: |
469+
git config --global user.name "github-actions[bot]"
470+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
471+
303472
- name: Update major version tag
304473
run: |
305474
major_tag="${{ needs.validate-tag.outputs.major-version }}"
306475
current_tag="${{ needs.release-please.outputs.tag-name }}"
307476
308477
echo "Updating $major_tag to point to $current_tag"
309478
310-
# Delete the major tag if it exists
311-
git push origin --delete "$major_tag" || true
479+
# Check if the major tag exists remotely
480+
if git ls-remote --tags origin | grep -q "refs/tags/$major_tag"; then
481+
echo "Tag $major_tag exists remotely, deleting it first"
482+
git push origin --delete "$major_tag"
483+
else
484+
echo "Tag $major_tag does not exist remotely, will create it"
485+
fi
312486
313487
# Create new major tag pointing to current release
314488
git tag -fa "$major_tag" -m "Update $major_tag to $current_tag"
@@ -332,6 +506,7 @@ jobs:
332506
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
333507
with:
334508
repository: actions/checkout
509+
ref: main
335510
path: test-repo
336511

337512
- name: Test released action

.github/workflows/sbom.yml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,16 +338,21 @@ jobs:
338338
.sbom-list li { margin: 10px 0; }
339339
.sbom-list a { color: #0366d6; text-decoration: none; padding: 10px; display: inline-block; }
340340
.sbom-list a:hover { text-decoration: underline; }
341+
.back { margin-bottom: 20px; }
342+
.back a { color: #0366d6; text-decoration: none; }
341343
</style>
342344
</head>
343345
<body>
346+
<div class="back">
347+
<a href="../">← Back to Documentation</a>
348+
</div>
344349
<h1>📋 Software Bill of Materials</h1>
345350
<p>CycloneDX v1.6 format SBOMs for conditional-paths-action</p>
346351
<ul class="sbom-list">
347-
<li>📦 <a href="sbom.json">Latest SBOM (Node.js 24)</a></li>
348-
<li>📦 <a href="sbom-node22.json">SBOM for Node.js 22</a></li>
349-
<li>📦 <a href="sbom-node24.json">SBOM for Node.js 24</a></li>
350-
<li>📊 <a href="sbom-comparison-report.md">Comparison Report</a></li>
352+
<li>📦 <a href="./sbom.json">Latest SBOM (Node.js 24)</a></li>
353+
<li>📦 <a href="./sbom-node22.json">SBOM for Node.js 22</a></li>
354+
<li>📦 <a href="./sbom-node24.json">SBOM for Node.js 24</a></li>
355+
<li>📊 <a href="./sbom-comparison-report.md">Comparison Report</a></li>
351356
</ul>
352357
<hr>
353358
<p><em>Generated: <script>document.write(new Date().toISOString())</script></em></p>

0 commit comments

Comments
 (0)