feat: support slack cli commands with composite action inputs (#560)
Co-authored-by: Claude <[email protected]> Co-authored-by: William Bergamin <[email protected]>
This commit is contained in:
co-authored by
Claude
William Bergamin
parent
0aed2c2a70
commit
e45cb891a6
@@ -4,4 +4,5 @@
|
||||
export SLACK_BOT_TOKEN=xoxb-01010101-example
|
||||
export SLACK_CHANNEL_ID=C0123456789
|
||||
export SLACK_INCOMING_WEBHOOK=https://hooks.slack.com/services/T0123456789/B0123456789/abcdefghijklmnopqrstuvwxyz
|
||||
export SLACK_SERVICE_TOKEN=xoxp-01010101-example
|
||||
export SLACK_WEBHOOK_TRIGGER=https://hooks.slack.com/triggers/T0123456789/00000000000/abcdefghijklmnopqrstuvwxyz
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"experiments": ["bolt"],
|
||||
"manifest": {
|
||||
"source": "local"
|
||||
},
|
||||
"project_id": "c4805b41-d1ce-4ea0-b297-ed2f8c64c267"
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"runtime": "actions",
|
||||
"hooks": {
|
||||
"deploy": "open https://api.slack.com/apps || true",
|
||||
"deploy": "echo https://api.slack.com/apps",
|
||||
"get-manifest": "cat ./.slack/manifest.json #"
|
||||
},
|
||||
"config": {
|
||||
@@ -6,7 +6,7 @@ experiments with the [Slack CLI][cli].
|
||||
|
||||
## Overview
|
||||
|
||||
This app showcases all three techniques of sending data into Slack and follows
|
||||
This app showcases all four techniques of interacting with Slack and follows
|
||||
patterns found in the integration tests.
|
||||
|
||||
- **Technique 1** Slack Workflow Builder: Use a Slack webhook trigger to start a
|
||||
@@ -15,6 +15,8 @@ patterns found in the integration tests.
|
||||
data provided through the GitHub workflow.
|
||||
- **Technique 3** Incoming webhook: Post a message to a Slack channel using an
|
||||
incoming webhook.
|
||||
- **Technique 4** Slack CLI Command: Install and run Slack CLI commands such as
|
||||
`deploy` or `manifest` using a service token.
|
||||
|
||||
Configurations for the Slack app and workflow, and the GitHub Actions workflow
|
||||
are found in the following files:
|
||||
@@ -22,6 +24,9 @@ are found in the following files:
|
||||
- Slack app setup: [`.github/resources/.slack/manifest.json`][slacktion]
|
||||
- GitHub Actions steps: [`.github/workflows/develop.yml`][develop]
|
||||
|
||||
> **Note:** During CLI integration tests, `.github/resources/.slack` is moved to
|
||||
> `.slack` at the project root so the Slack CLI can discover the app manifest.
|
||||
|
||||
Either the techniques or app setup and workflow steps can be adjusted during
|
||||
testing and development. For experimenting with new changes, we recommend using
|
||||
the [steps for development](#experimenting-for-development) while the
|
||||
@@ -76,6 +81,8 @@ tested. Required values include:
|
||||
https://hooks.slack.com/services/T0123456789/B0123456789/abcdefghijklmnopqrstuvwxyz
|
||||
- `SLACK_WEBHOOK_TRIGGER`:
|
||||
https://hooks.slack.com/triggers/T0123456789/00000000000/abcdefghijklmnopqrstuvwxyz
|
||||
- `SLACK_SERVICE_TOKEN`: xoxp-service-token-example (secret — for CLI commands)
|
||||
- `SLACK_APP_ID`: A0123456789 (variable — used with `--app` flag in CLI deploy)
|
||||
|
||||
### Experimenting for development
|
||||
|
||||
@@ -98,6 +105,7 @@ export SLACK_BOT_TOKEN=xoxb-01010101-example
|
||||
export SLACK_CHANNEL_ID=C0123456789
|
||||
export SLACK_INCOMING_WEBHOOK=https://hooks.slack.com/services/T0123456789/B0123456789/abcdefghijklmnopqrstuvwxyz
|
||||
export SLACK_WEBHOOK_TRIGGER=https://hooks.slack.com/triggers/T0123456789/00000000000/abcdefghijklmnopqrstuvwxyz
|
||||
export SLACK_SERVICE_TOKEN=xoxp-service-token-example
|
||||
```
|
||||
|
||||
Environment variables and credentials should be set in the created `.env` file
|
||||
|
||||
@@ -12,7 +12,7 @@ on:
|
||||
|
||||
jobs:
|
||||
integration:
|
||||
name: Run integration tests
|
||||
name: Run API tests
|
||||
runs-on: ubuntu-latest
|
||||
environment: staging
|
||||
permissions:
|
||||
@@ -68,7 +68,7 @@ jobs:
|
||||
env:
|
||||
INPUT_REF: ${{ inputs.ref }}
|
||||
|
||||
- name: "integration(wfb): send a payload to workflow builder via webhook trigger"
|
||||
- name: "test(wfb): send a payload to workflow builder via webhook trigger"
|
||||
id: wfb
|
||||
uses: ./
|
||||
with:
|
||||
@@ -82,12 +82,12 @@ jobs:
|
||||
repo_name: ${{ github.event.repository.full_name }}
|
||||
status: ${{ job.status }}
|
||||
|
||||
- name: "integration(wfb): confirm a payload was sent"
|
||||
- name: "test(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"
|
||||
- name: "test(api): post a message to channel"
|
||||
id: message
|
||||
uses: ./
|
||||
with:
|
||||
@@ -98,12 +98,12 @@ jobs:
|
||||
channel: ${{ secrets.SLACK_CHANNEL_ID }}
|
||||
text: ":checkered_flag: Action happens at <https://github.com/${{ github.repository }}>"
|
||||
|
||||
- name: "integration(method): confirm a message was posted"
|
||||
- name: "test(api): 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"
|
||||
- name: "test(api): post a message with blocks"
|
||||
id: blocks
|
||||
uses: ./
|
||||
with:
|
||||
@@ -120,12 +120,12 @@ jobs:
|
||||
short: true
|
||||
value: "Processing"
|
||||
|
||||
- name: "integration(method): confirm the blocks were posted"
|
||||
- name: "test(api): 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"
|
||||
- name: "test(api): post a threaded message"
|
||||
id: timer
|
||||
uses: ./
|
||||
with:
|
||||
@@ -137,15 +137,15 @@ jobs:
|
||||
text: "Started at `${{ steps.blocks.outputs.time }}`"
|
||||
thread_ts: "${{ steps.blocks.outputs.ts }}"
|
||||
|
||||
- name: "integration(incoming): confirm the thread started"
|
||||
- name: "test(api): 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"
|
||||
- name: "test(api): wait to mock event processing"
|
||||
run: sleep 3
|
||||
|
||||
- name: "integration(method): update the original message"
|
||||
- name: "test(api): update the original message"
|
||||
id: finished
|
||||
uses: ./
|
||||
with:
|
||||
@@ -163,7 +163,7 @@ jobs:
|
||||
short: true
|
||||
value: "Completed"
|
||||
|
||||
- name: "integration(method): post another threaded message"
|
||||
- name: "test(api): post another threaded message"
|
||||
id: done
|
||||
uses: ./
|
||||
with:
|
||||
@@ -175,7 +175,7 @@ jobs:
|
||||
text: "Finished at `${{ steps.finished.outputs.time }}`"
|
||||
thread_ts: "${{ steps.timer.outputs.thread_ts }}"
|
||||
|
||||
- name: "integration(method): post a file into a channel"
|
||||
- name: "test(api): post a file into a channel"
|
||||
id: file
|
||||
uses: ./
|
||||
with:
|
||||
@@ -188,7 +188,7 @@ jobs:
|
||||
file: .github/workflows/integration.yml
|
||||
filename: integration.yml
|
||||
|
||||
- name: "integration(method): react to the completed update message"
|
||||
- name: "test(api): react to the completed update message"
|
||||
uses: ./
|
||||
with:
|
||||
errors: true
|
||||
@@ -199,12 +199,12 @@ jobs:
|
||||
timestamp: ${{ steps.blocks.outputs.ts }}
|
||||
name: "tada"
|
||||
|
||||
- name: "integration(method): confirm the thread ended"
|
||||
- name: "test(api): 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"
|
||||
- name: "test(incoming): post a message via incoming webhook"
|
||||
id: incoming
|
||||
uses: ./
|
||||
with:
|
||||
@@ -212,7 +212,7 @@ jobs:
|
||||
webhook: ${{ secrets.SLACK_INCOMING_WEBHOOK }}
|
||||
webhook-type: incoming-webhook
|
||||
payload: |
|
||||
text: "Incoming webhook test for slack send"
|
||||
text: "Incoming webhook test for the Slack GitHub Action"
|
||||
blocks:
|
||||
- type: section
|
||||
text:
|
||||
@@ -220,17 +220,17 @@ jobs:
|
||||
text: ":link: A message was received via incoming webhook"
|
||||
emoji: true
|
||||
|
||||
- name: "integration(incoming): confirm a webhook was posted"
|
||||
- name: "test(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"
|
||||
- name: "test(incoming): reveal contents of the github payload"
|
||||
run: echo "$JSON"
|
||||
env:
|
||||
JSON: ${{ toJSON(github) }}
|
||||
|
||||
- name: "integration(incoming): post a message via payload file"
|
||||
- name: "test(incoming): post a message via payload file"
|
||||
id: payload_file
|
||||
uses: ./
|
||||
with:
|
||||
@@ -243,15 +243,80 @@ jobs:
|
||||
JOB_STATUS: ${{ job.status }}
|
||||
ATTACHMENT_COLOR: ${{ (job.status == 'success' && 'good') || (job.status == 'failure' && 'danger') || 'warning' }}
|
||||
|
||||
- name: "integration(incoming): confirm a payload file was posted"
|
||||
- name: "test(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
|
||||
cli:
|
||||
name: Run CLI tests
|
||||
runs-on: ${{ matrix.os }}
|
||||
environment: staging
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- macos-latest
|
||||
- windows-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: "build: checkout the latest changes"
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
codecov_token: ${{ secrets.CODECOV_API_TOKEN }}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
extension: js
|
||||
include: src
|
||||
persist-credentials: false
|
||||
ref: ${{ inputs.ref || github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
- name: "test(cli): run a slack cli version check"
|
||||
id: version
|
||||
uses: ./cli
|
||||
with:
|
||||
command: "version"
|
||||
|
||||
- name: "test(cli): confirm the version check outputs"
|
||||
shell: bash
|
||||
run: |
|
||||
set -ex
|
||||
[ "$CLI_OK" = "true" ]
|
||||
echo "$CLI_TIME" | grep -qE '^[0-9]+$'
|
||||
[ -n "$CLI_RESPONSE" ]
|
||||
env:
|
||||
CLI_OK: ${{ steps.version.outputs.ok }}
|
||||
CLI_RESPONSE: ${{ steps.version.outputs.response }}
|
||||
CLI_TIME: ${{ steps.version.outputs.time }}
|
||||
|
||||
- name: "test(cli): run an unknown command"
|
||||
id: unknown
|
||||
continue-on-error: true
|
||||
uses: ./cli
|
||||
with:
|
||||
command: "off"
|
||||
|
||||
- name: "test(cli): confirm the unknown command outputs"
|
||||
shell: bash
|
||||
run: |
|
||||
set -ex
|
||||
[ "$CLI_OK" = "false" ]
|
||||
echo "$CLI_TIME" | grep -qE '^[0-9]+$'
|
||||
[ -n "$CLI_RESPONSE" ]
|
||||
env:
|
||||
CLI_OK: ${{ steps.unknown.outputs.ok }}
|
||||
CLI_RESPONSE: ${{ steps.unknown.outputs.response }}
|
||||
CLI_TIME: ${{ steps.unknown.outputs.time }}
|
||||
|
||||
- name: "chore: configure the actioneering application"
|
||||
shell: bash
|
||||
run: mv .github/resources/.slack .slack
|
||||
|
||||
- name: "test(cli): validate the app manifest"
|
||||
uses: ./cli
|
||||
with:
|
||||
command: "manifest"
|
||||
token: ${{ secrets.SLACK_SERVICE_TOKEN }}
|
||||
|
||||
- name: "test(cli): deploy the app"
|
||||
uses: ./cli
|
||||
with:
|
||||
command: "deploy --app ${{ vars.SLACK_APP_ID }} --hide-triggers --force"
|
||||
token: ${{ secrets.SLACK_SERVICE_TOKEN }}
|
||||
|
||||
@@ -38,6 +38,9 @@ jobs:
|
||||
uses: teunmooij/github-versioned-release@3edf649c6e5e5e976d43f2584b15bdc8b4c8f0df # v1.2.1
|
||||
with:
|
||||
template: javascript-action
|
||||
include: |
|
||||
dist/**/*
|
||||
cli/**/*
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ on:
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
name: Run tests
|
||||
name: Run unit tests
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
checks: write
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Slack Send GitHub Action
|
||||
# Slack GitHub Action
|
||||
|
||||
> the GitHub Action for sending data to Slack
|
||||
> the GitHub Action for sending data to Slack and running commands
|
||||
|
||||
[](https://codecov.io/gh/slackapi/slack-github-action)
|
||||
|
||||
@@ -11,6 +11,7 @@ Use this GitHub Action to:
|
||||
- [Send data with a webhook to start a workflow in Workflow Builder](https://docs.slack.dev/tools/slack-github-action/sending-techniques/sending-data-webhook-slack-workflow).
|
||||
- [Send data using a Slack API method and a secret token with required scopes](https://docs.slack.dev/tools/slack-github-action/sending-techniques/sending-data-slack-api-method/).
|
||||
- [Send data as a message with a Slack incoming webhook URL](https://docs.slack.dev/tools/slack-github-action/sending-techniques/sending-data-slack-incoming-webhook/).
|
||||
- [Run Slack CLI commands with a service token](https://docs.slack.dev/tools/slack-github-action/sending-techniques/running-slack-cli-commands/).
|
||||
|
||||
## Project details
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
name: "Slack: Send to Slack"
|
||||
name: "Slack GitHub Action"
|
||||
author: "slackapi"
|
||||
description: "Send data to Slack to start a Slack workflow in Workflow Builder, call a Slack API method, or post a message into a channel"
|
||||
description: "Post a message, call a Web API method, start a Slack workflow, or run a Slack CLI command from GitHub Actions"
|
||||
inputs:
|
||||
api:
|
||||
description: "A custom API URL to send Slack API method requests to."
|
||||
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
name: "Slack GitHub Action: CLI"
|
||||
author: "slackapi"
|
||||
description: "Install the Slack CLI and run a command in a GitHub Actions workflow"
|
||||
inputs:
|
||||
command:
|
||||
description: "A Slack CLI command to run without the 'slack' prefix."
|
||||
required: true
|
||||
token:
|
||||
description: "A service token passed as the '--token' flag to the CLI command."
|
||||
required: false
|
||||
version:
|
||||
description: "The version of the Slack CLI to install. Defaults to the latest."
|
||||
required: false
|
||||
outputs:
|
||||
ok:
|
||||
description: "If the command completed with a '0' exit code."
|
||||
value: ${{ steps.slack-cli-unix.outputs.ok || steps.slack-cli-windows.outputs.ok }}
|
||||
response:
|
||||
description: "The standard output from the CLI command."
|
||||
value: ${{ steps.slack-cli-unix.outputs.response || steps.slack-cli-windows.outputs.response }}
|
||||
time:
|
||||
description: "The Unix epoch time that the step completed."
|
||||
value: ${{ steps.slack-cli-unix.outputs.time || steps.slack-cli-windows.outputs.time }}
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Check if Slack CLI already exists
|
||||
id: slack-cli-check
|
||||
shell: bash
|
||||
run: |
|
||||
if command -v slack &> /dev/null; then
|
||||
echo "exists=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "exists=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Cache Slack CLI
|
||||
if: steps.slack-cli-check.outputs.exists != 'true' && inputs.version != ''
|
||||
id: cache-cli
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
with:
|
||||
path: |
|
||||
${{ runner.os == 'Windows' && '~/AppData/Local/slack-cli' || '~/.slack/bin' }}
|
||||
key: slack-cli-${{ runner.os }}-${{ runner.arch }}-${{ inputs.version }}
|
||||
|
||||
- name: Bash Add Slack CLI to PATH
|
||||
if: steps.slack-cli-check.outputs.exists != 'true' && runner.os != 'Windows'
|
||||
shell: bash
|
||||
run: echo "$HOME/.slack/bin" >> "$GITHUB_PATH" # zizmor: ignore[github-env]
|
||||
|
||||
- name: Pwsh Add Slack CLI to PATH
|
||||
if: steps.slack-cli-check.outputs.exists != 'true' && runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: Add-Content -Path $env:GITHUB_PATH -Value "$env:USERPROFILE\AppData\Local\slack-cli\bin" # zizmor: ignore[github-env]
|
||||
|
||||
- name: Bash Install Slack CLI
|
||||
if: >-
|
||||
steps.slack-cli-check.outputs.exists != 'true' &&
|
||||
steps.cache-cli.outputs.cache-hit != 'true' &&
|
||||
runner.os != 'Windows'
|
||||
shell: bash
|
||||
run: |
|
||||
if [ -n "$SLACK_CLI_VERSION" ]; then
|
||||
curl -fsSL https://downloads.slack-edge.com/slack-cli/install.sh | bash -s -- -v "$SLACK_CLI_VERSION"
|
||||
else
|
||||
curl -fsSL https://downloads.slack-edge.com/slack-cli/install.sh | bash -s
|
||||
fi
|
||||
env:
|
||||
SLACK_CLI_VERSION: ${{ inputs.version }}
|
||||
|
||||
- name: Pwsh Install Slack CLI
|
||||
if: >-
|
||||
steps.slack-cli-check.outputs.exists != 'true' &&
|
||||
steps.cache-cli.outputs.cache-hit != 'true' &&
|
||||
runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
if ($env:SLACK_CLI_VERSION) {
|
||||
$installer = Join-Path $env:TEMP "install-slack-cli.ps1"
|
||||
Invoke-WebRequest -Uri "https://downloads.slack-edge.com/slack-cli/install-windows.ps1" -OutFile $installer
|
||||
& $installer -v $env:SLACK_CLI_VERSION
|
||||
} else {
|
||||
irm https://downloads.slack-edge.com/slack-cli/install-windows.ps1 | iex
|
||||
}
|
||||
env:
|
||||
SLACK_CLI_VERSION: ${{ inputs.version }}
|
||||
|
||||
- name: Bash Run Slack CLI command
|
||||
id: slack-cli-unix
|
||||
if: runner.os != 'Windows'
|
||||
shell: bash
|
||||
env:
|
||||
SLACK_COMMAND: ${{ inputs.command }}
|
||||
SLACK_TOKEN: ${{ inputs.token }}
|
||||
run: |
|
||||
args="$SLACK_COMMAND --skip-update"
|
||||
if [ "$RUNNER_DEBUG" = "1" ]; then
|
||||
args="$args --verbose"
|
||||
fi
|
||||
if [ -n "$SLACK_TOKEN" ]; then
|
||||
args="$args --token $SLACK_TOKEN"
|
||||
fi
|
||||
|
||||
set +e
|
||||
output=$(slack $args 2>&1 | tee /dev/stderr)
|
||||
exit_code=$?
|
||||
set -e
|
||||
|
||||
echo "ok=$([ $exit_code -eq 0 ] && echo 'true' || echo 'false')" >> "$GITHUB_OUTPUT"
|
||||
echo "time=$(date +%s)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
echo "response<<SLACKCLIEOF" >> "$GITHUB_OUTPUT"
|
||||
echo "$output" >> "$GITHUB_OUTPUT"
|
||||
echo "SLACKCLIEOF" >> "$GITHUB_OUTPUT"
|
||||
|
||||
if [ $exit_code -ne 0 ]; then
|
||||
exit $exit_code
|
||||
fi
|
||||
|
||||
- name: Pwsh Run Slack CLI command
|
||||
id: slack-cli-windows
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
env:
|
||||
SLACK_COMMAND: ${{ inputs.command }}
|
||||
SLACK_TOKEN: ${{ inputs.token }}
|
||||
run: |
|
||||
$cliArgs = "$env:SLACK_COMMAND --skip-update"
|
||||
if ($env:RUNNER_DEBUG -eq "1") {
|
||||
$cliArgs = "$cliArgs --verbose"
|
||||
}
|
||||
if ($env:SLACK_TOKEN) {
|
||||
$cliArgs = "$cliArgs --token $env:SLACK_TOKEN"
|
||||
}
|
||||
|
||||
$outputFile = New-TemporaryFile
|
||||
slack $cliArgs.Split(' ') 2>&1 | Tee-Object -FilePath $outputFile.FullName
|
||||
$exit_code = $LASTEXITCODE
|
||||
$output = Get-Content $outputFile.FullName -Raw
|
||||
|
||||
"ok=$( if ($exit_code -eq 0) { 'true' } else { 'false' } )" >> $env:GITHUB_OUTPUT
|
||||
"time=$([DateTimeOffset]::UtcNow.ToUnixTimeSeconds())" >> $env:GITHUB_OUTPUT
|
||||
|
||||
"response<<SLACKCLIEOF" >> $env:GITHUB_OUTPUT
|
||||
$output >> $env:GITHUB_OUTPUT
|
||||
"SLACKCLIEOF" >> $env:GITHUB_OUTPUT
|
||||
|
||||
if ($exit_code -ne 0) {
|
||||
exit $exit_code
|
||||
}
|
||||
@@ -57,6 +57,20 @@
|
||||
"tools/slack-github-action/sending-techniques/sending-data-slack-incoming-webhook/post-inline-block-message",
|
||||
"tools/slack-github-action/sending-techniques/sending-data-slack-incoming-webhook/post-blocks-found-in-file"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"label": "Running Slack CLI commands",
|
||||
"link": {
|
||||
"type": "doc",
|
||||
"id": "tools/slack-github-action/sending-techniques/running-slack-cli-commands/running-slack-cli-commands"
|
||||
},
|
||||
"items": [
|
||||
"tools/slack-github-action/sending-techniques/running-slack-cli-commands/running-slack-cli-commands",
|
||||
"tools/slack-github-action/sending-techniques/running-slack-cli-commands/deploy-an-app",
|
||||
"tools/slack-github-action/sending-techniques/running-slack-cli-commands/validate-a-manifest",
|
||||
"tools/slack-github-action/sending-techniques/running-slack-cli-commands/manage-collaborators"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# Example workflow: deploy an app
|
||||
|
||||
This workflow deploys a Slack app when changes are pushed to the main branch.
|
||||
|
||||
This example uses a service token to authenticate the deploy command.
|
||||
|
||||
## Files
|
||||
|
||||
### GitHub Actions workflow
|
||||
|
||||
```js reference
|
||||
https://github.com/slackapi/slack-github-action/blob/main/example-workflows/Technique_4_Slack_CLI_Command/deploy.yml
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
# Example workflow: manage collaborators
|
||||
|
||||
This workflow adds or removes an app collaborator using a manually triggered workflow.
|
||||
|
||||
This example combines the Slack API technique ([`users.lookupByEmail`](https://docs.slack.dev/reference/methods/users.lookupByEmail), [`chat.postMessage`](https://docs.slack.dev/reference/methods/chat.postMessage)) with the CLI technique ([`collaborators add`](https://docs.slack.dev/tools/slack-cli/reference/commands/slack_collaborators_add)/[`remove`](https://docs.slack.dev/tools/slack-cli/reference/commands/slack_collaborators_remove)) to look up a user by email, update collaborators, and post a confirmation message.
|
||||
|
||||
## Files
|
||||
|
||||
### GitHub Actions workflow
|
||||
|
||||
```js reference
|
||||
https://github.com/slackapi/slack-github-action/blob/main/example-workflows/Technique_4_Slack_CLI_Command/collaborators.yml
|
||||
```
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
sidebar_label: Overview
|
||||
---
|
||||
|
||||
# Running Slack CLI commands
|
||||
|
||||
The Slack CLI technique installs and runs [Slack CLI](/tools/slack-cli/) commands directly from a GitHub Actions workflow.
|
||||
|
||||
This is useful for automating tasks such as deploying apps, validating an app manifest, or interacting with Slack platform features that are available with the CLI.
|
||||
|
||||
## Setup
|
||||
|
||||
### Authentication
|
||||
|
||||
Pass a [service token](/authentication/tokens/) via the `token` input. This is appended as `--token <value>` to the CLI command. The [`slack auth token`](/tools/slack-cli/reference/commands/slack_auth_token) command can be used to gather this.
|
||||
|
||||
### CLI version
|
||||
|
||||
By default, the latest version of the Slack CLI is installed. To pin a specific version, use the `version` input:
|
||||
|
||||
```yaml
|
||||
- uses: slackapi/slack-github-action/cli@v2
|
||||
with:
|
||||
command: "version"
|
||||
version: "3.14.0"
|
||||
```
|
||||
|
||||
If the `slack` command already exists on `PATH`, installation is skipped entirely.
|
||||
|
||||
## Usage
|
||||
|
||||
Provide a `command` input with the Slack CLI command to run, omitting the `slack` prefix.
|
||||
|
||||
```yaml
|
||||
- uses: slackapi/slack-github-action/cli@v2
|
||||
with:
|
||||
command: "version"
|
||||
```
|
||||
|
||||
## Debug logging
|
||||
|
||||
When a workflow is re-run with **Enable debug logging**, the action automatically appends `--verbose` to the CLI command. You can also include `--verbose` in your `command` input manually at any time.
|
||||
|
||||
```yaml
|
||||
- uses: slackapi/slack-github-action/cli@v2
|
||||
with:
|
||||
command: "deploy --app ${{ vars.SLACK_APP_ID }} --verbose"
|
||||
token: ${{ secrets.SLACK_SERVICE_TOKEN }}
|
||||
```
|
||||
|
||||
## Outputs
|
||||
|
||||
The following outputs are available after a CLI command runs:
|
||||
|
||||
| Output | Type | Description |
|
||||
| ---------- | --------- | --------------------------------------------------------------------------------------- |
|
||||
| `ok` | `boolean` | If the command completed with a `0` exit code. |
|
||||
| `response` | `string` | The standard output from the CLI command. |
|
||||
| `time` | `number` | The Unix [epoch time](https://en.wikipedia.org/wiki/Unix_time) that the step completed. |
|
||||
|
||||
## Examples
|
||||
|
||||
### Check the installed CLI version
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: slackapi/slack-github-action/cli@v2
|
||||
id: slack
|
||||
with:
|
||||
command: "version"
|
||||
- run: echo "${{ steps.slack.outputs.response }}"
|
||||
```
|
||||
|
||||
### Validate the app manifest
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: slackapi/slack-github-action/cli@v2
|
||||
with:
|
||||
command: "manifest validate --app ${{ vars.SLACK_APP_ID }}"
|
||||
token: ${{ secrets.SLACK_SERVICE_TOKEN }}
|
||||
```
|
||||
|
||||
### Deploy an app with a service token
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: slackapi/slack-github-action/cli@v2
|
||||
with:
|
||||
command: "deploy --app ${{ vars.SLACK_APP_ID }} --force"
|
||||
token: ${{ secrets.SLACK_SERVICE_TOKEN }}
|
||||
```
|
||||
|
||||
## Example workflows
|
||||
|
||||
* [**Deploy an app**](/tools/slack-github-action/sending-techniques/running-slack-cli-commands/deploy-an-app): Deploy to Slack on push to the main branch.
|
||||
* [**Validate a manifest**](/tools/slack-github-action/sending-techniques/running-slack-cli-commands/validate-a-manifest): Check the app manifest on pull requests.
|
||||
* [**Manage collaborators**](/tools/slack-github-action/sending-techniques/running-slack-cli-commands/manage-collaborators): Add or remove an app collaborator using CLI and API techniques together.
|
||||
@@ -0,0 +1,13 @@
|
||||
# Example workflow: validate a manifest
|
||||
|
||||
This workflow validates the app manifest on pull requests to catch configuration issues early.
|
||||
|
||||
This example checks the app manifest file in the repository.
|
||||
|
||||
## Files
|
||||
|
||||
### GitHub Actions workflow
|
||||
|
||||
```js reference
|
||||
https://github.com/slackapi/slack-github-action/blob/main/example-workflows/Technique_4_Slack_CLI_Command/manifest.yml
|
||||
```
|
||||
@@ -4,11 +4,12 @@ sidebar_label: Overview
|
||||
|
||||
# Sending techniques
|
||||
|
||||
This GitHub Action offers three different techniques to send data to Slack:
|
||||
This GitHub Action offers four different techniques to interact with Slack:
|
||||
|
||||
* [Send data with a webhook to start a workflow in Workflow Builder](/tools/slack-github-action/sending-techniques/sending-data-webhook-slack-workflow).
|
||||
* [Send data using a Slack API method and a secret token with required scopes](/tools/slack-github-action/sending-techniques/sending-data-slack-api-method/).
|
||||
* [Send data as a message with a Slack incoming webhook URL](/tools/slack-github-action/sending-techniques/sending-data-slack-incoming-webhook/).
|
||||
* [Send data as a message with a Slack incoming webhook URL](/tools/slack-github-action/sending-techniques/sending-data-slack-incoming-webhook/).
|
||||
* [Run Slack CLI commands with a service token](/tools/slack-github-action/sending-techniques/running-slack-cli-commands/running-slack-cli-commands).
|
||||
|
||||
## Expected outputs
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Slack Send GitHub Action
|
||||
# Slack GitHub Action
|
||||
|
||||
The GitHub Action for sending data to Slack.
|
||||
The GitHub Action for sending data to Slack and running commands.
|
||||
|
||||
## Versioning
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ jobs:
|
||||
- name: Send the issue link into the Slack channel
|
||||
uses: slackapi/[email protected]
|
||||
with:
|
||||
errors: true
|
||||
method: chat.postMessage # https://docs.slack.dev/reference/methods/chat.postMessage/
|
||||
token: ${{ secrets.SLACK_BOT_TOKEN }}
|
||||
payload: |
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# Technique 4: Slack CLI Command
|
||||
|
||||
A [service token](https://docs.slack.dev/authentication/tokens/#service) is used to install and run [Slack CLI](https://docs.slack.dev/tools/slack-cli/) commands directly from a GitHub Actions workflow with this technique.
|
||||
|
||||
## Setup
|
||||
|
||||
For details on how to setup this technique in GitHub Actions, read the [setup](https://docs.slack.dev/tools/slack-github-action/sending-techniques/running-slack-cli-commands/) section of the docs.
|
||||
|
||||
## Example workflows
|
||||
|
||||
1. [**Deploy an app**](#deploy-an-app): Deploy to Slack on push to the main branch.
|
||||
2. [**Validate the app manifest**](#validate-the-app-manifest): Check the app manifest on pull requests.
|
||||
3. [**Manage a collaborator**](#manage-a-collaborator): Add or remove an app collaborator using CLI and API techniques together.
|
||||
|
||||
### Deploy an app
|
||||
|
||||
Deploy a Slack app when changes are pushed to the main branch. This example uses a service token to authenticate the deploy command.
|
||||
|
||||
**Related files**:
|
||||
|
||||
- [`deploy.yml`](./deploy.yml): GitHub Actions workflow.
|
||||
|
||||
### Validate the app manifest
|
||||
|
||||
Run manifest validation on pull requests to catch configuration issues early. This example checks the app manifest file in the repository.
|
||||
|
||||
**Related files**:
|
||||
|
||||
- [`manifest.yml`](./manifest.yml): GitHub Actions workflow.
|
||||
|
||||
### Manage a collaborator
|
||||
|
||||
Add or remove an app collaborator using a manually triggered workflow with [`workflow_dispatch`](https://docs.github.com/en/actions/how-tos/manage-workflow-runs/manually-run-a-workflow). This example combines the Slack API technique ([`users.lookupByEmail`](https://docs.slack.dev/reference/methods/users.lookupByEmail), [`chat.postMessage`](https://docs.slack.dev/reference/methods/chat.postMessage)) with the CLI technique ([`collaborators add`](https://docs.slack.dev/tools/slack-cli/reference/commands/slack_collaborators_add)/[`remove`](https://docs.slack.dev/tools/slack-cli/reference/commands/slack_collaborators_remove)) to look up a user by email, update collaborators, and post a confirmation message.
|
||||
|
||||
**Related files**:
|
||||
|
||||
- [`collaborators.yml`](./collaborators.yml): GitHub Actions workflow.
|
||||
@@ -0,0 +1,59 @@
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
||||
|
||||
name: Manage a collaborator
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
email:
|
||||
description: "The collaborator's email address"
|
||||
required: true
|
||||
type: string
|
||||
add:
|
||||
description: "Checked to add, unchecked to remove"
|
||||
required: false
|
||||
default: true
|
||||
type: boolean
|
||||
jobs:
|
||||
collaborator:
|
||||
name: Add or remove a collaborator
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Look up the Slack user by email
|
||||
id: email
|
||||
uses: slackapi/slack-github-action@v2
|
||||
with:
|
||||
method: users.lookupByEmail # https://docs.slack.dev/reference/methods/users.lookupByEmail/
|
||||
token: ${{ secrets.SLACK_BOT_TOKEN }}
|
||||
payload: |
|
||||
email: ${{ inputs.email }}
|
||||
|
||||
- name: Gather the display name
|
||||
if: ${{ steps.email.outputs.ok }}
|
||||
run: |
|
||||
SLACK_USER_ID=$(echo '${{ steps.email.outputs.response }}' | jq -r '.user.id')
|
||||
SLACK_DISPLAY_NAME=$(echo '${{ steps.email.outputs.response }}' | jq -r '(.user.profile.display_name | select(. != "")) // .user.real_name')
|
||||
echo "SLACK_USER_ID=$SLACK_USER_ID" >> "$GITHUB_ENV"
|
||||
echo "SLACK_DISPLAY_NAME=$SLACK_DISPLAY_NAME" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Add or remove the collaborator
|
||||
if: ${{ steps.email.outputs.ok }}
|
||||
uses: slackapi/slack-github-action/cli@v2
|
||||
with:
|
||||
command: "collaborators ${{ inputs.add && 'add' || 'remove' }} ${{ inputs.email }} --app ${{ vars.SLACK_APP_ID }}"
|
||||
token: ${{ secrets.SLACK_SERVICE_TOKEN }}
|
||||
|
||||
- name: Post a confirmation message
|
||||
if: ${{ steps.email.outputs.ok }}
|
||||
uses: slackapi/slack-github-action@v2
|
||||
with:
|
||||
errors: true
|
||||
method: chat.postMessage # https://docs.slack.dev/reference/methods/chat.postMessage/
|
||||
token: ${{ secrets.SLACK_BOT_TOKEN }}
|
||||
payload: |
|
||||
channel: ${{ secrets.SLACK_CHANNEL_ID }}
|
||||
text: "<@${{ env.SLACK_USER_ID }}> (${{ env.SLACK_DISPLAY_NAME }}) was ${{ inputs.add && 'added to' || 'removed from' }} the app collaborators."
|
||||
@@ -0,0 +1,32 @@
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
||||
|
||||
name: Deploy an app
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
jobs:
|
||||
deploy:
|
||||
name: Deploy to Slack
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Deploy the app
|
||||
uses: slackapi/slack-github-action/cli@v2
|
||||
with:
|
||||
command: "deploy --app ${{ vars.SLACK_APP_ID }} --force"
|
||||
token: ${{ secrets.SLACK_SERVICE_TOKEN }}
|
||||
|
||||
- name: Post a deployment message
|
||||
uses: slackapi/slack-github-action@v2
|
||||
with:
|
||||
errors: true
|
||||
method: chat.postMessage
|
||||
token: ${{ secrets.SLACK_BOT_TOKEN }}
|
||||
payload: |
|
||||
channel: ${{ secrets.SLACK_CHANNEL_ID }}
|
||||
text: "Deployed to Slack from ${{ github.sha }}"
|
||||
@@ -0,0 +1,20 @@
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
||||
|
||||
name: Validate the app manifest
|
||||
on:
|
||||
pull_request:
|
||||
jobs:
|
||||
validate:
|
||||
name: Check the app manifest
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Validate the manifest
|
||||
uses: slackapi/slack-github-action/cli@v2
|
||||
with:
|
||||
command: "manifest validate --app ${{ vars.SLACK_APP_ID }}"
|
||||
token: ${{ secrets.SLACK_SERVICE_TOKEN }}
|
||||
Reference in New Issue
Block a user