Skip to content

Commit

Permalink
add payload output (#549)
Browse files Browse the repository at this point in the history
* add payload output

* add ack_no_webhook input

* update readme

* fix missing test

* revert wrongly included changes
  • Loading branch information
sarisia authored Aug 14, 2024
1 parent 31f9b74 commit 2a2cb30
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
contents: read
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332

- uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567
with:
registry: ghcr.io
Expand Down
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ For `if` parameter, see
| noprefix | No | `true` or `false` | `false` | Set `true` to avoid appending job status (`Success: `, etc.) to title |
| nodetail | No | `true` or `false` | `false` | Set `true` will set both `nocontext` and `noprefix` to `true` |
| notimestamp | No | `true` or `false` | `false` | Set `true` to avoid appending timestamp |
| ack_no_webhook | No | `true` or `false` | `false` | Set `true` to suppress warnings when no Webhook endpoint is given |


<details>
Expand All @@ -119,6 +120,14 @@ For `if` parameter, see

Just change `job` to `title` in your workflow file to make it work. -->


### Outputs

| Key | Description |
| - | - |
| payload | Discord webhook payload. See [Full payload control](#full-payload-control) |


## Tips

### Using markdown
Expand Down Expand Up @@ -171,6 +180,40 @@ If some of these webhooks are failed, other deliveries will **NOT** be cancelled
If the option `nofail` is set to `false` and any of one fail, the action will set
workflow status to `Failure`.

### Full payload control

You can modify payload before sending to Discord:

```yaml
- uses: sarisia/actions-status-discord@v1
if: always()
id: webhook # set id to reference output payload later
with:
ack_no_webhook: true # set this to suppress warning
# you can omit webhook input (or DISCORD_WEBHOOK environment variable)
- run: npm install axios
- uses: actions/github-script@v7
env:
WEBHOOK_PAYLOAD: ${{ steps.webhook.outputs.payload }}
WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK }}
with:
script: |
const axios = require("axios")
const { WEBHOOK_PAYLOAD, WEBHOOK_URL } = process.env
const payload = JSON.parse(WEBHOOK_PAYLOAD)
// modify payload as you like
delete payload.embeds[0].color
// send to Discord
axios.post(WEBHOOK_URL, payload)
```

[See actions/github-script docs](https://github.com/actions/github-script)

### GHES, Gitea and Forgejo

This actions may work with [GHES](https://docs.github.com/en/[email protected]/admin/github-actions/managing-access-to-actions-from-githubcom/about-using-actions-in-your-enterprise), [Gitea](https://blog.gitea.io/2022/12/feature-preview-gitea-actions/) and [Forgejo](https://forgejo.org/2023-02-27-forgejo-actions/), but not tested against yet.
Expand Down
8 changes: 8 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ inputs:
description: "Avoid appending timestamp"
required: false
default: "false"
ack_no_webhook:
description: "Suppress warning when webhook is not set"
required: false
default: "false"

outputs:
payload:
description: "Discord webhook payload"

runs:
using: "node20"
Expand Down
8 changes: 5 additions & 3 deletions src/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface Inputs {
nocontext: boolean
noprefix: boolean
notimestamp: boolean
ack_no_webhook: boolean
}

interface StatusOption {
Expand Down Expand Up @@ -70,12 +71,13 @@ export function getInputs(): Inputs {
avatar_url: core.getInput('avatar_url').trim(),
nocontext: nocontext,
noprefix: noprefix,
notimestamp: stob(core.getInput('notimestamp'))
notimestamp: stob(core.getInput('notimestamp')),
ack_no_webhook: stob(core.getInput('ack_no_webhook'))
}

// validate
if (!inputs.webhooks.length) {
throw new Error("no webhook is given")
if (!inputs.webhooks.length && !inputs.ack_no_webhook) {
logWarning("No webhook is given. If this is intended, you can suppress this warning by setting `ack_no_webhook` to `true`.")
}
if (!(inputs.status in statusOpts)) {
throw new Error(`invalid status value: ${inputs.status}`)
Expand Down
10 changes: 7 additions & 3 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { endGroup, startGroup } from '@actions/core'
import { endGroup, startGroup, setOutput } from '@actions/core'
import * as github from '@actions/github'
import axios from 'axios'
import { formatEvent } from './format'
Expand All @@ -13,12 +13,16 @@ async function run() {

logInfo('Generating payload...')
const payload = getPayload(inputs)
startGroup('Dump payload')
logInfo(JSON.stringify(payload, null, 2))
const payloadStr = JSON.stringify(payload, null, 2)
startGroup('Dump payload (You can access the payload as `${{ steps.<step_id>.outputs.payload }}` in latter steps)')
logInfo(payloadStr)
endGroup()

logInfo(`Triggering ${inputs.webhooks.length} webhook${inputs.webhooks.length > 1 ? 's' : ''}...`)
await Promise.all(inputs.webhooks.map(w => wrapWebhook(w.trim(), payload)))

// set output
setOutput('payload', payloadStr)
} catch (e: any) {
logError(`Unexpected failure: ${e} (${e.message})`)
}
Expand Down
10 changes: 5 additions & 5 deletions test/input.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ describe("getInputs()", () => {
process.env['INPUT_NOPREFIX'] = 'false'
process.env['INPUT_NODETAIL'] = 'false'
process.env['INPUT_NOTIMESTAMP'] = 'false'
process.env['INPUT_ACKNOWEBHOOK'] = 'false'

// no defaults in action.yml, but need for passing validation
process.env['DISCORD_WEBHOOK'] = "https://env.webhook.invalid"
Expand All @@ -34,11 +35,7 @@ describe("getInputs()", () => {
expect(got.color).toBe(undefined)
expect(got.username).toBe('')
expect(got.avatar_url).toBe('')
})

test("no webhooks", () => {
delete process.env['DISCORD_WEBHOOK']
expect(getInputs).toThrow("no webhook is given")
expect(got.ack_no_webhook).toBe(false)
})

test("invalid status", () => {
Expand Down Expand Up @@ -130,6 +127,7 @@ describe("getInputs()", () => {
process.env['INPUT_COLOR'] = '0xffffff'
process.env['INPUT_USERNAME'] = 'jest test'
process.env['INPUT_AVATAR_URL'] = '\n\n\nhttps://avatar.webhook.invalid\n'
process.env['INPUT_ACK_NO_WEBHOOK'] = 'true'

const got = getInputs()
expect(got.noprefix).toBe(true)
Expand All @@ -146,5 +144,7 @@ describe("getInputs()", () => {
expect(got.color).toBe(0xffffff)
expect(got.username).toBe('jest test')
expect(got.avatar_url).toBe('https://avatar.webhook.invalid')
expect(got.noprefix).toBe(true)
expect(got.ack_no_webhook).toBe(true)
})
})
3 changes: 2 additions & 1 deletion test/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ describe('getPayload(Inputs)', () => {
color: undefined,
url: '',
username: '',
avatar_url: ''
avatar_url: '',
ack_no_webhook: false
}

test("default", () => {
Expand Down

0 comments on commit 2a2cb30

Please sign in to comment.