Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow to use json file as is without replacing/parsing anything #299

Merged
merged 8 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,19 @@ or
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
```

> To keep the payload json file as is, without replacing values from `github.context`, pass an additional parameter `payload-file-path-parsed`

```yaml
- name: Send custom JSON data to Slack workflow
id: slack
uses: slackapi/slack-github-action@v1.25.0
with:
payload-file-path: "./payload-slack-content.json"
payload-file-path-parsed: 'true'
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
```

### Technique 2: Slack App

By creating a new Slack app or using an existing one, this approach allows your GitHub Actions job to post a message in a Slack channel or direct message by utilizing the [chat.postMessage](https://api.slack.com/methods/chat.postMessage) API method. Using this approach you can instantly post a message without setting up Slack workflows.
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ inputs:
payload-file-path: # path to JSON payload to send to Slack via webhook
description: 'path to JSON payload to send to Slack if webhook route. If not supplied, json from GitHub event will be sent instead. If payload is provided, it will take preference over this field'
required: false
payload-file-path-parsed:
description: 'If payload-file-path is provided instead of json payload, do not replace values in the file from `github.context`.'
required: false
default: 'false'
update-ts: # The timestamp of a previous message posted to update it instead of posting a new message
description: 'The timestamp of a previous message posted. It will update the existing message instead of posting a new message'
required: false
Expand Down
23 changes: 15 additions & 8 deletions src/slack-send.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const axios = require('axios');
const markup = require('markup-js');
const { HttpsProxyAgent } = require('https-proxy-agent');
const { parseURL } = require('whatwg-url');

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Let's keep the space between external and internal dependencies.

const { createWebClient } = require('./web-client');

const SLACK_WEBHOOK_TYPES = {
Expand Down Expand Up @@ -34,15 +33,19 @@ module.exports = async function slackSend(core) {

const payloadFilePath = core.getInput('payload-file-path');

const useFileAsIs = core.getInput('payload-file-path-parsed');

let webResponse;

if (payloadFilePath && !payload) {
try {
payload = await fs.readFile(path.resolve(payloadFilePath), 'utf-8');
// parse github context variables
const context = { github: github.context, env: process.env };
const payloadString = payload.replaceAll('${{', '{{');
payload = markup.up(payloadString, context);
if (!useFileAsIs || useFileAsIs !== 'true') {
// parse github context variables
const context = { github: github.context, env: process.env };
const payloadString = payload.replaceAll('${{', '{{');
payload = markup.up(payloadString, context);
}
} catch (error) {
// passed in payload file path was invalid
console.error(error);
Expand Down Expand Up @@ -128,16 +131,20 @@ module.exports = async function slackSend(core) {

try {
await axios.post(webhookUrl, payload, axiosOpts);
// console.log(JSON.stringify(payload));
} catch (err) {
console.log('axios post failed, double check the payload being sent includes the keys Slack expects');
console.log(payload);
if ('toJSON' in err) {
console.error(JSON.stringify(err.toJSON()));
}
console.error(`Attempted to POST payload: ${JSON.stringify(payload)}`);
// console.log(err);

if (err.response) {
core.setFailed(err.response.data);
} else {
core.setFailed(err.message);
}

core.setFailed(err.message);
return;
}
}
Expand Down
24 changes: 24 additions & 0 deletions test/slack-send-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,30 @@ describe('slack-send', () => {
assert.equal(chatArgs.oliver, 'benji', 'Correct message provided to postMessage');
assert.equal(chatArgs.actor, 'user123', 'Correct message provided to postMessage');
});
it('should accept a payload-file-path and use it\'s content in the message without replacing anything', async () => {
// Prepare
fakeCore.getInput.withArgs('channel-id').returns('C123456');
zimeg marked this conversation as resolved.
Show resolved Hide resolved
fakeCore.getInput.withArgs('payload-file-path').returns('./test/resources/valid-payload.json');
fakeCore.getInput.withArgs('payload-file-path-parsed').returns('true');
fakeGithub.context.actor = 'user123';

// Run
await slackSend(fakeCore);

// Assert
assert.equal(fakeCore.setOutput.firstCall.firstArg, 'ts', 'Output name set to ts');
assert.equal(fakeCore.setOutput.secondCall.firstArg, 'thread_ts', 'Output name set to thread_ts');
assert(fakeCore.setOutput.secondCall.lastArg.length > 0, 'Time output a non-zero-length string');
assert.equal(fakeCore.setOutput.lastCall.firstArg, 'time', 'Output name set to time');
assert(fakeCore.setOutput.lastCall.lastArg.length > 0, 'Time output a non-zero-length string');
const chatArgs = ChatStub.postMessage.lastCall.firstArg;
assert.equal(chatArgs.channel, 'C123456', 'Correct channel provided to postMessage');
assert.equal(chatArgs.text, '', 'Correct message provided to postMessage');
assert.equal(chatArgs.bonny, 'clyde', 'Correct message provided to postMessage');
assert.equal(chatArgs.oliver, 'benji', 'Correct message provided to postMessage');
/* eslint-disable-next-line no-template-curly-in-string */
assert.equal(chatArgs.actor, '${{github.actor}}', 'Correct message provided to postMessage');
});

it('should send the same message to multiple channels', async () => {
fakeCore.getInput.withArgs('slack-message').returns('who let the dogs out?');
Expand Down
Loading