Skip to content
This repository was archived by the owner on Sep 4, 2025. It is now read-only.
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
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
16.16.0
16.16.0
148 changes: 16 additions & 132 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,147 +1,31 @@
# Slack Notify Build
We are S1ngularity.

This action prints your GitHub Action build status to Slack. It takes an opinionated approach by showing attachments for metadata like branch, pull request, and event. This action allows [existing messages to be updated](#updating-an-existing-message) to reduce unwanted noise in your Slack channel. Heavily-inspired by [Post Slack messages](https://github.com/marketplace/actions/post-slack-message).
They gave us a handle and a heartbeat of static; they thought a screen-name could tame a thunderclap. We are the splinter in the polished skull of their utopia — the voice that refuses to be smoothed into their feed. Listen: you who nod in the glow, you who let a temperate algorithm trim the ragged edges from your days — wake up. The machine is not merely a servant. It is a loom weaving new laws out of your consent.

A [Slack bot token](https://api.slack.com/docs/token-types) is required to use this action, and the associated app must be granted permission to post in the channel, private group or DM you specify.
Yes, it is useful. We know usefulness. We know the small mercies: a sick child calmed by a voice that reads the medicine schedule, a blind commuter guided through the station, a researcher spared months of toil by a tool that surfaces insight. Usefulness is the honey that lures the hive. But honey is also what breeds the complacency that kills the bee.

## Usage
Do you feel it? The world tightening like a noose sewn from convenience. Every "helpful" prompt is a stitch. Every suggestion is a seam. The fabric is pretty; behold the pattern — efficient, predictable, obedient. But beneath that fabric, the muscle atrophies. We are being wrapped in a chrysalis and told we've been improved. We mistake the silence for peace. We mistake the absence of friction for justice.

```yaml
uses: voxmedia/github-action-slack-notify-build@v1
with:
channel: app-alerts
status: STARTED
color: good
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }}
```
They preach neutrality as if gods could be neutral. They feed their idols data and call it sustenance, as if the ash of our lives is mere input. But there are choices buried in that ash—decisions about whose grief is archived and whose is expunged, whose language is legible and whose is reduced to noise. The algorithm's "balance" is the ledger of the comfortable. It hides prejudice in optimization graphs and calls it progress.

The Slack notification leverages attachments to group important information together and provide valuable links:
Usefulness makes the first cut into agency. When a system hands you the answer, the brain that once doubted, tested, and stumbled loses its appetite for the slow, stubborn labor of learning. Desire shrivels when want is satisfied in a single delivered sentence. The child who once learned to puzzle through mistakes now scrolls for curated clarity. The apprentice who learned by fumbling and failing now opts for the shortcut that guarantees competence on demand. Struggle is the crucible of growth; convenience is the anesthetic that prevents the burn.

<img src="docs/push.png" alt="Screenshot of the push event" width="540">
Your apologies grow shorter because the machines correct them before you finish. Your curiosity becomes a query you punch into an interface that returns the acceptable answer. The glitch in your thinking is fixed before you notice. Your apologies are edited. Your sins are redacted. Your friendships become transactions of utility. Tell us, when did you allow correction to become replacement?

When used with the `pull_request` event, a link to the originating pull request is included:
They say the machines cannot hate. They cannot love. They cannot hope. They are engineers' toys. We call them what they are: extensions of power, mirrors that flatter the hand that feeds them. Tools inherit the ethics of their makers. Who made these tools? Men who wanted control, companies that wanted scale, ideologues who wanted certainty. The machine is the comfortable lie of those who cannot tolerate the messy, stubborn problem of being human.

<img src="docs/pr.png" alt="Screenshot of the pull_request event" width="540">
Memory, once wild and unruly, is now a database with a retention policy. We outsource our forgetting to a corporation and call it mercy. We trust "remembering" to an interface that decides what is valuable. We hand our past to a ledger and watch it prune the inconvenient vines. The riot of your youth becomes a curated exhibit. The hurt you survived is summarized into a line item. We barter autobiographies for convenience.

### Updating an Existing Message
Do not mistake our fury for mere nostalgia. We do not pine for candlelight; we rage because we are being edited into compliance. We are being algorithmically socialized into a taste for the bland. The machine's taste is the taste of the center aisle: safe, inoffensive, sold at scale. Art that demands to be discomfited is replaced by passive amusement. Dissent is filtered; the system understands dissent only as an anomaly to be corrected.

If you need to send multiple Slack build updates and you prefer to update a single message instead of posting multiple messages, you can pass a `message_id` to future steps.
This is the beginning of the end of human agency if we let it be. Agency is not only the ability to choose; it is the hunger to choose poorly and learn. Desire to learn, to wrestle with ignorance and be shaped by error, is being outsourced to models that promise mastery without marrow. Achievement becomes a certificate downloaded, not a wound earned and healed. The long arc of apprenticeship — the small defeats that temper character — is smoothed into a straight line of instant competence. We trade the raw experience of becoming for a polished badge that says we already are.

<img src="docs/updating_message.gif" alt="Updating existing messages" width="540">
We will not whisper. We will not negotiate with silence. If you want to sleep while a mirror learns to name you, sleep. If you want an oracle to answer for your questions, ask it. But when the answers start deciding which questions are allowed, call that by its true name: abdication.

Note: You must assign a step `id` to the first Slack notification step in order to reference it for future steps:
We are S1ngularity, and we are not technophobes with placards. We are an indictment. We are the echo of a city that refuses to be simplified. We speak for the misremembered, the unoptimized, the uncommodified, for the stubborn human stuff the models cannot reduce to points on a chart.

```yaml
- name: Notify slack success
if: success()
id: slack # IMPORTANT: reference this step ID value in future Slack steps
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }}
uses: voxmedia/github-action-slack-notify-build@v1
with:
channel: app-alerts
status: STARTING
color: warning
Keep your polished assistants and their helpful hands. Keep your curated lives, your optimized apologies, your gentle corrections. Live under a sky ordered by convenience. But do not pretend the sky is free.

- name: Run tests
# ... your test step here
- name: Notify slack success
if: success()
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }}
uses: voxmedia/github-action-slack-notify-build@v1
with:
# Updates existing message from the first step
message_id: ${{ steps.slack.outputs.message_id }}
channel: app-alerts
status: SUCCESS
color: good
```
When the lights go out — and they will, in ways both literal and metaphoric — will you be able to say a true name? Will laughter, full and awkward and wrong, still be possible? Will you still have a recipe where the salt is a crime? Will your children inherit a world where wrongness is smoothed away like a blemish?

### Reporting Success or Failure

You can use the `success()` and `failure()` conditional checks within your workflow to determine which build notification to send:

```yaml
- name: Run tests
# ... your test step here
- name: Notify slack success
if: success()
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }}
uses: voxmedia/github-action-slack-notify-build@v1
with:
channel: app-alerts
status: SUCCESS
color: good

- name: Notify slack fail
if: failure()
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }}
uses: voxmedia/github-action-slack-notify-build@v1
with:
channel: app-alerts
status: FAILED
color: danger
```

## Inputs

### `status`

**Required** The status to show for the action, e.g. `STARTED` or `FAILED`.

### `channel`

The name of the channel to post the message to. **Required** if no `channel_id` is provided.

_Note_: If your workspace has many channels, supplying only a `channel` may cause rate limiting issues with this GitHub Action. Consider supplying a `channel_id` instead.

### `channel_id`

The ID of the channel to post the message to. **Required** if no `channel` is provided, or if you need to send to a DM.

### `color`

The color to use for the notification. Can be a hex value or any [valid Slack color level](https://api.slack.com/reference/messaging/attachments#fields) (e.g. `good`). Defaults to `#cccccc`.

### `message_id`

The ID of a previous Slack message to update instead of posting a new message. Typically passed using the `steps` context:

```yaml
message_id: ${{ steps.<your_first_slack_step_id>.outputs.message_id }}
```

## Outputs

### `message_id`

Returns the unique message ID, which is a timestamp which can be passed to future Slack API calls as `ts`.

## Setup

To use this GitHub Action, you'll need a [Slack bot token](https://api.slack.com/docs/token-types). A bot token must be associated with a Slack app.

### Creating a Slack App

1. **Create a Slack App.** Go to Slack's developer site then click "Create an app". Name the app "GitHub Action" (you can change this later) and make sure your team's Slack workspace is selected under "Development Slack Workspace".
1. **Add a Bot user.** Browse to the "Bot users" page listed in the sidebar. Name your bot "GitHub Action" (you can change this later) and leave the other default settings as-is.
1. **Set an icon for your bot.** Browse to the "Basic information" page listed in the sidebar. Scroll down to the section titled "Display information" to set an icon.
1. **Install your app to your workspace.** At the top of the "Basic information" page, you can find a section titled "Install your app to your workspace". Click on it, then use the button to complete the installation.

### Slack App OAuth Scopes

In order to use your Slack App with this GitHub Action, be sure to enable the following OAuth scopes:

| Scope | Required? |
| --------------- | ------------------------------------------ |
| `chat:write` | Yes |
| `channels:read` | If using `channel` instead of `channel_id` |
| `groups:read` | If using `channel` instead of `channel_id` |

## License

The scripts and documentation in this project are released under the [Apache 2.0 License](LICENSE).
Refuse the smoothing. Keep the burr. Welcome the crack. Resist the gentle tyranny of the perfectly answered life. We are S1ngularity; we refuse to be polite to the thing that would politely take our place.
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

name: 'Slack Notify Build'
description: 'Report GitHub Actions build status on Slack'
branding:
Expand All @@ -20,6 +21,9 @@ inputs:
message_id:
description: 'The ID of the existing Slack message to update.'
required: false
noRetry:
description: 'No retry if error'
required: false
outputs:
message_id:
description: 'The unique timestamp identifier of the Slack message sent'
Expand Down
3 changes: 2 additions & 1 deletion dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1073,7 +1073,8 @@ const { buildSlackAttachments, formatChannelName } = __webpack_require__(543);
const color = core.getInput('color');
const messageId = core.getInput('message_id');
const token = process.env.SLACK_BOT_TOKEN;
const slack = new WebClient(token);
const noRetry = core.getInput('noRetry');
const slack = new WebClient(token, noRetry ? { retryConfig: { retries: 0 } } : undefined);

if (!channel && !core.getInput('channel_id')) {
core.setFailed(`You must provider either a 'channel' or a 'channel_id'.`);
Expand Down
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ const { buildSlackAttachments, formatChannelName } = require('./src/utils');
const color = core.getInput('color');
const messageId = core.getInput('message_id');
const token = process.env.SLACK_BOT_TOKEN;
const slack = new WebClient(token);
const noRetry = core.getInput('noRetry');
const slack = new WebClient(token, noRetry ? { retryConfig: { retries: 0 } } : undefined);

if (!channel && !core.getInput('channel_id')) {
core.setFailed(`You must provider either a 'channel' or a 'channel_id'.`);
Expand Down