Merge branch 'main' into zimeg-build-node-test-runner

This commit is contained in:
Eden Zimbelman
2026-02-24 13:18:41 -08:00
committed by GitHub
6 changed files with 297 additions and 222 deletions
+21 -7
View File
@@ -18,15 +18,29 @@ Information on setting up and configuring mocked events can be found in [`.githu
### Testing
When testing locally, ensure at least linting and unit tests pass by running `npm test`.
Additionally, sending a PR is highly recommended with every change as there are several GitHub
Actions jobs that execute what are effectively integration tests for this GitHub Action.
Expected behaviors are confirmed with both unit tests and integration tests. Our unit tests run fast without secrets, while integration tests use webhooks and tokens for sending data to Slack across various techniques.
#### Checks on PRs
#### Unit tests
Actions that run the integration tests on PRs from a fork will require approval before running.
These checks use stored secrets so the changes should be reviewed before approving the workflow to
avoid accidentally leaking tokens!
Run the following scripts to confirm tests pass before opening a PR:
```sh
$ npm test # Unit tests
$ npm run lint # Lint and format
$ npm run check # Typecheck
```
The `test.yml` workflow runs these scripts for pull requests and changes to the `main` branch.
#### Integration tests
The `integration.yml` workflow uses this action in interactions with Slack using secrets saved to the `staging` environment.
A PR from a forked branch will fail this workflow until a maintainer reviews the code and [dispatches](https://github.com/slackapi/slack-github-action/actions/workflows/integration.yml) a test run that points to the most recent commit using the following format:
```
pull/<NUMBER>/head
```
### Releasing
+3 -3
View File
@@ -2,7 +2,7 @@
Describe the goal of this PR. Mention any related Issue numbers.
### Requirements (place an `x` in each `[ ]`)
### Requirements <!-- Place an `x` in each `[ ]` -->
* [ ] I've read and understood the [Contributing Guidelines](https://github.com/slackapi/slack-github-action/blob/main/.github/contributing.md) and have done my best effort to follow them.
* [ ] I've read and agree to the [Code of Conduct](https://slackhq.github.io/code-of-conduct).
- [ ] I've read and understood the [Contributing Guidelines](https://github.com/slackapi/slack-github-action/blob/main/.github/contributing.md) and have done my best effort to follow them.
- [ ] I've read and agree to the [Code of Conduct](https://slackhq.github.io/code-of-conduct).
+257
View File
@@ -0,0 +1,257 @@
name: Integration tests
on:
pull_request:
push:
branches:
- main
workflow_dispatch:
inputs:
ref:
description: "The branch, tag, or SHA to checkout"
required: true
jobs:
integration:
name: Run integration tests
runs-on: ubuntu-latest
environment: staging
permissions:
contents: read
steps:
- name: "check: require maintainer approval"
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository
run: |
echo "::error::Integration tests from forked branches require maintainer approval."
echo "::notice::Dispatch a test run at ${{ github.server_url }}/${{ github.repository }}/actions/workflows/integration.yml with ref 'pull/${{ github.event.pull_request.number }}/head'"
exit 1
- name: "build: checkout the latest changes"
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
ref: ${{ inputs.ref || github.event.pull_request.head.sha || github.sha }}
- name: "build: setup the node runtime"
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
cache: npm
cache-dependency-path: package-lock.json
node-version-file: .nvmrc
- name: "build: install the required dependencies"
run: npm ci
- name: "build: package code for distribution"
run: npm run build
- name: "pretest(inputs): save the push event trigger commit URL"
if: github.event_name == 'push'
id: push
run: |
echo "url=$URL" >> "$GITHUB_OUTPUT"
env:
URL: ${{ github.event.head_commit.url }}
- name: "pretest(inputs): save the pull request event trigger URL"
if: github.event_name == 'pull_request'
id: pull_request
run: |
echo "url=$URL" >> "$GITHUB_OUTPUT"
env:
URL: ${{ github.event.pull_request.html_url }}
- name: "pretest(inputs): save the workflow dispatch event trigger commit URL"
if: github.event_name == 'workflow_dispatch'
id: workflow_dispatch
run: |
echo "url=https://github.com/${GITHUB_REPOSITORY}/commit/${INPUT_REF}" >> "$GITHUB_OUTPUT"
env:
INPUT_REF: ${{ inputs.ref }}
- name: "integration(wfb): send a payload to workflow builder via webhook trigger"
id: wfb
uses: ./
with:
errors: true
webhook: ${{ secrets.SLACK_WEBHOOK_TRIGGER }}
webhook-type: webhook-trigger
payload: |
author: ${{ github.event.sender.login }}
channel_id: ${{ secrets.SLACK_CHANNEL_ID }}
event_url: ${{ steps.push.outputs.url || steps.pull_request.outputs.url || steps.workflow_dispatch.outputs.url }}
repo_name: ${{ github.event.repository.full_name }}
status: ${{ job.status }}
- name: "integration(wfb): confirm a payload was sent"
run: test -n "$WFB_OUTPUT_TIME"
env:
WFB_OUTPUT_TIME: ${{ steps.wfb.outputs.time }}
- name: "integration(botToken): post a message to channel"
id: message
uses: ./
with:
errors: true
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
text: ":checkered_flag: Action happens at <https://github.com/${{ github.repository }}>"
- name: "integration(method): confirm a message was posted"
run: test -n "$MESSAGE_OUTPUT_TS"
env:
MESSAGE_OUTPUT_TS: ${{ steps.message.outputs.ts }}
- name: "integration(method): post a message with blocks"
id: blocks
uses: ./
with:
errors: true
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
text: ":eyes: Event received..."
attachments:
- color: "dbab09"
fields:
- title: "Status"
short: true
value: "Processing"
- name: "integration(method): confirm the blocks were posted"
run: test -n "$BLOCKS_OUTPUT_TS"
env:
BLOCKS_OUTPUT_TS: ${{ steps.blocks.outputs.ts }}
- name: "integration(method): post a threaded message"
id: timer
uses: ./
with:
errors: true
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
text: "Started at `${{ steps.blocks.outputs.time }}`"
thread_ts: "${{ steps.blocks.outputs.ts }}"
- name: "integration(incoming): confirm the thread started"
run: test -n "$TIMER_OUTPUT_TIME"
env:
TIMER_OUTPUT_TIME: ${{ steps.timer.outputs.time }}
- name: "integration(method): wait to mock event processing"
run: sleep 3
- name: "integration(method): update the original message"
id: finished
uses: ./
with:
errors: true
method: chat.update
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
ts: "${{ steps.blocks.outputs.ts }}"
text: ":gear: Event processed!"
attachments:
- color: "28a745"
fields:
- title: "Status"
short: true
value: "Completed"
- name: "integration(method): post another threaded message"
id: done
uses: ./
with:
errors: true
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ steps.blocks.outputs.channel_id }}
text: "Finished at `${{ steps.finished.outputs.time }}`"
thread_ts: "${{ steps.timer.outputs.thread_ts }}"
- name: "integration(method): post a file into a channel"
id: file
uses: ./
with:
errors: true
method: files.uploadV2
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel_id: ${{ secrets.SLACK_CHANNEL_ID }}
initial_comment: ":robot_face: The codes exists here"
file: .github/workflows/integration.yml
filename: integration.yml
- name: "integration(method): react to the completed update message"
uses: ./
with:
errors: true
method: reactions.add
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
timestamp: ${{ steps.blocks.outputs.ts }}
name: "tada"
- name: "integration(method): confirm the thread ended"
run: test -n "$DONE_OUTPUT_TIME"
env:
DONE_OUTPUT_TIME: ${{ steps.done.outputs.time }}
- name: "integration(incoming): post a message via incoming webhook"
id: incoming
uses: ./
with:
errors: true
webhook: ${{ secrets.SLACK_INCOMING_WEBHOOK }}
webhook-type: incoming-webhook
payload: |
text: "Incoming webhook test for slack send"
blocks:
- type: section
text:
type: plain_text
text: ":link: A message was received via incoming webhook"
emoji: true
- name: "integration(incoming): confirm a webhook was posted"
run: test -n "$INCOMING_WEBHOOK_OUTPUT_TIME"
env:
INCOMING_WEBHOOK_OUTPUT_TIME: ${{ steps.incoming.outputs.time }}
- name: "integration(incoming): reveal contents of the github payload"
run: echo "$JSON"
env:
JSON: ${{ toJSON(github) }}
- name: "integration(incoming): post a message via payload file"
id: payload_file
uses: ./
with:
errors: true
payload-file-path: ./.github/resources/.slack/incoming-webhook.json
payload-templated: true
webhook: ${{ secrets.SLACK_INCOMING_WEBHOOK }}
webhook-type: incoming-webhook
env:
JOB_STATUS: ${{ job.status }}
ATTACHMENT_COLOR: ${{ (job.status == 'success' && 'good') || (job.status == 'failure' && 'danger') || 'warning' }}
- name: "integration(incoming): confirm a payload file was posted"
run: test -n "$PAYLOAD_FILE_OUTPUT_TIME"
env:
PAYLOAD_FILE_OUTPUT_TIME: ${{ steps.payload_file.outputs.time }}
- name: "chore(health): check up on recent changes to the health score"
uses: slackapi/slack-health-score@d58a419f15cdaff97e9aa7f09f95772830ab66f7 # v0.1.1
with:
codecov_token: ${{ secrets.CODECOV_API_TOKEN }}
github_token: ${{ secrets.GITHUB_TOKEN }}
extension: js
include: src
+2 -199
View File
@@ -1,6 +1,6 @@
name: Tests
on:
pull_request_target: # zizmor: ignore[dangerous-triggers]
pull_request:
push:
branches:
- main
@@ -10,15 +10,14 @@ jobs:
tests:
name: Run tests
runs-on: ubuntu-latest
environment: staging
permissions:
checks: write
contents: read
steps:
- name: "build: checkout the latest changes"
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha }}
- name: "build: setup the node runtime"
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
@@ -48,202 +47,6 @@ jobs:
- name: "build: package code for distribution"
run: npm run build
- name: "pretest(inputs): save the push event trigger commit URL"
if: "contains(github.event_name, 'push')"
id: push
run: |
echo "url=$URL" >> "$GITHUB_OUTPUT"
env:
URL: ${{ github.event.head_commit.url }}
- name: "pretest(inputs): save the pull request event trigger commit URL"
if: "contains(github.event_name, 'pull_request')"
id: pull_request
run: |
echo "url=$URL" >> "$GITHUB_OUTPUT"
env:
URL: ${{ github.event.pull_request.html_url }}
- name: "integration(wfb): send a payload to workflow builder via webhook trigger"
id: wfb
uses: ./
with:
errors: true
webhook: ${{ secrets.SLACK_WEBHOOK_TRIGGER }}
webhook-type: webhook-trigger
payload: |
author: ${{ github.event.sender.login }}
channel_id: ${{ secrets.SLACK_CHANNEL_ID }}
event_url: ${{ steps.push.outputs.url || steps.pull_request.outputs.url }}
repo_name: ${{ github.event.repository.full_name }}
status: ${{ job.status }}
- name: "integration(wfb): confirm a payload was sent"
run: test -n "$WFB_OUTPUT_TIME"
env:
WFB_OUTPUT_TIME: ${{ steps.wfb.outputs.time }}
- name: "integration(botToken): post a message to channel"
id: message
uses: ./
with:
errors: true
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
text: ":checkered_flag: Action happens at <https://github.com/${{ github.repository }}>"
- name: "integration(method): confirm a message was posted"
run: test -n "$MESSAGE_OUTPUT_TS"
env:
MESSAGE_OUTPUT_TS: ${{ steps.message.outputs.ts }}
- name: "integration(method): post a message with blocks"
id: blocks
uses: ./
with:
errors: true
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
text: ":eyes: Event received..."
attachments:
- color: "dbab09"
fields:
- title: "Status"
short: true
value: "Processing"
- name: "integration(method): confirm the blocks were posted"
run: test -n "$BLOCKS_OUTPUT_TS"
env:
BLOCKS_OUTPUT_TS: ${{ steps.blocks.outputs.ts }}
- name: "integration(method): post a threaded message"
id: timer
uses: ./
with:
errors: true
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
text: "Started at `${{ steps.blocks.outputs.time }}`"
thread_ts: "${{ steps.blocks.outputs.ts }}"
- name: "integration(incoming): confirm the thread started"
run: test -n "$TIMER_OUTPUT_TIME"
env:
TIMER_OUTPUT_TIME: ${{ steps.timer.outputs.time }}
- name: "integration(method): wait to mock event processing"
run: sleep 3
- name: "integration(method): update the original message"
id: finished
uses: ./
with:
errors: true
method: chat.update
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
ts: "${{ steps.blocks.outputs.ts }}"
text: ":gear: Event processed!"
attachments:
- color: "28a745"
fields:
- title: "Status"
short: true
value: "Completed"
- name: "integration(method): post another threaded message"
id: done
uses: ./
with:
errors: true
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ steps.blocks.outputs.channel_id }}
text: "Finished at `${{ steps.finished.outputs.time }}`"
thread_ts: "${{ steps.timer.outputs.thread_ts }}"
- name: "integration(method): post a file into a channel"
id: file
uses: ./
with:
errors: true
method: files.uploadV2
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel_id: ${{ secrets.SLACK_CHANNEL_ID }}
initial_comment: ":robot_face: The codes exists here"
file: .github/workflows/test.yml
filename: action.yml
- name: "integration(method): react to the completed update message"
uses: ./
with:
errors: true
method: reactions.add
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
timestamp: ${{ steps.blocks.outputs.ts }}
name: "tada"
- name: "integration(method): confirm the thread ended"
run: test -n "$DONE_OUTPUT_TIME"
env:
DONE_OUTPUT_TIME: ${{ steps.done.outputs.time }}
- name: "integration(incoming): post a message via incoming webhook"
id: incoming
uses: ./
with:
errors: true
webhook: ${{ secrets.SLACK_INCOMING_WEBHOOK }}
webhook-type: incoming-webhook
payload: |
text: "Incoming webhook test for slack send"
blocks:
- type: section
text:
type: plain_text
text: ":link: A message was received via incoming webhook"
emoji: true
- name: "integration(incoming): confirm a webhook was posted"
run: test -n "$INCOMING_WEBHOOK_OUTPUT_TIME"
env:
INCOMING_WEBHOOK_OUTPUT_TIME: ${{ steps.incoming.outputs.time }}
- name: "integration(incoming): reveal contents of the github payload"
run: echo "$JSON"
env:
JSON: ${{ toJSON(github) }}
- name: "integration(incoming): post a message via payload file"
id: payload_file
uses: ./
with:
errors: true
payload-file-path: ./.github/resources/.slack/incoming-webhook.json
payload-templated: true
webhook: ${{ secrets.SLACK_INCOMING_WEBHOOK }}
webhook-type: incoming-webhook
env:
JOB_STATUS: ${{ job.status }}
ATTACHMENT_COLOR: ${{ (job.status == 'success' && 'good') || (job.status == 'failure' && 'danger') || 'warning' }}
- name: "integration(incoming): confirm a payload file was posted"
run: test -n "$PAYLOAD_FILE_OUTPUT_TIME"
env:
PAYLOAD_FILE_OUTPUT_TIME: ${{ steps.payload_file.outputs.time }}
- name: "chore(health): check up on recent changes to the health score"
uses: slackapi/slack-health-score@d58a419f15cdaff97e9aa7f09f95772830ab66f7 # v0.1.1
with:
+13 -12
View File
@@ -13,7 +13,7 @@
"@actions/github": "^9.0.0",
"@slack/logger": "^4.0.0",
"@slack/web-api": "^7.13.0",
"axios": "^1.13.4",
"axios": "^1.13.5",
"axios-retry": "^4.5.0",
"flat": "^6.0.1",
"https-proxy-agent": "^7.0.6",
@@ -497,13 +497,13 @@
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.4.tgz",
"integrity": "sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==",
"version": "1.13.5",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz",
"integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.4",
"follow-redirects": "^1.15.11",
"form-data": "^4.0.5",
"proxy-from-env": "^1.1.0"
}
},
@@ -668,15 +668,16 @@
}
},
"node_modules/follow-redirects": {
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
@@ -687,9 +688,9 @@
}
},
"node_modules/form-data": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
+1 -1
View File
@@ -38,7 +38,7 @@
"@actions/github": "^9.0.0",
"@slack/logger": "^4.0.0",
"@slack/web-api": "^7.13.0",
"axios": "^1.13.4",
"axios": "^1.13.5",
"axios-retry": "^4.5.0",
"flat": "^6.0.1",
"https-proxy-agent": "^7.0.6",