Date: 2025-12-08 Feature: 010-release-notes-generator
Question: Can CLAUDE_CODE_OAUTH_TOKEN be used with the Claude API in GitHub Actions?
Decision: NO - Use ANTHROPIC_API_KEY only
Rationale:
CLAUDE_CODE_OAUTH_TOKEN(sk-ant-...) is restricted to Claude Code CLI only- Attempting to use it with the API returns: "This credential is only authorized for use with Claude Code"
ANTHROPIC_API_KEYfrom Anthropic Console is required for programmatic API access
Alternatives Considered:
| Option | Feasibility | Notes |
|---|---|---|
| CLAUDE_CODE_OAUTH_TOKEN | NOT POSSIBLE | CLI-only, returns auth error |
| ANTHROPIC_API_KEY | SELECTED | Works with all API endpoints |
| Claude Agent SDK | Overkill | Adds unnecessary dependencies |
Action Required: User must obtain ANTHROPIC_API_KEY from console.anthropic.com and add as GitHub secret.
Question: What's the best way to call Claude API from GitHub Actions?
Decision: curl + jq (no SDK dependencies)
Rationale:
- GitHub Actions runners have curl and jq pre-installed
- No Python/Node setup step required
- Faster workflow execution (no dependency installation)
- Simpler error handling with bash
Alternatives Considered:
| Option | Pros | Cons | Decision |
|---|---|---|---|
| curl + jq | No deps, fast | Manual JSON handling | SELECTED |
| Anthropic Python SDK | Type safety | Requires pip install step | Rejected |
| Anthropic Node SDK | Type safety | Requires npm install step | Rejected |
| anthropics/claude-code-action | Official GH Action | Designed for code review, not text gen | Rejected |
Implementation:
curl -s https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "content-type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{...}'Question: What data should be sent to Claude for release notes generation?
Decision: Commit messages only (not full diffs)
Rationale:
- Commit messages contain "what" and "why" - sufficient for release notes
- Full diffs can be megabytes for large releases
- Commit messages: ~50-200 chars each, 500 commits ≈ 50KB (~12K tokens)
- Claude's 200K token context easily handles hundreds of commits
Git Commands:
# Get previous tag
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
# Collect commit messages (exclude merge commits)
if [ -z "$PREV_TAG" ]; then
COMMITS=$(git log --pretty=format:"- %s" --no-merges | head -200)
else
COMMITS=$(git log ${PREV_TAG}..HEAD --pretty=format:"- %s" --no-merges | head -200)
fiFiltering Strategy:
--no-merges: Exclude merge commitshead -200: Truncate to prevent context overflow- Post-filter in prompt: Skip chore/docs/test commits
Question: Which Claude model should be used?
Decision: claude-sonnet-4-5-20250929 (default)
Rationale:
- Sufficient quality for release notes (structured text generation)
- Faster response time (~5-10 seconds vs ~15-30 for Opus)
- Lower cost per request
- Opus available as configurable option for complex changelogs
| Model | Speed | Cost | Quality | Recommendation |
|---|---|---|---|---|
| claude-sonnet-4-5-20250929 | Fast | Lower | Good | DEFAULT |
| claude-opus-4-5-20251101 | Slow | Higher | Excellent | OPTIONAL |
| claude-haiku-4-5-20251001 | Very Fast | Lowest | Basic | NOT RECOMMENDED |
Question: How to ensure concise release notes?
Decision: Three-layer approach
Implementation:
-
API Parameter (hard limit):
{ "max_tokens": 1024 }Caps output at ~750 words.
-
Prompt Engineering (soft guidance):
Generate CONCISE release notes (maximum 400 words). Focus only on user-facing changes. Skip internal refactoring and dependency updates. Group by: New Features, Bug Fixes, Breaking Changes. -
Post-Processing (safety net):
NOTES=$(echo "$RESPONSE" | jq -r '.content[0].text' | head -c 4000)
Question: How to handle API failures without blocking releases?
Decision: Graceful fallback with warning
Implementation:
RESPONSE=$(curl -s --max-time 30 ... || echo '{"error": "timeout"}')
NOTES=$(echo "$RESPONSE" | jq -r '.content[0].text // empty')
if [ -z "$NOTES" ]; then
NOTES="Release notes could not be generated automatically. See commit history for changes."
echo "::warning::Claude API call failed, using fallback message"
fiPrinciple: Never block a release due to notes generation failure.
Question: Where in the release workflow should notes generation happen?
Decision: New job before release job
Rationale:
- Generate notes early while builds are running (parallel)
- Pass notes to release job via outputs
- Allows notes to be available for installer jobs
Workflow Structure:
jobs:
generate-notes: # NEW - runs immediately
runs-on: ubuntu-latest
outputs:
notes: ${{ steps.generate.outputs.notes }}
build: # EXISTING - runs in parallel with generate-notes
...
release: # EXISTING - depends on both
needs: [build, generate-notes]
...Question: How to store release notes for installer inclusion?
Decision: Save as artifact, commit to releases/ directory
Implementation:
- Generate notes in
generate-notesjob - Save to
RELEASE_NOTES-{version}.md - Upload as artifact
- Download in build jobs for installer inclusion
- Optionally commit to repository (separate step)
File Location Options:
| Option | Pros | Cons | Decision |
|---|---|---|---|
releases/RELEASE_NOTES-v1.0.0.md |
Per-version files, easy history | Many files over time | SELECTED |
CHANGELOG.md (prepend) |
Single file, standard | Complex merge handling | Alternative |
docs/releases/ |
Organized | Non-standard location | Rejected |
Question: How to include release notes in macOS DMG?
Decision: Add file to DMG temp directory before creation
Implementation (modify scripts/create-dmg.sh):
# Add after creating TEMP_DIR
if [ -f "RELEASE_NOTES.md" ]; then
cp "RELEASE_NOTES.md" "$TEMP_DIR/"
echo "✅ Release notes included in DMG"
fiLocation in DMG: Root level alongside Applications symlink.
Question: How to include release notes in Windows installer?
Decision: Install to documentation folder via Inno Setup
Implementation (modify inno/mcpproxy.iss):
[Files]
Source: "{#SourceDir}\RELEASE_NOTES.md"; DestDir: "{app}\docs"; Flags: ignoreversionPost-install location: C:\Program Files\MCPProxy\docs\RELEASE_NOTES.md
| Question | Decision |
|---|---|
| API Authentication | ANTHROPIC_API_KEY (not CLAUDE_CODE_OAUTH_TOKEN) |
| API Call Method | curl + jq |
| Input Data | Commit messages only (max 200) |
| Model | claude-sonnet-4-5-20250929 |
| Output Control | max_tokens + prompt + post-process |
| Error Handling | Graceful fallback, never block |
| Workflow Position | New job before release |
| File Storage | Per-version files in releases/ |
| DMG Integration | Copy to temp dir |
| Windows Integration | Inno Setup [Files] section |
- Required: Add
ANTHROPIC_API_KEYas GitHub repository secret - Optional: Configure model via workflow input (default: sonnet)
- Testing: Use
workflow_dispatchto test without pushing tag