@@ -106,57 +106,109 @@ jobs:
106106 cd release
107107 sha256sum * > checksums.txt
108108
109- - name : Create Release Notes
110- id : release_notes
109+ - name : Get previous release tag
110+ id : previous_tag
111111 run : |
112- cat > release_notes.md << 'EOF'
113- ## Installation
112+ set -euo pipefail
113+ CURRENT_TAG="${{ steps.version_early.outputs.version }}"
114114
115- ### Binary Installation (Recommended)
115+ # Use git tags directly (more reliable than gh release list)
116+ # Get the most recent tag that is not the current tag
117+ PREVIOUS_TAG=$(git tag --sort=-version:refname | grep -v "^${CURRENT_TAG}$" | head -n1 || echo "")
116118
117- **Linux (x64):**
118- ```bash
119- curl -L https://github.com/${{ github.repository }}/releases/download/${{ steps.version_early.outputs.version }}/awf-linux-x64 -o awf
120- chmod +x awf
121- sudo mv awf /usr/local/bin/
122- ```
119+ echo "previous_tag=$PREVIOUS_TAG" >> $GITHUB_OUTPUT
120+ echo "Previous tag: $PREVIOUS_TAG (current: $CURRENT_TAG)"
121+
122+ - name : Generate changelog from commits
123+ id : changelog
124+ run : |
125+ set -euo pipefail
126+ CURRENT_TAG="${{ steps.version_early.outputs.version }}"
127+ PREVIOUS_TAG="${{ steps.previous_tag.outputs.previous_tag }}"
128+
129+ echo "Generating changelog from $PREVIOUS_TAG to $CURRENT_TAG"
130+
131+ # Generate changelog using GitHub's API
132+ if [ -n "$PREVIOUS_TAG" ]; then
133+ CHANGELOG=$(gh api repos/${{ github.repository }}/releases/generate-notes \
134+ -f tag_name="$CURRENT_TAG" \
135+ -f previous_tag_name="$PREVIOUS_TAG" \
136+ --jq '.body' 2>/dev/null || echo "")
137+ else
138+ # First release - try API without previous tag
139+ CHANGELOG=$(gh api repos/${{ github.repository }}/releases/generate-notes \
140+ -f tag_name="$CURRENT_TAG" \
141+ --jq '.body' 2>/dev/null || echo "")
142+ fi
123143
124- ### NPM Installation (Alternative)
144+ # If API call failed, fall back to git log
145+ if [ -z "$CHANGELOG" ]; then
146+ echo "GitHub API failed, falling back to git log"
147+ if [ -n "$PREVIOUS_TAG" ]; then
148+ CHANGELOG=$(git log --oneline --pretty=format:"* %s (%h)" "$PREVIOUS_TAG..HEAD" 2>/dev/null || echo "* Initial release")
149+ else
150+ # First release - get all commits (no arbitrary limit)
151+ CHANGELOG=$(git log --oneline --pretty=format:"* %s (%h)" 2>/dev/null || echo "* Initial release")
152+ fi
153+ fi
125154
126- ```bash
127- # Install from tarball
128- npm install -g https://github.com/${{ github.repository }}/releases/download/${{ steps.version_early.outputs.version }}/awf.tgz
129- ```
155+ # Write changelog to file for multiline handling
156+ echo "$CHANGELOG" > changelog_body.md
130157
131- ### Requirements
158+ # Validate changelog was generated
159+ if [ ! -s changelog_body.md ]; then
160+ echo "Error: Changelog generation failed or produced empty output"
161+ exit 1
162+ fi
132163
133- - Docker and Docker Compose must be installed
134- - For iptables manipulation, run with sudo: `sudo awf ...`
135- - Container images will be pulled automatically from GHCR on first run
164+ echo "Changelog generated successfully ($(wc -l < changelog_body.md) lines)"
165+ env :
166+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
136167
137- ## Verification
168+ - name : Generate CLI help output
169+ id : cli_help
170+ run : |
171+ set -euo pipefail
138172
139- Verify checksums after download:
140- ```bash
141- sha256sum -c checksums.txt
142- ```
173+ # Generate CLI help from the built binary
174+ node dist/cli.js --help > cli_help.txt
143175
144- ## Usage
176+ # Validate CLI help was generated
177+ if [ ! -s cli_help.txt ]; then
178+ echo "Error: CLI help generation failed or produced empty output"
179+ exit 1
180+ fi
145181
146- ```bash
147- sudo awf --allow-domains github.com,api.github.com 'curl https://api.github.com'
148- ```
182+ echo "CLI help generated ($(wc -l < cli_help.txt) lines):"
183+ cat cli_help.txt
149184
150- See [README.md](https://github.com/${{ github.repository }}/blob/${{ steps.version_early.outputs.version }}/README.md) for full documentation.
185+ - name : Create Release Notes
186+ id : release_notes
187+ env :
188+ VERSION : ${{ steps.version_early.outputs.version }}
189+ VERSION_NUMBER : ${{ steps.version_early.outputs.version_number }}
190+ REPOSITORY : ${{ github.repository }}
191+ run : |
192+ set -euo pipefail
193+
194+ # Use Node.js script for safe template substitution
195+ # (avoids shell injection issues with special characters)
196+ node scripts/generate-release-notes.js \
197+ changelog_body.md \
198+ cli_help.txt \
199+ release_notes.md
200+
201+ # Validate output was generated
202+ if [ ! -s release_notes.md ]; then
203+ echo "Error: Release notes generation failed"
204+ exit 1
205+ fi
151206
152- ## Container Images
207+ # Cleanup temp files
208+ rm -f changelog_body.md cli_help.txt
153209
154- Published to GitHub Container Registry:
155- - `ghcr.io/${{ github.repository }}/squid:${{ steps.version_early.outputs.version_number }}`
156- - `ghcr.io/${{ github.repository }}/copilot:${{ steps.version_early.outputs.version_number }}`
157- - `ghcr.io/${{ github.repository }}/squid:latest`
158- - `ghcr.io/${{ github.repository }}/copilot:latest`
159- EOF
210+ echo "Release notes preview (first 20 lines):"
211+ head -20 release_notes.md
160212
161213 - name : Create GitHub Release
162214 uses : softprops/action-gh-release@v1
0 commit comments