Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 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
df40717
Update documentation
namoscato Oct 12, 2025
f6e4e4c
Gracefully handle missing artifact
namoscato Oct 12, 2025
0c4fd2d
Merge branch 'main' of github.com:Fieldguide/action-slack-deploy-pipe…
namoscato Oct 12, 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
137 changes: 137 additions & 0 deletions .github/actions/generate-user-mapping/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Generate Slack Deploy User Mapping

This action generates a mapping of Slack user details by GitHub username for use in [Slack Deploy Pipeline Notifications](../../../README.md). It intends to decouple the user mapping process, dependent on a conservatively rate limited [Slack API method](https://docs.slack.dev/reference/methods/users.list/), from the higher throughput notification action.

## Setup

### GitHub Token

A fine-grained personal access token must be configured as the default `GITHUB_TOKEN` does not include adequate permissions:

1. [Create a fine-grained personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token)
2. Under **Resource owner**, select your GitHub organization
3. Under **Permissions**, select "Members" (read-only)
4. [Create a GitHub secret](https://docs.github.com/en/actions/security-guides/encrypted-secrets) with this token, named `GH_ORG_MEMBERS_TOKEN`

### Slack Token

If you have not already provisioned a Slack Bot Token:

5. [Create a Slack App](https://api.slack.com/apps) for your workspace
6. Under **OAuth & Permissions**, add the [`users:read`](https://api.slack.com/scopes/users:read) Bot Token Scope
7. Copy the app's **Bot User OAuth Token**
8. [Create a GitHub secret](https://docs.github.com/en/actions/security-guides/encrypted-secrets) with this token, named `SLACK_DEPLOY_BOT_TOKEN`

## Usage

In a conventional setup, the user mapping is periodically uploaded as a GitHub workflow artifact and downloaded within deploy workflows.

### Schedule Workflow

Create a [`schedule`](https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#schedule) event-triggered workflow that [uploads](https://github.com/actions/upload-artifact) the generated user mapping as a `slack-deploy-user-mapping.json` [workflow artifact](https://docs.github.com/en/actions/tutorials/store-and-share-data):

```yaml
name: Generate Slack Deploy User Mapping

on:
schedule:
- cron: '0 0 * * *' # midnight UTC

jobs:
generate:
runs-on: ubuntu-latest
steps:
- name: Generate user mapping
uses: Fieldguide/action-slack-deploy-pipeline/.github/actions/generate-user-mapping@v2
id: user-mapping
env:
SLACK_DEPLOY_BOT_TOKEN: ${{ secrets.SLACK_DEPLOY_BOT_TOKEN }}
with:
github_token: ${{ secrets.GH_ORG_MEMBERS_TOKEN }}
github_org: your-org # replace with your GitHub organization name

- name: Write to file
run: |
cat << 'EOF' > slack-deploy-user-mapping.json
${{ steps.user-mapping.outputs.json }}
EOF

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: slack-deploy-user-mapping
path: slack-deploy-user-mapping.json
if-no-files-found: 'error'
retention-days: 2
overwrite: true
```

### Deploy Workflow

In your deploy workflows, [download the artifact](https://github.com/dawidd6/action-download-artifact) and set the `SLACK_DEPLOY_GITHUB_USERS` environment variable before using the [Slack Deploy Pipeline Notifications](../../../README.md) action:

```yaml
name: Deploy

on:
push:
branches:
- main

env:
SLACK_DEPLOY_BOT_TOKEN: ${{ secrets.SLACK_DEPLOY_BOT_TOKEN }}
SLACK_DEPLOY_CHANNEL: 'C040YVCUDRR' # replace with your Slack Channel ID

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Download Slack deploy user mapping artifact
uses: dawidd6/action-download-artifact@v6
with:
workflow: slack_deploy_user_mapping.yaml
name: slack-deploy-user-mapping
if_no_artifact_found: warn

- name: Set Slack deploy user mapping environment variable
if: hashFiles('slack-deploy-user-mapping.json') != ''
run: |
echo "SLACK_DEPLOY_GITHUB_USERS<<EOF" >> $GITHUB_ENV
cat slack-deploy-user-mapping.json >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV

- name: Post to Slack
uses: Fieldguide/action-slack-deploy-pipeline@v2
id: slack

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

- name: Post to Slack
uses: Fieldguide/action-slack-deploy-pipeline@v2
if: always()
with:
thread_ts: ${{ steps.slack.outputs.ts }}
conclusion: true
```

## Configuration

### Environment Variables

| variable | description |
| ------------------------ | --------------------------------------- |
| `SLACK_DEPLOY_BOT_TOKEN` | **Required** Slack bot user OAuth token |

### Inputs

| input | description |
| -------------- | ------------------------------------------------------- |
| `github_token` | GitHub organization personal access token secret |
| `github_org` | GitHub organization name from which members are fetched |

### Outputs

| output | description |
| ------ | ---------------------------------------------------------------- |
| `json` | JSON-serialized mapping of Slack user details by GitHub username |
20 changes: 20 additions & 0 deletions .github/actions/generate-user-mapping/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
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: 'GitHub organization personal access token secret'
required: true
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
55 changes: 40 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@ Post [GitHub Action](https://github.com/features/actions) deploy workflow progre
## Features

- Posts summary message at beginning of the deploy workflow, surfacing commit message and author
- Maps GitHub actor to Slack user by full name, mentioning them in the summary message
- Maps GitHub actor to Slack user by full name or mapping, mentioning them in the summary message
- Threads intermediate stage completions, sending unexpected failures back to the channel
- 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
- Updates summary message with workflow duration at its conclusion
- Supports `pull_request`, `push`, `release`, `schedule`, and `workflow_dispatch` [event types](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows)

## 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. 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
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`
Expand Down Expand Up @@ -90,15 +90,22 @@ jobs:
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.

## Environment Variables
## Configuration

| 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 |
### Environment Variables

## Inputs
Global configuration to be used across all Slack Deploy actions within the workflow.

| 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 mapping](#predefined-user-mapping) of Slack user details by GitHub username in JSON or YAML format |

### Inputs

Optional step-specific input enables threading and denotes the conclusion.

| input | description |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
Expand All @@ -107,8 +114,26 @@ jobs:
| `github_token` | Repository `GITHUB_TOKEN` or personal access token secret; defaults to [`github.token`](https://docs.github.com/en/actions/learn-github-actions/contexts#github-context) |
| `status` | The current status of the job; defaults to [`job.status`](https://docs.github.com/en/actions/learn-github-actions/contexts#job-context) |

## Outputs
### Outputs

| output | description |
| ------ | -------------------------- |
| `ts` | Slack message timestamp ID |

## Slack User Mapping

By default, this GitHub Action attempts to [mention](https://slack.com/help/articles/205240127-Use-mentions-in-Slack) the Slack user corresponding to the GitHub actor by full name. This process depends on a conservatively rate limited [Slack API method](https://docs.slack.dev/reference/methods/users.list/); depending on your deploy throughput, it might fail and gracefully fallback to the GitHub username.

To improve reliability, the action can be provided a predefined user mapping via a `SLACK_DEPLOY_GITHUB_USERS` environment variable. The data should be an object keyed by GitHub username mapped to Slack user detail values in JSON or YAML format.

The data is conventionally JSON generated by the [Generate Slack Deploy User Mapping](./.github/actions/generate-user-mapping/README.md) GitHub Action. However, it can also be provided as inline YAML as in the example below:

```yaml
- uses: Fieldguide/action-slack-deploy-pipeline@v2
env:
SLACK_DEPLOY_GITHUB_USERS: |
namoscato:
slack_user_id: U0411GE5J9J
username: Nick
icon_url: "https://secure.gravatar.com/avatar/d79555502b4c47fc9d31144af55dc3e5.jpg"
```
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