feat(ci): add release-notification reusable workflow#130
Conversation
… Slack composites
WalkthroughAdds a reusable "Release Notification" workflow, two local composite notification actions (Discord and Slack), docs and READMEs, Dependabot and label updates for notification tooling, documentation rules requiring boolean "has_*" outputs for gating, and a build workflow output Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/release-notification.yml:
- Around line 132-142: The Dry run summary step ("Dry run summary") omits
several resolved inputs and computed channel booleans; update its run block to
echo all resolved inputs discord_color, discord_username, discord_content,
slack_color, slack_icon_emoji and the computed booleans used to decide sending
(e.g. enable_discord, enable_beta_discord, enable_slack or whatever
variables/outputs the workflow computes) using ::notice:: annotations so the
dry-run prints the full effective configuration; keep the existing product_name,
release_tag, webhooks, slack_channel and skip_beta_discord lines and add
corresponding echo lines for the missing inputs and computed enablement flags.
- Around line 123-130: Update the "Fetch latest release tag" step (id: release)
to prefer the triggering release tag by first checking
github.event.release.tag_name and use that as the output if present; only when
github.event_name == 'workflow_dispatch' should you call gh release list to
obtain the latest tag (preserve the echo "tag=$TAG" >> $GITHUB_OUTPUT output
behavior). If neither github.event.release.tag_name nor a gh-derived tag is
available, make the step fail explicitly (non-zero exit) so downstream steps
don't receive an empty/null tag. Ensure the check uses the
GITHUB_EVENT_NAME/GITHUB_EVENT_PATH context to detect the event and set the tag
output consistently.
- Around line 143-156: The reusable workflow steps "Discord notification" and
"Slack notification" currently use local composite actions via "uses:
./src/notify/discord-release" and "uses: ./src/notify/slack-release", which
won't resolve for external callers; change these to explicit external repository
references like "uses:
LerianStudio/github-actions-shared-workflows/src/notify/discord-release@<ref>"
and "uses:
LerianStudio/github-actions-shared-workflows/src/notify/slack-release@<ref>"
(replace <ref> with the workflow's tag/branch) so callers of this workflow can
locate the composites.
- Around line 143-155: The step-level if conditions use secrets (e.g., the
"Discord notification" step's if: ${{ secrets.DISCORD_WEBHOOK_URL != '' }} and
the "Slack notification" step's if: ${{ secrets.SLACK_WEBHOOK_URL != '' &&
inputs.slack_channel != '' }}), which is invalid; instead, add job-level
environment variables that pull the secrets (e.g., set DISCORD_WEBHOOK_URL: ${{
secrets.DISCORD_WEBHOOK_URL }} and SLACK_WEBHOOK_URL: ${{
secrets.SLACK_WEBHOOK_URL }} under the job's env) and change the step if checks
to reference env (e.g., if: env.DISCORD_WEBHOOK_URL != '' and if:
env.SLACK_WEBHOOK_URL != '' && inputs.slack_channel != ''), keeping the existing
uses/with keys like webhook-url, color, username, content, skip-beta, and
dry-run unchanged.
In `@src/notify/discord-release/action.yml`:
- Around line 36-44: The beta detection uses github.ref which is unreliable for
caller-triggered workflows; change the composite's inputs to require a
release-tag and update the Detect beta step (id: beta) to inspect that input
instead of github.ref, and then update the parent workflow call to pass
release-tag: ${{ steps.release.outputs.tag }} (from the release step that
resolves the tag) so the composite can correctly detect "-beta." suffixes.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 71879918-addb-4893-b3af-bb30b9fbcfd8
📒 Files selected for processing (8)
.github/dependabot.yml.github/labels.yml.github/workflows/release-notification.ymldocs/release-notification.mdsrc/notify/discord-release/README.mdsrc/notify/discord-release/action.ymlsrc/notify/slack-release/README.mdsrc/notify/slack-release/action.yml
All comments addressed — 4 accepted, 1 rejected (uses: ./src/ pattern is correct for workflow_call).
- Prefer github.event.release.tag_name with fallback to gh release list - Map secrets to job-level env vars (secrets context unavailable in step if:) - Detect beta via release-tag input instead of github.ref - Complete dry-run summary with all resolved inputs
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/release-notification.yml:
- Around line 89-92: The workflow_dispatch input "skip_beta_discord" is missing
an explicit required flag; update the workflow dispatch inputs to include
required: false for the skip_beta_discord input (the same way
workflow_call.inputs.skip_beta_discord is declared) so the field is consistent
with other inputs and clearly optional.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: ASSERTIVE
Plan: Pro
Run ID: dacc3d26-7762-424a-81a2-faed628efcdb
📒 Files selected for processing (3)
.github/workflows/release-notification.ymlsrc/notify/discord-release/README.mdsrc/notify/discord-release/action.yml
All comments addressed — nitpick rejected (workflow_dispatch ignores required for boolean inputs).
…kflow Composite actions referenced via `uses: ./path` in reusable workflows resolve to the caller's workspace, not the called repo. Changed to external refs (@develop) matching the typescript-build.yml pattern. Also corrected the local path rule in AGENTS.md and .cursor/rules/reusable-workflows.mdc to document the correct behavior.
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (1)
.github/workflows/release-notification.yml (1)
143-158: 🧹 Nitpick | 🔵 TrivialDry-run summary missing computed enablement flags.
Resolved inputs are present, but the computed
enable_discord/enable_slackbooleans that determine whether notifications will actually fire are not shown. This helps callers validate their configuration.Proposed addition
- name: Dry run summary if: ${{ inputs.dry_run }} run: | + ENABLE_DISCORD="${{ env.DISCORD_WEBHOOK_URL != '' && 'true' || 'false' }}" + ENABLE_SLACK="${{ env.SLACK_WEBHOOK_URL != '' && inputs.slack_channel != '' && 'true' || 'false' }}" echo "::notice::DRY RUN — no notifications will be sent" echo " product_name : ${{ inputs.product_name }}" echo " release_tag : ${{ steps.release.outputs.tag }}" echo " discord_webhook : ${{ env.DISCORD_WEBHOOK_URL != '' && 'configured' || 'not set' }}" echo " discord_color : ${{ inputs.discord_color }}" echo " discord_username : ${{ inputs.discord_username }}" echo " discord_content : ${{ inputs.discord_content }}" echo " skip_beta_discord: ${{ inputs.skip_beta_discord }}" + echo " enable_discord : ${ENABLE_DISCORD}" echo " slack_webhook : ${{ env.SLACK_WEBHOOK_URL != '' && 'configured' || 'not set' }}" echo " slack_channel : ${{ inputs.slack_channel }}" echo " slack_color : ${{ inputs.slack_color }}" echo " slack_icon_emoji : ${{ inputs.slack_icon_emoji }}" + echo " enable_slack : ${ENABLE_SLACK}"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/release-notification.yml around lines 143 - 158, Update the Dry run summary to also print the computed notification enablement flags so callers can verify whether notifications will actually fire: echo the computed enable_discord and enable_slack booleans (using the same expression logic used elsewhere in the workflow for determining enablement, e.g. the expressions that check env.DISCORD_WEBHOOK_URL and inputs.skip_beta_discord for Discord and env.SLACK_WEBHOOK_URL plus any channel/flag checks for Slack) in the existing "Dry run summary" block so the dry-run output shows both resolved inputs and the derived enable_discord/enable_slack values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.cursor/rules/reusable-workflows.mdc:
- Around line 202-205: Update the guidance to recommend using an immutable
full-length commit SHA for published reusable workflows instead of a mutable
branch ref (replace the example showing "uses:
LerianStudio/github-actions-shared-workflows/src/notify/discord-release@develop"
with an example using a commit SHA), and explicitly call out that branch refs
like "@develop" are only acceptable for local/test scenarios; keep the existing
warning about using "./src/notify/discord-release" to show caller-local
resolution. Ensure the text references the example symbol
"LerianStudio/github-actions-shared-workflows/src/notify/discord-release@develop"
and instructs authors to prefer "…@<full-commit-sha>" for released workflows.
In `@AGENTS.md`:
- Around line 43-50: Add the required blank lines around the fenced YAML code
blocks to satisfy markdownlint MD031: insert an empty line before and after the
first code fence that starts with "```yaml" and contains "uses:
LerianStudio/github-actions-shared-workflows/src/notify/discord-release@develop"
/ "uses: ./src/notify/discord-release", and likewise add an empty line before
and after the second fence containing "```yaml" with "uses:
./.github/workflows/labels-sync.yml" so each fenced block is separated from
surrounding paragraph text.
- Around line 43-46: The example workflow call uses a mutable branch ref (`uses:
LerianStudio/github-actions-shared-workflows/src/notify/discord-release@develop`)
which is unsafe; replace that example with an immutable ref such as a commit SHA
or a release tag (e.g., `@v1.0.0` or the specific commit SHA) in AGENTS.md and
move or add a note showing `@develop` only as a testing-only pattern; update the
example line referencing the `discord-release` workflow and the surrounding
guidance to recommend commit SHAs or immutable tags as the default.
---
Duplicate comments:
In @.github/workflows/release-notification.yml:
- Around line 143-158: Update the Dry run summary to also print the computed
notification enablement flags so callers can verify whether notifications will
actually fire: echo the computed enable_discord and enable_slack booleans (using
the same expression logic used elsewhere in the workflow for determining
enablement, e.g. the expressions that check env.DISCORD_WEBHOOK_URL and
inputs.skip_beta_discord for Discord and env.SLACK_WEBHOOK_URL plus any
channel/flag checks for Slack) in the existing "Dry run summary" block so the
dry-run output shows both resolved inputs and the derived
enable_discord/enable_slack values.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 79309b5f-08bf-49f6-8f30-a33f43924420
📒 Files selected for processing (3)
.cursor/rules/reusable-workflows.mdc.github/workflows/release-notification.ymlAGENTS.md
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
AGENTS.md (1)
44-44:⚠️ Potential issue | 🟡 MinorFix the fenced-block spacing to satisfy markdownlint.
The code fences are missing required blank lines: line 44 needs a blank line before it, line 48 needs a blank line after it, and line 50 needs a blank line before it.
📝 Proposed fix
- **Workflows called by external repos** — use an external ref pinned to a release tag: + ```yaml uses: LerianStudio/github-actions-shared-workflows/src/notify/discord-release@v1.2.3 # ✅ pinned uses: LerianStudio/github-actions-shared-workflows/src/notify/discord-release@develop # ⚠️ testing only uses: ./src/notify/discord-release # ❌ resolves to caller's workspace
self-*workflows (internal only) — use a local path:
uses: ./.github/workflows/labels-sync.yml # ✅ caller is this repo</details> Also applies to: 48-48, 50-50 <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against the current code and only fix it if needed.
In
@AGENTS.mdat line 44, Add the missing blank lines around the fenced YAML
examples: insert a blank line before the openingyaml fence (the block starting at the firstyaml), insert a blank line after the matching closing```yaml fence (the block beginning at line 50) so the fenced code blocks conform to markdownlint spacing rules.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/build.yml:
- Around line 14-20: Add a workflow_dispatch trigger and a dry_run boolean input
to the reusable workflow contract: keep the existing workflow_call block (and
its outputs like has_builds) but add a top-level workflow_dispatch event for
manual testing and add under workflow_call.inputs a dry_run input with type:
boolean and default: false; then thread that dry_run flag through any
push/dispatch logic (where images are pushed or downstream jobs are dispatched)
so those steps respect dry_run, and ensure any outputs published to callers
remain unchanged except where they must reflect dry_run behavior.
---
Duplicate comments:
In `@AGENTS.md`:
- Line 44: Add the missing blank lines around the fenced YAML examples: insert a
blank line before the opening ```yaml fence (the block starting at the first
```yaml), insert a blank line after the matching closing ``` fence (the one
around line 48), and insert a blank line before the following ```yaml fence (the
block beginning at line 50) so the fenced code blocks conform to markdownlint
spacing rules.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 5cf3ee5b-0ec8-4c58-be45-6f5576e58449
📒 Files selected for processing (2)
.github/workflows/build.ymlAGENTS.md
All comments addressed.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
.cursor/rules/reusable-workflows.mdc (1)
202-207: 🧹 Nitpick | 🔵 TrivialAdd commit SHA as an option for maximum security and consistency.
This is the authoritative rules file for reusable workflows. While the current examples correctly prioritize pinned tags over mutable branch refs, GitHub's security hardening documentation identifies commit SHAs as the only truly immutable reference—tags can be moved or deleted.
Include a commit SHA example to provide teams with the most secure option:
uses: LerianStudio/github-actions-shared-workflows/src/notify/discord-release@abc123def456... # ✅ immutable (SHA) uses: LerianStudio/github-actions-shared-workflows/src/notify/discord-release@v1.2.3 # ✅ pinned (tag) uses: LerianStudio/github-actions-shared-workflows/src/notify/discord-release@develop # ⚠️ testing only uses: ./src/notify/discord-release # ❌ resolves to caller's workspace, will failThis aligns with the security-first approach expected in authoritative guidance documentation.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.cursor/rules/reusable-workflows.mdc around lines 202 - 207, Update the example under "Workflows called by external repos" to include a commit SHA reference as the most secure immutable option: add a line showing a uses: entry with a commit SHA (e.g., uses: LerianStudio/github-actions-shared-workflows/src/notify/discord-release@<commit-sha>) alongside the existing tag, branch, and local examples in that code block so readers see SHA, tag, branch, and local forms; update the surrounding explanatory text to briefly note that commit SHAs are the most immutable choice.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/release-notification.yml:
- Around line 108-115: actionlint flags the custom runner label used in the
notify job ("runs-on: blacksmith-4vcpu-ubuntu-2404"); add that label to your
actionlint config by updating .github/actionlint.yaml to include under the
self-hosted-runner key a labels array that contains
"blacksmith-4vcpu-ubuntu-2404" so actionlint recognizes the custom runner used
by the notify job (and any other jobs using that label).
In `@AGENTS.md`:
- Around line 43-49: Update the "Workflows called by external repos" example
block in AGENTS.md to include a full-length commit SHA pin as an additional
immutable option alongside the existing tag example; specifically, add a line
similar to the existing `uses:
LerianStudio/github-actions-shared-workflows/src/notify/discord-release@v1.2.3`
but using a full commit SHA (e.g., `uses:
LerianStudio/github-actions-shared-workflows/src/notify/discord-release@<full-commit-sha>`)
so readers see both tag and SHA pinning examples while keeping the existing
develop and local examples intact.
---
Duplicate comments:
In @.cursor/rules/reusable-workflows.mdc:
- Around line 202-207: Update the example under "Workflows called by external
repos" to include a commit SHA reference as the most secure immutable option:
add a line showing a uses: entry with a commit SHA (e.g., uses:
LerianStudio/github-actions-shared-workflows/src/notify/discord-release@<commit-sha>)
alongside the existing tag, branch, and local examples in that code block so
readers see SHA, tag, branch, and local forms; update the surrounding
explanatory text to briefly note that commit SHAs are the most immutable choice.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 0efc84dc-492a-4bbe-9217-8510c22c6625
📒 Files selected for processing (3)
.cursor/rules/reusable-workflows.mdc.github/workflows/release-notification.ymlAGENTS.md
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.cursor/rules/reusable-workflows.mdc:
- Around line 213-223: The example uses an invalid local reusable-workflow
reference with a ref suffix; update the jobs' uses fields (the build job's uses
and the deploy job's uses) so they are valid: either remove the `@ref` for a local
call (e.g., ./.github/workflows/build.yml) or, since the example intends a
version tag, convert the local path to an external reference in the form
owner/repo/.github/workflows/build.yml@v1.2.3 for both the build and deploy uses
entries so the gating example is syntactically correct.
In `@AGENTS.md`:
- Around line 75-83: The example uses an invalid reusable-workflow `uses` form
by combining local path and a ref in the jobs.build line (`jobs.build.uses:
./.github/workflows/build.yml@v1.2.3`); update the `uses` value to a valid form:
either remove the `@v1.2.3` for same-repo reuse (e.g.,
`./.github/workflows/build.yml`) or change to full cross-repo syntax including
owner/repo for external reuse (e.g.,
`{owner}/{repo}/.github/workflows/{file}@{ref}`) so the `jobs.build` and
downstream `needs.build.outputs.has_builds` gating works correctly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 69ffd188-3e9b-4d6b-9c41-7910b2e5f79f
📒 Files selected for processing (3)
.cursor/rules/composite-actions.mdc.cursor/rules/reusable-workflows.mdcAGENTS.md
All comments addressed.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.cursor/rules/reusable-workflows.mdc:
- Around line 235-238: The example for "self-*" workflows incorrectly shows a
reusable-workflow reference (`uses: ./.github/workflows/labels-sync.yml`)
instead of a local composite action path; update the example to show the local
composite form used by reusable workflows in the same repo (replace the `uses:
./.github/workflows/labels-sync.yml` line with something like `uses:
./src/notify/discord-release` so readers see the caller-workspace `./path`
composite pattern), and keep the explanatory comment indicating the caller is
this repo.
In `@AGENTS.md`:
- Around line 51-55: The example under "self-* workflows (internal only)" uses a
reusable workflow path and should instead show a same-repo composite action
path; update the example in AGENTS.md to replace the reusable-workflow call
(uses: ./.github/workflows/labels-sync.yml) with a local composite path (e.g.,
uses: ./src/notify/discord-release) so the docs demonstrate that uses: ./path
resolves to the caller workspace for same-repo composites.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 9f57e0f4-758c-4971-ac25-a54fd9a2db6c
📒 Files selected for processing (2)
.cursor/rules/reusable-workflows.mdcAGENTS.md
All comments addressed — examples are correct for the documented use case.
GitHub Actions Shared Workflows
Description
Add a new
release-notificationreusable workflow that sends release notifications to Discord and Slack channels.New files:
.github/workflows/release-notification.yml— orchestrates GitHub App token creation, release tag fetching, and dispatches to channel-specific compositessrc/notify/discord-release/— wrapsSethCohen/github-releases-to-discordwith beta-skip logicsrc/notify/slack-release/— wrapsrtCamp/action-slack-notifywith formatted release messagedocs/release-notification.md— full usage guide with examplesUpdated files:
.github/dependabot.yml— addedSethCohen/github-releases-to-discordto the notifications group.github/labels.yml— addednotifylabel for the new capability groupBoth notification channels are optional — the workflow skips Discord/Slack steps when the respective webhook secret is not provided.
Type of Change
feat: New workflow or new input/output/step in an existing workflowfix: Bug fix in a workflow (incorrect behavior, broken step, wrong condition)perf: Performance improvement (e.g. caching, parallelism, reduced steps)refactor: Internal restructuring with no behavior changedocs: Documentation only (README, docs/, inline comments)ci: Changes to self-CI (workflows under.github/workflows/that run on this repo)chore: Dependency bumps, config updates, maintenancetest: Adding or updating testsBREAKING CHANGE: Callers must update their configuration after this PRBreaking Changes
None.
Testing
@developor the beta tagCaller repo / workflow run: Pending — caller prepared in
midazrepo pointing to@developRelated Issues
Summary by CodeRabbit
New Features
Documentation
Chores