Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 21 additions & 8 deletions .github/workflows/_package-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
workflow_call:
inputs:
commit_message:
description: 'Commit message to check for skip markers'
description: "Commit message to check for skip markers"
required: false
type: string
secrets:
Expand Down Expand Up @@ -66,11 +66,11 @@ jobs:
- name: Validate installation
shell: bash
run: |
OUTPUT=$(uv run --all-extras --no-dev aignostics --help)
if [[ "$OUTPUT" != *"built with love in Berlin"* ]]; then
echo "Output does not contain 'built with love in Berlin'"
exit 1
fi
OUTPUT=$(uv run --all-extras --no-dev aignostics --help)
if [[ "$OUTPUT" != *"built with love in Berlin"* ]]; then
echo "Output does not contain 'built with love in Berlin'"
exit 1
fi

- name: Install upx for native Windows version
if: ${{ matrix.runner == 'windows-latest' || matrix.runner == 'windows-11-arm' }}
Expand Down Expand Up @@ -219,7 +219,7 @@ jobs:
rm -rf ./test-results/coverage_html
gh release create ${{ github.ref_name }} ./dist/* ./dist_native_zipped/* ./audit-results/* \
--notes-file ${{ steps.git-cliff.outputs.changelog }}

- name: Inform Sentry about release
uses: getsentry/action-release@dab6548b3c03c4717878099e43782cf5be654289 # v3.5.0
env:
Expand All @@ -230,6 +230,19 @@ jobs:
environment: production
release: ${{ github.ref_name }}

- name: Convert release notes from Markdown to Slack mrkdwn
id: slack-notes
shell: bash
run: |
# Convert Markdown links [text](url) to Slack mrkdwn <url|text>
# Convert bold **text** to *text*
SLACK_RELEASE_NOTES=$(echo '${{ toJSON(steps.git-cliff.outputs.content) }}' | \
Comment on lines +235 to +239
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The conversion uses toJSON(steps.git-cliff.outputs.content) and then echoes it as a literal string, which produces a JSON-escaped value (surrounding quotes and escaped \n). That means sed will run against the escaped representation and the Slack output is likely to contain quotes/backslashes instead of proper newlines/markdown. Consider passing the raw content into the step (e.g., via an env var) or explicitly decoding the JSON string before running the sed transforms.

Suggested change
shell: bash
run: |
# Convert Markdown links [text](url) to Slack mrkdwn <url|text>
# Convert bold **text** to *text*
SLACK_RELEASE_NOTES=$(echo '${{ toJSON(steps.git-cliff.outputs.content) }}' | \
env:
RELEASE_NOTES: ${{ steps.git-cliff.outputs.content }}
shell: bash
run: |
# Convert Markdown links [text](url) to Slack mrkdwn <url|text>
# Convert bold **text** to *text*
SLACK_RELEASE_NOTES=$(printf '%s\n' "${RELEASE_NOTES}" | \

Copilot uses AI. Check for mistakes.
sed -E 's/\[([^]]+)\]\(([^)]+)\)/<\2|\1>/g' | \
sed -E 's/\*\*([^*]+)\*\*/*\1*/g')
echo "content<<SLACKEOF" >> "$GITHUB_OUTPUT"
echo "$SLACK_RELEASE_NOTES" >> "$GITHUB_OUTPUT"
echo "SLACKEOF" >> "$GITHUB_OUTPUT"

- name: Release Announcement
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1
with:
Expand All @@ -238,7 +251,7 @@ jobs:
payload: |
"repository": "${{ github.repository }}",
"version": "${{ steps.git-cliff.outputs.version }}",
"release_notes": ${{ toJSON(steps.git-cliff.outputs.content) }},
"release_notes": ${{ steps.slack-notes.outputs.content }},
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

payload appears to be constructed as JSON/YAML, but release_notes is now injected without quoting/escaping. If steps.slack-notes.outputs.content contains newlines, quotes, or colons, this will break the payload parsing or produce invalid JSON for the Slack webhook. Wrap the value in toJSON(...) (or otherwise ensure proper escaping) so the payload remains valid regardless of release note contents.

Suggested change
"release_notes": ${{ steps.slack-notes.outputs.content }},
"release_notes": ${{ toJSON(steps.slack-notes.outputs.content) }},

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The release_notes value is not wrapped with toJSON(), which will create an invalid payload for the Slack action if the notes contain special characters or newlines.
Severity: MEDIUM

Suggested Fix

To ensure the payload is always valid JSON, wrap the output variable in a toJSON() call. The line should be changed to: "release_notes": ${{ toJSON(steps.slack-notes.outputs.content) }},.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: .github/workflows/_package-publish.yml#L254

Potential issue: In the `_package-publish.yml` workflow, the `release_notes` field is
populated with raw, potentially multiline content that may contain special characters.
This content is not properly escaped using `toJSON()` before being inserted into the
payload for the `slackapi/slack-github-action`. When the action attempts to parse this
payload, the unescaped value will break the JSON/YAML structure. This will cause the
'Release Announcement' step to fail, preventing release notifications from being sent to
the designated Slack channel.

Did we get this right? 👍 / 👎 to inform future reviews.

"channel_id": "${{ secrets.SLACK_CHANNEL_ID_RELEASE_ANNOUNCEMENT }}"

- name: Allow other workflows to trigger on release
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ filter_unconventional = true
split_commits = true
# regex for preprocessing the commit messages
commit_preprocessors = [
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))" },
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/pull/${2}))" },
{ pattern = '^[-*]?\s+(\w+)\s+\(([^)]+)\):', replace = "* ${1}(${2}):" },
{ pattern = '^[-*]\s+', replace = "" },
]
Expand Down
Loading