Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
d5098bf
feat(sc-30416): add GitHub-to-Slack user mapping generation action
jakeschurch Aug 21, 2025
ebd4585
feat(sc-30416): add support for user mapping file to resolve Slack us…
jakeschurch Aug 21, 2025
618a7b6
feat(sc-30416): add support for user mapping file to resolve Slack us…
jakeschurch Aug 21, 2025
346c9a6
[sc-30416] exec pnpm run package
jakeschurch Aug 21, 2025
0cc19aa
[sc-30416] fmt
jakeschurch Aug 21, 2025
ae30272
[sc-30416] more testing
jakeschurch Aug 21, 2025
bab69f8
[sc-30416] add check
jakeschurch Aug 21, 2025
854a171
[sc-30416] package dist
jakeschurch Aug 21, 2025
8459f1f
refactor: split notify and generateMapping actions, remove mode input
jakeschurch Sep 3, 2025
d4fbe11
refactor(generate-mapping): return raw mapping JSON instead of writin…
jakeschurch Sep 3, 2025
2bf6fc3
docs(readme): document SLACK_GITHUB_MAPPING_RAW for custom GitHub-to-…
jakeschurch Sep 3, 2025
f5a6c80
[sc-30416] docs: fmt
jakeschurch Sep 9, 2025
1430d1c
[sc-30416] add new dist
jakeschurch Sep 9, 2025
15aabd4
[sc-30416] remove print statements
jakeschurch Sep 9, 2025
431b635
[sc-30416] fix for gitattrs
jakeschurch Sep 9, 2025
251c8b8
[sc-30416] fixup
jakeschurch Sep 9, 2025
5ec6eff
refactor: unify github-to-slack mapping shape validation and add type…
jakeschurch Sep 22, 2025
e48f0df
[sc-30416] fixup readme
jakeschurch Sep 22, 2025
2b3500d
fixup|refactor(getMessageAuthorFactory): extract Slack user lookup lo…
jakeschurch Sep 22, 2025
44a8537
[sc-30416] add requested feedback on action input / output names
jakeschurch Sep 22, 2025
efee6c5
[sc-30416] make messageAuthor caching more readable
jakeschurch Sep 22, 2025
d5e06b7
[sc-30416] improve code readability
jakeschurch Sep 22, 2025
e2ab954
[sc-30416] bundle
jakeschurch Sep 22, 2025
9c5dea5
[sc-30416] bug: skip deactivated users
jakeschurch Sep 22, 2025
dc871c3
[sc-30416] remove deleted
jakeschurch Sep 23, 2025
b5eb3a9
[sc-30416] skip adding users to cache if error thrown
jakeschurch Sep 23, 2025
fcede99
[sc-30416] run bundle
jakeschurch Sep 23, 2025
d6f8d7a
Tighten type predicates
namoscato Sep 27, 2025
a43dead
Deepen getSlackUserFromName
namoscato Sep 27, 2025
6d32203
Revert setFailed changes
namoscato Sep 27, 2025
4edb065
Simplify githubToSlackMapping
namoscato Sep 27, 2025
927703b
Fix setFailed handling
namoscato Sep 27, 2025
4732a6a
Handle null githubUserMapping values
namoscato Oct 1, 2025
1663b68
Favor githubUserMapping over withSlackUserId
namoscato Oct 1, 2025
b1f2cb5
Rename entrypoints
namoscato Oct 1, 2025
942c96a
Make SlackClient dependencies optional
namoscato Oct 1, 2025
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
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1 @@
dist/** -diff linguist-generated=true
dist/**/* -diff linguist-generated=true
21 changes: 21 additions & 0 deletions .github/actions/generate-user-mapping/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
name: 'Generate Slack Deploy User Mapping'
description: 'Generate mapping of Slack user details by GitHub username for use in Slack Deploy Pipeline Notifications'
author: 'Fieldguide'
inputs:
github_token:
description: 'Repository GITHUB_TOKEN or personal access token secret'
required: false
default: ${{ github.token }}
github_org:
description: 'GitHub organization name from which members are fetched'
required: true
outputs:
json:
description: 'JSON-serialized mapping of Slack user details by GitHub username'
runs:
using: 'node20'
main: '../../../dist/generateUserMapping/index.js'
branding:
icon: bell
color: purple
164 changes: 119 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,68 +1,76 @@
# Slack Deploy Pipeline Notifications

[![ci](https://github.com/Fieldguide/action-slack-deploy-pipeline/actions/workflows/ci.yml/badge.svg)](https://github.com/Fieldguide/action-slack-deploy-pipeline/actions/workflows/ci.yml)

# Slack Deploy Pipeline Notifications
<img width="524" alt="Slack Deploy Pipeline Notifications example thread" src="https://user-images.githubusercontent.com/847532/230737887-1d18a062-af7f-4c7f-a78c-e604fc9803c2.jpg">

Post [GitHub Action](https://github.com/features/actions) deploy workflow progress notifications to [Slack](https://slack.com/).
## Table of Contents

<br />
- [Features](#features)
- [Slack Notify Workflow](#slack-notify-workflow)
- [Generate User Mapping Workflow](#generate-user-mapping-workflow)
- [Environment Variables](#environment-variables)
- [Inputs](#inputs)
- [Outputs](#outputs)
- [User Mapping](#user-mapping-optional)

<img width="524" alt="Slack Deploy Pipeline Notifications example thread" src="https://user-images.githubusercontent.com/847532/230737887-1d18a062-af7f-4c7f-a78c-e604fc9803c2.jpg">
---

## Features

- Posts summary message at beginning of the deploy workflow, surfacing commit message and author
- Posts a summary message at the beginning of the deploy workflow, surfacing the commit message and author
- Maps GitHub actor to Slack user by full name, mentioning them in the summary message
- Threads intermediate stage completions, sending unexpected failures back to the channel
- Threads intermediate stage completions, notifies the channel of unexpected failures
- Adds summary message reaction to unsuccessful jobs (useful with [Reacji Channeler](https://reacji-channeler.builtbyslack.com/))
- Updates summary message duration at conclusion of the workflow
- Supports `pull_request`, `push`, `release`, `schedule`, and `workflow_dispatch` [event types](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows)
- Updates the summary message with the workflow duration at its conclusion
- Supports [`pull_request`, `push`, `release`, `schedule`, and `workflow_dispatch`](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows) event types

---

## Setup
## Slack Notify Workflow

### Setup

1. [Create a Slack App](https://api.slack.com/apps) for your workspace
1. Under **OAuth & Permissions**, add two Bot Token Scopes:
1. [`chat:write`](https://api.slack.com/scopes/chat:write) to post messages
1. [`chat:write.customize`](https://api.slack.com/scopes/chat:write.customize) to customize messages with GitHub actor
1. [`reactions:write`](https://api.slack.com/scopes/reactions:write) to add summary message error reactions
1. [`users:read`](https://api.slack.com/scopes/users:read) to map GitHub user to Slack user
1. Install the app to your workspace
1. Copy the app's **Bot User OAuth Token** from the **OAuth & Permissions** page
1. [Create a GitHub secret](https://docs.github.com/en/actions/security-guides/encrypted-secrets) with this token, named `SLACK_DEPLOY_BOT_TOKEN`
1. Invite the bot user into the Slack channel you will post messages to (`/invite @bot_user_name`)
1. Click the Slack channel name in the header, and copy its **Channel ID** from the bottom of the dialog

## Usage
2. Under **OAuth & Permissions**, add Bot Token Scopes:
- [`chat:write`](https://api.slack.com/scopes/chat:write) to post messages
- [`chat:write.customize`](https://api.slack.com/scopes/chat:write.customize) to customize messages with GitHub actor
- [`reactions:write`](https://api.slack.com/scopes/reactions:write) to add summary message error reactions
- [`users:read`](https://api.slack.com/scopes/users:read) to map GitHub user to Slack user
3. Install the app to your workspace
4. Copy the app's **Bot User OAuth Token** from the **OAuth & Permissions** page
5. [Create a GitHub secret](https://docs.github.com/en/actions/security-guides/encrypted-secrets) with this token, named `SLACK_DEPLOY_BOT_TOKEN`
6. Invite the bot user into the Slack channel you will post messages to (`/invite @bot_user_name`)
7. Click the Slack channel name in the header, and copy its **Channel ID** from the bottom of the dialog

### Minimal Example

```yaml
name: Deploy

on:
push:
branches:
- main
workflow_dispatch:

# 1. Configure environment variables
env:
SLACK_DEPLOY_BOT_TOKEN: ${{ secrets.SLACK_DEPLOY_BOT_TOKEN }} # required
SLACK_DEPLOY_CHANNEL: 'C040YVCUDRR' # required - replace with your Slack Channel ID
SLACK_DEPLOY_ERROR_REACTION: 'x' # optional emoji name added as non-successful summary message reaction
SLACK_DEPLOY_BOT_TOKEN: ${{ secrets.SLACK_DEPLOY_BOT_TOKEN }}
SLACK_DEPLOY_CHANNEL: 'C040YVCUDRR' # replace with your Slack Channel ID

jobs:
staging:
runs-on: ubuntu-latest
outputs:
slack_ts: ${{ steps.slack.outputs.ts }}
steps:
# 2. Post summary message at the beginning of your workflow
- name: Post to Slack
- name: Post summary message to Slack
uses: Fieldguide/action-slack-deploy-pipeline@v2
id: slack

- name: Deploy to staging
run: sleep 10 # replace with your deploy steps

# 3. Post threaded stage updates throughout
- name: Post to Slack
- name: Post threaded stage update
uses: Fieldguide/action-slack-deploy-pipeline@v2
if: always()
with:
Expand All @@ -76,31 +84,69 @@ jobs:
- name: Deploy to production
run: sleep 5 # replace with your deploy steps

# 4. Post last "conclusion" stage
- name: Post to Slack
- name: Post conclusion to Slack
uses: Fieldguide/action-slack-deploy-pipeline@v2
if: always()
with:
thread_ts: ${{ needs.staging.outputs.slack_ts }}
conclusion: true
```

1. Configure required `SLACK_DEPLOY_BOT_TOKEN` and `SLACK_DEPLOY_CHANNEL` [environment variables](https://docs.github.com/en/actions/learn-github-actions/environment-variables).
1. Use this action at the beginning of your workflow to post a "Deploying" message in your configured channel.
1. As your workflow progresses, use this action with the `thread_ts` input to post threaded replies.
1. Denote the last step with the `conclusion` input to update the initial message's status.
---

## Generate User Mapping Workflow

You can provide a raw mapping of GitHub logins to Slack user details to avoid Slack and GitHub API calls for user mapping. This can be done manually, or generated automatically using the included mapping action.

### Generate Mapping Automatically

Use the included composite action to generate a mapping of Slack users by GitHub login:

```yaml
name: Generate Slack User Mapping
on:
workflow_dispatch:
push:
branches:
- main
env:
SLACK_DEPLOY_BOT_TOKEN: ${{ secrets.SLACK_DEPLOY_BOT_TOKEN }}
SLACK_DEPLOY_CHANNEL: 'C040YVCUDRR' # replace with your Slack Channel ID
jobs:
generate-user-mapping:
runs-on: ubuntu-latest
steps:
- name: Generate user mapping
uses: Fieldguide/action-slack-deploy-pipeline/.github/actions/generate-user-mapping
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
github_org: your-org-name
id: user-mapping

# Use mapping in deploy workflow
- name: Post to Slack
uses: Fieldguide/action-slack-deploy-pipeline@main
id: slack
env:
SLACK_DEPLOY_GITHUB_USERS: ${{ steps.user-mapping.outputs.json }}
```

You can then pass `SLACK_GITHUB_MAPPING_RAW` to your deploy workflow as shown above.

---

## Environment Variables

| variable | description |
| ----------------------------- | --------------------------------------- |
| `SLACK_DEPLOY_BOT_TOKEN` | **Required** Slack bot user OAuth token |
| `SLACK_DEPLOY_CHANNEL` | **Required** Slack channel ID |
| `SLACK_DEPLOY_ERROR_REACTION` | Optional Slack emoji name |
| Variable | Description |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SLACK_DEPLOY_BOT_TOKEN` | **Required** Slack bot user OAuth token |
| `SLACK_DEPLOY_CHANNEL` | **Required** Slack channel ID |
| `SLACK_DEPLOY_ERROR_REACTION` | Optional Slack emoji name |
| `SLACK_DEPLOY_GITHUB_USERS` | Optional: Raw mapping (JSON or YAML) of Slack user details by GitHub login. If set, avoids Slack/GitHub API calls for user mapping. Can be generated automatically using the mapping action. |

## Inputs

| input | description |
| Input | Description |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `thread_ts` | Initial Slack message timestamp ID |
| `conclusion` | `true` denotes last stage |
Expand All @@ -109,6 +155,34 @@ jobs:

## Outputs

| output | description |
| ------ | -------------------------- |
| `ts` | Slack message timestamp ID |
| Output | Description |
| ------------------ | ----------------------------------------------------- |
| `ts` | Slack message timestamp ID |
| `raw_mapping_json` | Raw JSON mapping of Slack user details by GitHub user |

---

## User Mapping (Optional)

To avoid Slack and GitHub API calls for mapping GitHub users to Slack users, you can provide a raw mapping as a JSON or YAML string in the `SLACK_GITHUB_MAPPING_RAW` environment variable. The mapping should be an object keyed by GitHub login, with Slack user details as values. Example:

```json
{
"octocat": {
"slack_user_id": "U12345678",
"username": "Octo Cat",
"icon_url": "https://avatars.slack-edge.com/..."
}
}
```

Or YAML:

```yaml
octocat:
slack_user_id: U12345678
username: Octo Cat
icon_url: https://avatars.slack-edge.com/...
```

You can generate this mapping automatically using the included mapping action, and pass its output to your deploy workflow as `SLACK_GITHUB_MAPPING_RAW`.
2 changes: 1 addition & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ outputs:
description: 'Slack message timestamp ID'
runs:
using: 'node20'
main: 'dist/index.js'
main: 'dist/notifySlack/index.js'
branding:
icon: bell
color: purple
Loading
Loading