Skip to content
Open
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
13 changes: 13 additions & 0 deletions .github/actions/build-notification/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.DS_Store
.idea
*.log
tmp/

*.tern-port
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
*.tsbuildinfo
.npm
.eslintcache
2 changes: 2 additions & 0 deletions .github/actions/build-notification/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist/
node_modules/
15 changes: 15 additions & 0 deletions .github/actions/build-notification/.prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict'

module.exports = {
printWidth: 80,
tabWidth: 2,
useTabs: false,
semi: false,
singleQuote: true,
jsxSingleQuote: false,
trailingComma: 'es5',
bracketSpacing: true,
jsxBracketSameLine: false,
arrowParens: 'avoid',
endOfLine: 'lf',
}
91 changes: 91 additions & 0 deletions .github/actions/build-notification/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Build Notification

Single entrypoint for oe-core build Slack notifications. Workflows pass context and optionally a `notification_kind`; this action decides whether to send, the payload shape, and which webhook to use.

## Usage

Success notifications run inline in `run-build`:

- **All builds** — `deployed` after artifact upload (tagged → `SLACK_WEBHOOK_ARTIFACTS_DEPLOY_URL_TAGGED`, branch → `SLACK_WEBHOOK_URL`)
- **Tagged builds** — **Build's done!** (`cache-synced`) after S3 cache push via `SLACK_WEBHOOK_URL_TAGGED`

Failure and cancelled notifications run from a separate job at the end of the build workflow.

```yaml
notify-build:
name: Notify Build Outcome
runs-on: ubuntu-latest
needs: [decide-refs, run-build]
if: always() && (needs.run-build.result == 'failure' || needs.run-build.result == 'cancelled')
steps:
- name: Fetch initial sources for action
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
submodules: false
path: ./oe-core-for-workflow
- name: Notify build outcome
uses: ./oe-core-for-workflow/.github/actions/build-notification
continue-on-error: true
with:
workflow: flex-build
notification_kind: auto
event_name: ${{ github.event_name }}
job_result: ${{ needs.run-build.result }}
webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook_url_tagged: ${{ vars.SLACK_WEBHOOK_URL_TAGGED }}
workflow_name: Build Flex image on github workflows
oe_core_ref: ${{ needs.decide-refs.outputs.oe-core }}
monorepo_ref: ${{ needs.decide-refs.outputs.monorepo }}
firmware_ref: ${{ needs.decide-refs.outputs.ot3-firmware }}
variant: ${{ needs.decide-refs.outputs.variant }}
console_url: ${{ needs.run-build.outputs.console_url }}
system_url: ${{ needs.run-build.outputs.system_url }}
fullimage_url: ${{ needs.run-build.outputs.fullimage_url }}
version_file_url: ${{ needs.run-build.outputs.version_file_url }}
release_notes_file_url: ${{ needs.run-build.outputs.release_notes_file_url }}
```

## Webhook routing (build-ot3-actions.yml)

| Step | When | Branch builds | Tagged builds |
| --- | --- | --- | --- |
| Notify artifacts deployed | After S3 artifact upload | `SLACK_WEBHOOK_URL` | `SLACK_WEBHOOK_ARTIFACTS_DEPLOY_URL_TAGGED` |
| Notify build complete | After S3 cache push | skip | `SLACK_WEBHOOK_URL_TAGGED` |
| notify-build (failure/cancelled) | End of workflow | `SLACK_WEBHOOK_URL` | `SLACK_WEBHOOK_URL_TAGGED` |

Each step passes the appropriate URL via `webhook_url` (branch) and `webhook_url_tagged` (tagged). The action picks based on whether `monorepo_ref` starts with `refs/tags/`.

## Routing rules (`flex-build`)

Set `notification_kind` to target a specific alert, or `auto` (default) to derive the kind from `job_result`.

| Condition | Notification | Webhook target |
| --- | --- | --- |
| `event_name != workflow_dispatch` | skip | |
| `notification_kind: deployed`, `job_result == success`, branch build | send `deployed` | `webhook_url` |
| `notification_kind: deployed`, tagged build with non-empty `variant` | send `deployed` | `webhook_url_tagged` (fallback: `webhook_url`) |
| `notification_kind: deployed`, tagged build with empty `variant` | skip | |
| `notification_kind: cache-synced`, tagged build with non-empty `variant`, `job_result == success` | send `cache-synced` | `webhook_url_tagged` (fallback: `webhook_url`) |
| `notification_kind: cache-synced`, branch build | skip | |
| `notification_kind: auto`, `job_result == failure` | send `failure` | tagged or default by ref |
| `notification_kind: auto`, `job_result == cancelled` | send `cancelled` | tagged or default by ref |
| other combinations | skip | |

## Slack Workflow setup

Webhook URLs must be Slack Workflow trigger URLs (not legacy Incoming Webhooks).

| GitHub config | Slack workflow |
| --- | --- |
| `secrets.SLACK_WEBHOOK_URL` | Branch builds — deployed, failure, cancelled |
| `vars.SLACK_WEBHOOK_ARTIFACTS_DEPLOY_URL_TAGGED` | Tagged builds — artifacts available (`status: deployed`) |
| `vars.SLACK_WEBHOOK_URL_TAGGED` | Tagged builds — **Build's done!** after cache sync (`status: cache-synced`), plus failure/cancelled |

## Outputs

| Output | Description |
| --- | --- |
| `sent` | `true` when a webhook POST was made |
| `notification_kind` | `deployed`, `cache-synced`, `failure`, `cancelled`, or `none` |
| `webhook_target` | `tagged`, `default`, or `none` |
| `skip_reason` | Why a notification was skipped |
89 changes: 89 additions & 0 deletions .github/actions/build-notification/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: "Build Notification"
description: "Single entrypoint for Flex build Slack notifications with routing rules."
inputs:
workflow:
description: "Workflow rule set to apply (currently flex-build)."
required: true
default: "flex-build"
event_name:
description: "GitHub event name (for example workflow_dispatch)."
required: true
job_result:
description: "Job result: success, failure, cancelled, or skipped."
required: true
notification_kind:
description: "Notification to evaluate: auto (default), deployed, cache-synced, failure, or cancelled."
required: false
default: "auto"
webhook_url:
description: "Slack incoming webhook for branch builds and fallback."
required: false
default: ""
webhook_url_tagged:
description: "Slack workflow webhook for tagged builds. Falls back to webhook_url when empty."
required: false
default: ""
workflow_name:
description: "Human-readable workflow name for the Slack payload."
required: false
default: ""
workflow_run_url:
description: "Link to the workflow run. Defaults to the current run URL."
required: false
default: ""
failed_jobs:
description: "Comma-separated failed job names (optional)."
required: false
default: ""
oe_core_ref:
description: "oe-core ref."
required: false
default: ""
monorepo_ref:
description: "Monorepo ref."
required: false
default: ""
firmware_ref:
description: "Firmware ref."
required: false
default: ""
variant:
description: "Build variant from decide-refs (internal-release, release, or empty)."
required: false
default: ""
console_url:
description: "S3 console URL."
required: false
default: ""
system_url:
description: "System update zip URL."
required: false
default: ""
fullimage_url:
description: "Full image tar URL."
required: false
default: ""
version_file_url:
description: "Version file URL."
required: false
default: ""
release_notes_file_url:
description: "Release notes file URL."
required: false
default: ""
dry_run:
description: "When true, evaluate routing and build payload but do not POST."
required: false
default: "false"
outputs:
sent:
description: "true when a Slack notification was sent, false when skipped."
notification_kind:
description: "deployed, cache-synced, failure, cancelled, or none."
webhook_target:
description: "tagged, default, or none."
skip_reason:
description: "Why the notification was skipped, empty when sent."
runs:
using: "node24"
main: "dist/index.js"
Loading
Loading