|
4 | 4 | workflow_dispatch: |
5 | 5 | inputs: |
6 | 6 | use_ai: |
7 | | - description: Generate the changelog with GitHub Models when manual notes are empty. |
| 7 | + description: Generate the changelog with AI when manual notes are empty. |
8 | 8 | required: true |
9 | 9 | type: boolean |
10 | 10 | default: true |
|
13 | 13 | required: false |
14 | 14 | type: string |
15 | 15 | default: '' |
16 | | - model: |
17 | | - description: GitHub Models model for AI changelog generation. |
18 | | - required: false |
19 | | - type: string |
20 | | - default: openai/gpt-4o |
21 | 16 |
|
22 | 17 | permissions: |
23 | 18 | contents: write |
24 | | - models: read |
25 | 19 |
|
26 | 20 | concurrency: |
27 | 21 | group: minor-release-${{ github.ref }} |
@@ -108,21 +102,43 @@ jobs: |
108 | 102 |
|
109 | 103 | - name: Generate changelog notes with AI |
110 | 104 | if: ${{ inputs.manual_changelog == '' && inputs.use_ai }} |
111 | | - id: ai_changelog |
112 | | - uses: actions/ai-inference@v1 |
113 | | - with: |
114 | | - model: ${{ inputs.model }} |
115 | | - prompt-file: .github/prompts/minor-release-changelog.prompt.yml |
116 | | - input: | |
117 | | - version: ${{ steps.release_meta.outputs.new_version }} |
118 | | - date: ${{ steps.release_meta.outputs.release_date }} |
119 | | - file_input: | |
120 | | - release_context: .release/release-context.md |
121 | | -
|
122 | | - - name: Save AI changelog notes |
123 | | - if: ${{ inputs.manual_changelog == '' && inputs.use_ai }} |
| 105 | + env: |
| 106 | + OPENAI_API_KEY: ${{ secrets.OPENAI_SECRET }} |
124 | 107 | run: | |
125 | | - cp "${{ steps.ai_changelog.outputs.response-file }}" .release/changelog-body.md |
| 108 | + SYSTEM_PROMPT=$(cat .github/prompts/minor-release-changelog-system.txt) |
| 109 | + USER_TEMPLATE=$(cat .github/prompts/minor-release-changelog-user.txt) |
| 110 | + RELEASE_CONTEXT=$(cat .release/release-context.md) |
| 111 | + VERSION="${{ steps.release_meta.outputs.new_version }}" |
| 112 | + DATE="${{ steps.release_meta.outputs.release_date }}" |
| 113 | +
|
| 114 | + jq -n \ |
| 115 | + --arg sys "$SYSTEM_PROMPT" \ |
| 116 | + --arg usr "$USER_TEMPLATE" \ |
| 117 | + --arg ver "$VERSION" \ |
| 118 | + --arg dt "$DATE" \ |
| 119 | + --arg ctx "$RELEASE_CONTEXT" \ |
| 120 | + '{ |
| 121 | + model: "gpt-5.4-nano-2026-03-17", |
| 122 | + messages: [ |
| 123 | + {role: "system", content: $sys}, |
| 124 | + {role: "user", content: ($usr | gsub("\\{\\{version\\}\\}"; $ver) | gsub("\\{\\{date\\}\\}"; $dt) | gsub("\\{\\{release_context\\}\\}"; $ctx))} |
| 125 | + ], |
| 126 | + max_completion_tokens: 1200, |
| 127 | + temperature: 0.2 |
| 128 | + }' > /tmp/payload.json |
| 129 | +
|
| 130 | + RESPONSE=$(curl -s https://api.openai.com/v1/chat/completions \ |
| 131 | + -H "Authorization: Bearer $OPENAI_API_KEY" \ |
| 132 | + -H "Content-Type: application/json" \ |
| 133 | + -d @/tmp/payload.json) |
| 134 | +
|
| 135 | + ERROR=$(echo "$RESPONSE" | jq -r '.error.message // empty') |
| 136 | + if [ -n "$ERROR" ]; then |
| 137 | + echo "API error: $ERROR" >&2 |
| 138 | + exit 1 |
| 139 | + fi |
| 140 | +
|
| 141 | + echo "$RESPONSE" | jq -r '.choices[0].message.content' > .release/changelog-body.md |
126 | 142 |
|
127 | 143 | - name: Require changelog notes |
128 | 144 | run: | |
|
0 commit comments