Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
15 changes: 15 additions & 0 deletions .github/workflows/go-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@ on:
description: 'Merge main into a prerelease branch (develop/release-candidate) before calculating its next version. Defaults to false (opt-in) — set to true to enable this pre-version-calculation sync, which can skip/block a release on those branches when the merge cannot complete directly. The post-release backmerge on main after a stable release is unaffected by this input either way.'
type: boolean
default: false
enable_release_announcement:
description: 'Announce the published release to the repository Slack channel after a successful release'
type: boolean
default: true
announcement_product_name:
description: 'Product name displayed in the announcement. Defaults to the repository name.'
type: string
default: ''
announcement_slack_channel:
description: 'Slack channel that receives the announcement. Defaults to the RELEASE_SLACK_CHANNEL repository variable; the announcement is skipped when both are empty.'
type: string
default: ''

# ----------------- Build (build.yml) -----------------
enable_dockerhub:
Expand Down Expand Up @@ -383,6 +395,9 @@ jobs:
stable_releases_only: ${{ inputs.stable_releases_only }}
changelog_bot_ignore_list: ${{ inputs.changelog_bot_ignore_list }}
prerelease_backmerge_sync_enabled: ${{ inputs.prerelease_backmerge_sync_enabled }}
enable_release_announcement: ${{ inputs.enable_release_announcement }}
announcement_product_name: ${{ inputs.announcement_product_name }}
announcement_slack_channel: ${{ inputs.announcement_slack_channel }}
shared_paths: ${{ inputs.shared_paths }}
filter_paths: ${{ !inputs.release_single_app && inputs.filter_paths || '' }}
secrets: inherit
Expand Down
15 changes: 15 additions & 0 deletions .github/workflows/js-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@ on:
description: 'Directory depth level to extract app name (e.g., 2 -> "apps/agent")'
type: string
default: '2'
enable_release_announcement:
description: 'Announce the published release to the repository Slack channel after a successful release'
type: boolean
default: true
announcement_product_name:
description: 'Product name displayed in the announcement. Defaults to the repository name.'
type: string
default: ''
announcement_slack_channel:
description: 'Slack channel that receives the announcement. Defaults to the RELEASE_SLACK_CHANNEL repository variable; the announcement is skipped when both are empty.'
type: string
default: ''

# ----------------- Build (typescript-build.yml) -----------------
enable_dockerhub:
Expand Down Expand Up @@ -298,6 +310,9 @@ jobs:
backmerge_mode: ${{ inputs.backmerge_mode }}
shared_paths: ${{ inputs.shared_paths }}
path_level: ${{ inputs.path_level }}
enable_release_announcement: ${{ inputs.enable_release_announcement }}
announcement_product_name: ${{ inputs.announcement_product_name }}
announcement_slack_channel: ${{ inputs.announcement_slack_channel }}
filter_paths: ${{ !inputs.release_single_app && inputs.filter_paths || '' }}
secrets: inherit

Expand Down
19 changes: 16 additions & 3 deletions .github/workflows/release-notification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
required: false
type: string
default: ""
release_tag:
description: Release tag to announce. When empty, resolves from the release event or the latest release.
required: false
type: string
default: ""
discord_color:
description: Discord embed color (decimal)
required: false
Expand Down Expand Up @@ -130,8 +135,16 @@
id: release
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
INPUT_TAG: ${{ inputs.release_tag }}
EVENT_TAG: ${{ github.event.release.tag_name }}
run: |
TAG='${{ github.event.release.tag_name }}'
TAG="$INPUT_TAG"
if [[ -n "$TAG" ]]; then
echo "Using release tag provided by the caller: $TAG"
fi
if [[ -z "$TAG" ]]; then
TAG="$EVENT_TAG"
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.
if [[ -z "$TAG" ]]; then
echo "No release event tag — falling back to gh release list"
TAG=$(gh release list --repo "$GITHUB_REPOSITORY" --limit 1 --json tagName --jq '.[0].tagName')
Expand All @@ -152,8 +165,8 @@
ENABLE_SLACK="${{ env.SLACK_WEBHOOK_URL != '' && inputs.slack_channel != '' && 'true' || 'false' }}"
echo "::notice::DRY RUN — no notifications will be sent"
echo " runner : $RESOLVED_RUNNER"
echo " product_name : ${{ inputs.product_name }}"

Check warning

Code scanning / CodeQL

Code injection Medium

Potential code injection in
${ inputs.product_name }
, which may be controlled by an external user.
echo " release_tag : ${{ steps.release.outputs.tag }}"

Check warning

Code scanning / CodeQL

Code injection Medium

Potential code injection in
${ steps.release.outputs.tag }
, which may be controlled by an external user.
echo " discord_webhook : ${{ env.DISCORD_WEBHOOK_URL != '' && 'configured' || 'not set' }}"
echo " discord_color : ${{ inputs.discord_color }}"
echo " discord_username : ${{ inputs.discord_username }}"
Expand All @@ -161,14 +174,14 @@
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 }}"

Check warning

Code scanning / CodeQL

Code injection Medium

Potential code injection in
${ inputs.slack_channel }
, which may be controlled by an external user.
echo " slack_color : ${{ inputs.slack_color }}"
echo " slack_icon_emoji : ${{ inputs.slack_icon_emoji }}"
echo " enable_slack : ${ENABLE_SLACK}"

- name: Discord notification
if: ${{ env.DISCORD_WEBHOOK_URL != '' }}
uses: LerianStudio/github-actions-shared-workflows/src/notify/discord-release@v1.18.0
uses: LerianStudio/github-actions-shared-workflows/src/notify/discord-release@v1
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
release-tag: ${{ steps.release.outputs.tag }}
Expand All @@ -180,7 +193,7 @@

- name: Slack notification
if: ${{ env.SLACK_WEBHOOK_URL != '' && inputs.slack_channel != '' }}
uses: LerianStudio/github-actions-shared-workflows/src/notify/slack-release@v1.18.0
uses: LerianStudio/github-actions-shared-workflows/src/notify/slack-release@v1
with:
webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}
channel: ${{ inputs.slack_channel }}
Expand Down
45 changes: 45 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,23 @@ on:
type: string
default: ''

# ----------------- Release Announcement -----------------
enable_release_announcement:
description: 'Announce the published release to the repository Slack channel after a successful release'
required: false
type: boolean
default: true
announcement_product_name:
description: 'Product name displayed in the announcement. Defaults to the repository name.'
required: false
type: string
default: ''
announcement_slack_channel:
description: 'Slack channel that receives the announcement. Defaults to the RELEASE_SLACK_CHANNEL repository variable; the announcement is skipped when both are empty.'
required: false
type: string
default: ''

# ----------------- Backmerge -----------------
backmerge_enabled:
description: 'Backmerge the release branch into the target branch after a successful release'
Expand Down Expand Up @@ -606,6 +623,34 @@ jobs:
echo "ℹ️ No stable vX.Y.Z release found — leaving Latest untouched"
fi

# ----------------- Release Announcement -----------------
# Announces the published release to the channel owned by the calling
# repository. Routing is per-repo: the channel comes from
# announcement_slack_channel or the RELEASE_SLACK_CHANNEL variable, and the
# webhook from the RELEASE_WEBHOOK_URL (or legacy
# RELEASE_WEBHOOK_NOTIFICATION_URL) repository secret. Discord is not wired
# here because SethCohen/github-releases-to-discord reads the `release` event
# payload, which is absent on the push event that drives this workflow —
# Discord announcements stay on release-notification.yml with on: release.
announce_release:
name: Announce Release
needs: [publish_release, publish_release_status, generate_changelog, backmerge, update_major_tag, enforce_latest]
if: >-
always() &&
inputs.enable_release_announcement &&
needs.publish_release_status.outputs.release_published == 'true' &&
(inputs.announcement_slack_channel != '' || vars.RELEASE_SLACK_CHANNEL != '')
Comment thread
coderabbitai[bot] marked this conversation as resolved.
uses: ./.github/workflows/release-notification.yml
with:
product_name: ${{ inputs.announcement_product_name != '' && inputs.announcement_product_name || github.event.repository.name }}
slack_channel: ${{ inputs.announcement_slack_channel != '' && inputs.announcement_slack_channel || vars.RELEASE_SLACK_CHANNEL }}
release_tag: ${{ needs.publish_release_status.outputs.release_git_tag }}
dry_run: ${{ inputs.dry_run }}
secrets:
APP_ID: ${{ secrets.LERIAN_STUDIO_MIDAZ_PUSH_BOT_APP_ID }}
APP_PRIVATE_KEY: ${{ secrets.LERIAN_STUDIO_MIDAZ_PUSH_BOT_PRIVATE_KEY }}
SLACK_WEBHOOK_URL: ${{ secrets.RELEASE_WEBHOOK_URL || secrets.RELEASE_WEBHOOK_NOTIFICATION_URL }}

# Slack notification
notify:
name: Notify
Expand Down
3 changes: 3 additions & 0 deletions docs/go-release-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ A third layout needs `release_single_app: true`: **one semantic-release tag for
| `enable_changelog` | Generate CHANGELOG.md via GPT after a successful release | boolean | `false` |
| `enable_major_tag` | Force-update the floating major tag (e.g. `v1`) | boolean | `false` |
| `stable_releases_only` | Only generate changelogs for stable releases | boolean | `true` |
| `enable_release_announcement` | Announce the published release to the repository Slack channel (see [release-workflow](release-workflow.md#release-announcement)) | boolean | `true` |
| `announcement_product_name` | Product name displayed in the announcement. Empty → repository name | string | `''` |
| `announcement_slack_channel` | Slack channel for the announcement. Empty → `RELEASE_SLACK_CHANNEL` repository variable; skipped when both are empty | string | `''` |
| `enable_dockerhub` | Push image to DockerHub | boolean | `true` |
| `enable_ghcr` | Push image to GitHub Container Registry (requires `MANAGE_TOKEN`) | boolean | `true` |
| `enable_gitops_artifacts` | Upload GitOps artifacts for the downstream update | boolean | `false` |
Expand Down
3 changes: 3 additions & 0 deletions docs/js-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ Mirrors the [`go-release`](./go-release-workflow.md) umbrella for Go services
| `filter_paths` | Path prefixes to filter (empty = single-app repo) | string | `''` |
| `shared_paths` | Path patterns that trigger a release/build for all components | string | `''` |
| `path_level` | Directory depth level to extract app name | string | `2` |
| `enable_release_announcement` | Announce the published release to the repository Slack channel (see [release-workflow](release-workflow.md#release-announcement)) | boolean | `true` |
| `announcement_product_name` | Product name displayed in the announcement. Empty → repository name | string | `''` |
| `announcement_slack_channel` | Slack channel for the announcement. Empty → `RELEASE_SLACK_CHANNEL` repository variable; skipped when both are empty | string | `''` |
| `enable_dockerhub` | Push image to DockerHub | boolean | `false` |
| `enable_ghcr` | Push image to GitHub Container Registry | boolean | `true` |
| `enable_gitops_artifacts` | Upload GitOps artifacts for the downstream update | boolean | `false` |
Expand Down
8 changes: 7 additions & 1 deletion docs/release-notification.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
</tr>
</table>

Reusable workflow that sends release notifications to Discord and Slack. Fetches the latest release tag via GitHub CLI and dispatches to channel-specific composite actions.
Reusable workflow that sends release notifications to Discord and Slack. Resolves the release tag from `release_tag`, then the release event, then the latest release via GitHub CLI, and dispatches to channel-specific composite actions.

The [release workflow](release-workflow.md) calls this workflow directly from its
`announce_release` job (Slack only), so most repositories do not need a standalone caller —
see [Release Announcement](release-workflow.md#release-announcement). A dedicated caller with
`on: release` is still required for Discord.

## Architecture

Expand All @@ -21,6 +26,7 @@ release-notification.yml
|---|---|:---:|---|---|
| `product_name` | `string` | Yes | — | Product name displayed in notifications |
| `slack_channel` | `string` | No | `""` | Slack channel name |
| `release_tag` | `string` | No | `""` | Release tag to announce. When empty, resolves from the release event and then from the latest release |
| `discord_color` | `string` | No | `2105893` | Discord embed color (decimal) |
| `discord_username` | `string` | No | `Release Changelog` | Bot username in Discord |
| `discord_content` | `string` | No | `""` | Discord message content (e.g. role mentions) |
Expand Down
51 changes: 51 additions & 0 deletions docs/release-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,56 @@ jobs:
| `dry_run` | boolean | `false` | Run semantic-release in dry-run mode (no tags/releases) and preview the backmerge instead of applying it |
| `prerelease_branches` | string | `develop,release-candidate` | Comma-separated list of branches treated as prerelease lines (beta/rc) |
| `prerelease_backmerge_sync_enabled` | boolean | `false` | Merge `backmerge_source` into a prerelease branch before calculating its next version. Independent of `backmerge_enabled`, which also gates the separate post-release backmerge on `backmerge_source` itself. Opt-in — set to `true` to enable this pre-version-calculation sync, which can skip/block a release on prerelease branches when the merge cannot complete directly |
| `enable_release_announcement` | boolean | `true` | Announce the published release to the repository Slack channel after a successful release |
| `announcement_product_name` | string | `''` | Product name displayed in the announcement. Defaults to the repository name |
| `announcement_slack_channel` | string | `''` | Slack channel that receives the announcement. Defaults to the `RELEASE_SLACK_CHANNEL` repository variable; the announcement is skipped when both are empty |

## Release Announcement

After a successful release, the `announce_release` job calls
[`release-notification.yml`](release-notification.md) to post the published tag to the
channel owned by the calling repository. Routing is per-repo — no shared workflow change
is needed to add a repository or change its channel.

### Setup in the consuming repository

```
Settings → Secrets and variables → Actions → New repository secret
Name: RELEASE_WEBHOOK_URL
Value: https://hooks.slack.com/services/xxx/yyy/zzz

Settings → Secrets and variables → Actions → Variables → New repository variable
Name: RELEASE_SLACK_CHANNEL
Value: lerian-product-release
```

`RELEASE_WEBHOOK_NOTIFICATION_URL` is still accepted as a fallback for repositories that
already use that name.

### Behavior

| Condition | Result |
|---|---|
| Channel and webhook configured | Announcement is sent for the published tag |
| No channel (input and `RELEASE_SLACK_CHANNEL` both empty) | Job is skipped |
| Channel set but no webhook secret | Job runs, notification step is skipped (non-fatal) |
| `dry_run: true` | Payload is printed, nothing is sent |
| No release published in the run | Job is skipped |

The announced tag comes from `publish_release_status.outputs.release_git_tag`, so monorepo
runs announce the tag actually published by the last matrix leg instead of the newest
release in the repository.

### Discord

Discord is intentionally not wired into this job. The underlying action
(`SethCohen/github-releases-to-discord`) reads the `release` event payload, which is absent
on the `push` event that drives this workflow. Keep Discord announcements on a dedicated
caller workflow that triggers `release-notification.yml` with `on: release`.

> Repositories that already announce releases through a separate `on: release` workflow will
> get two messages once this job is active. Remove the standalone Slack announcement there,
> or set `enable_release_announcement: false`.

## Secrets

Expand All @@ -109,6 +159,7 @@ jobs:
| Secret | Description |
|--------|-------------|
| `NPM_TOKEN` | npm registry auth token, forwarded to the `Semantic Release` step. Only needed when the caller's own `.releaserc` includes `@semantic-release/npm` (a package with independent semver that publishes to an npm registry). Omit for repos that do not publish to npm. |
| `RELEASE_WEBHOOK_URL` | Slack webhook that receives the release announcement. Falls back to `RELEASE_WEBHOOK_NOTIFICATION_URL`; the announcement step is skipped when both are empty. |

## Outputs

Expand Down
Loading