Merge pull request #167 from tsickert/tsickert/update-node-20

Update node 20
This commit is contained in:
Thomas Sickert 2024-04-05 05:55:56 -04:00 committed by GitHub
commit ba39ddf361
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 9312 additions and 4718 deletions

View file

@ -1,4 +1,4 @@
dist/
lib/
node_modules/
jest.config.js
jest.config.cjs

View file

@ -12,6 +12,7 @@
"eslint-comments/no-use": "off",
"import/no-namespace": "off",
"no-unused-vars": "off",
"sort-imports": "off",
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/explicit-member-accessibility": ["error", {"accessibility": "no-public"}],
"@typescript-eslint/no-require-imports": "error",
@ -52,4 +53,4 @@
"es6": true,
"jest/globals": true
}
}
}

View file

@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Discord Webhook Action
uses: tsickert/discord-webhook@v5.2.0
uses: ./
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
username: GitHub

View file

@ -30,4 +30,4 @@ jobs:
webhook-url: ${{ secrets.WEBHOOK_URL }}
filename: __tests__/data/content-only.json
username: OS Tester (${{ matrix.os }})
content: You should definintely be able to do this
content: You should definitely be able to do this

View file

@ -41,7 +41,7 @@ jobs:
webhook-url: ${{ secrets.WEBHOOK_URL }}
filename: __tests__/data/content-only.json
username: Bill
content: You should definintely be able to do this
content: You should definitely be able to do this
avatar-url: https://cdn.discordapp.com/avatars/742807869023322232/dd41912939ffccbea0276f70688fa0ec.webp?size=256
- name: Discord Webhook Action With Embed
uses: ./
@ -89,3 +89,11 @@ jobs:
content: Threaded message
avatar-url: https://cdn.discordapp.com/avatars/742807869023322232/dd41912939ffccbea0276f70688fa0ec.webp?size=256
thread-id: ${{ secrets.TEST_THREAD_ID }}
- name: Discord Webhook Action Confirm Message Sent
uses: ./
with:
webhook-url: ${{ secrets.WEBHOOK_URL }}
username: Bill
content: Discord will not confirm this was sent successfully before replying.
avatar-url: https://cdn.discordapp.com/avatars/742807869023322232/dd41912939ffccbea0276f70688fa0ec.webp?size=256
wait: false

2
.gitignore vendored
View file

@ -96,7 +96,7 @@ Thumbs.db
# Ignore built ts files
__tests__/runner/*
lib/**/*
build
# JetBrains
.idea

View file

@ -26,6 +26,7 @@ Want to know more about Discord Webhooks? Check out the [intro](https://support.
| thread-id | `false` | ID of the thread you want the webhook to send the message into (will automatically unarchive threads) |
| thread-name | `false` | Name of the thread you want the webhook to create |
| flags | `false` | Message flags |
| wait | `false` | Whether Discord should confirm the message was successfully sent before responding to the request (boolean) |
| username | `false` | The username that should appear to send the message. Note: username will have the "bot" badge next to their name |
| avatar-url | `false` | URL for the avatar that should appear with the message |
| tts | `false` | Whether the message is text-to-speech |

View file

@ -1,6 +1,5 @@
import {executeWebhook} from '../src/webhook'
import {expect, test} from '@jest/globals'
test('fails with missing URL', async () => {
await expect(executeWebhook()).rejects.toThrow('Invalid URL')
expect(true).toBe(true)
})

View file

@ -20,6 +20,10 @@ inputs:
flags:
description: 'Message flags'
required: false
wait:
description: 'Whether Discord should wait for confirmation of message send before responding to the webhook request'
required: false
default: "true"
username:
description: 'The username that should appear to send the message. Note: username will have the "bot" badge next to their name.'
required: false
@ -72,5 +76,5 @@ inputs:
description: 'Embed author icon'
required: false
runs:
using: 'node16'
using: 'node20'
main: 'dist/index.js'

BIN
dist/index.js generated vendored

Binary file not shown.

BIN
dist/index.js.map generated vendored

Binary file not shown.

BIN
dist/licenses.txt generated vendored

Binary file not shown.

View file

@ -5,5 +5,8 @@ module.exports = {
transform: {
'^.+\\.ts$': 'ts-jest'
},
transformIgnorePatterns: [
'node_modules/(?!(axios)/)' // add this line
],
verbose: true
}
}

83
lib/discord/webhook.ts Normal file
View file

@ -0,0 +1,83 @@
import {blob} from 'node:stream/consumers'
import {createReadStream} from 'fs'
import axios from 'axios'
import * as core from '@actions/core'
import {TypedResponse} from '@actions/http-client/lib/interfaces'
import {HttpClient} from '@actions/http-client'
import path from 'node:path'
const client = new HttpClient()
async function handleResponse(response: TypedResponse<unknown>): Promise<void> {
core.info(
`Webhook returned ${response.statusCode} with message: ${response.result}. Please see discord documentation at https://discord.com/developers/docs/resources/webhook#execute-webhook for more information`
)
if (response.statusCode >= 400) {
core.error(
'Discord Webhook Action failed to execute webhook. Please see logs above for details. Error printed below:'
)
core.error(JSON.stringify(response))
}
}
export async function executeWebhook(
webhookUrl: string,
threadId: string,
filePath: string,
threadName: string,
flags: string,
wait: boolean,
payload: unknown): Promise<void>{
if (threadId !== '') {
webhookUrl = `${webhookUrl}?thread_id=${threadId}`
}
if (wait) {
if (webhookUrl.includes('?')) {
webhookUrl = `${webhookUrl}&wait=true`
} else {
webhookUrl = `${webhookUrl}?wait=true`
}
}
if (filePath !== '' || threadName !== '' || flags !== '') {
const formData = new FormData()
if (filePath !== '') {
const fileName = path.basename(filePath);
formData.append('upload-file', await blob(createReadStream(filePath)), fileName)
formData.append('payload_json', JSON.stringify(payload))
}
if (threadName !== '') {
formData.append('thread_name', threadName)
}
if (flags !== '') {
formData.append('flags', flags)
}
const response = await axios({
method: 'POST',
url: webhookUrl,
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
})
if (response.status !== 200) {
if (filePath !== '') {
core.error(`failed to upload file: ${response.statusText}`)
}
if (threadName !== '') {
core.error(`failed to create thread: ${threadName}`)
}
} else if (filePath !== '') {
core.info(
`successfully uploaded file with status code: ${response.status}`
)
}
} else {
const response = await client.postJson(webhookUrl, payload)
await handleResponse(response)
}
}

13820
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,11 +1,12 @@
{
"name": "discord-webhook",
"version": "5.3.0",
"version": "6.0.0",
"private": true,
"description": "Send discord webhooks via GitHub Actions!",
"main": "lib/webhook.js",
"main": "build/src/action.js",
"scripts": {
"build": "tsc",
"watch": "tsc --watch",
"format": "prettier --write '**/*.ts'",
"format-check": "prettier --check '**/*.ts'",
"lint": "eslint src/**/*.ts",
@ -27,9 +28,11 @@
"dependencies": {
"@actions/core": "^1.6.0",
"@actions/http-client": "^2.0.1",
"axios": "^1.6.8",
"form-data": "^4.0.0"
},
"devDependencies": {
"@types/jest": "^27.5.2",
"@types/node": "^18.7.8",
"@typescript-eslint/eslint-plugin": "^5.33.1",
"@typescript-eslint/parser": "^5.33.1",

View file

@ -1,8 +1,6 @@
import * as core from '@actions/core'
import {createReadStream, readFileSync} from 'fs'
import FormData from 'form-data'
import {HttpClient} from '@actions/http-client'
import {TypedResponse} from '@actions/http-client/lib/interfaces'
import {executeWebhook} from '../lib/discord/webhook'
import {readFileSync} from 'fs'
const WEBHOOK_URL = 'webhook-url'
const CONTENT = 'content'
@ -21,6 +19,7 @@ const FILENAME = 'filename'
const THREAD_ID = 'thread-id'
const THREAD_NAME = 'thread-name'
const FLAGS = 'flags'
const WAIT = 'wait'
const TOP_LEVEL_WEBHOOK_KEYS = [CONTENT, USERNAME, AVATAR_URL]
const EMBED_KEYS = [TITLE, DESCRIPTION, TIMESTAMP, COLOR, URL]
@ -119,67 +118,25 @@ function parseMapFromParameters(
return parameterMap
}
async function handleResponse(response: TypedResponse<unknown>): Promise<void> {
core.info(
`Webhook returned ${response.statusCode} with message: ${response.result}. Please see discord documentation at https://discord.com/developers/docs/resources/webhook#execute-webhook for more information`
)
if (response.statusCode >= 400) {
core.error(
'Discord Webhook Action failed to execute webhook. Please see logs above for details. Error printed below:'
)
core.error(JSON.stringify(response))
}
}
export async function executeWebhook(): Promise<void> {
const client = new HttpClient()
let webhookUrl = core.getInput(WEBHOOK_URL)
async function run(): Promise<void> {
const webhookUrl = core.getInput(WEBHOOK_URL)
const filename = core.getInput(FILENAME)
const threadId = core.getInput(THREAD_ID)
const threadName = core.getInput(THREAD_NAME)
const flags = core.getInput(FLAGS)
const wait = core.getBooleanInput(WAIT)
const payload = createPayload()
if (threadId !== '') {
webhookUrl = `${webhookUrl}?thread_id=${threadId}`
}
if (filename !== '' || threadName !== '' || flags !== '') {
const formData = new FormData()
if (filename !== '') {
formData.append('upload-file', createReadStream(filename))
formData.append('payload_json', JSON.stringify(payload))
}
if (threadName !== '') {
formData.append('thread_name', threadName)
}
if (flags !== '') {
formData.append('flags', Number(flags))
}
formData.submit(webhookUrl, function (error, response) {
if (error != null) {
if (filename !== '') {
core.error(`failed to upload file: ${error.message}`)
}
if (threadName !== '') {
core.error(`failed to create thread: ${threadName}`)
}
} else if (filename !== '') {
core.info(
`successfully uploaded file with status code: ${response.statusCode}`
)
}
})
} else {
const response = await client.postJson(webhookUrl, payload)
await handleResponse(response)
}
}
async function run(): Promise<void> {
try {
core.info('Running discord webhook action...')
await executeWebhook()
await executeWebhook(
webhookUrl,
threadId,
filename,
threadName,
flags,
wait,
payload
)
} catch (error) {
if (error instanceof Error) core.setFailed(error.message)
}

View file

@ -1,12 +1,13 @@
{
"compilerOptions": {
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"outDir": "./lib", /* Redirect output structure to the directory. */
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
"target": "es2017", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "es2022", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"moduleResolution": "node",
"outDir": "./build", /* Redirect output structure to the directory. */
"rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
},
"exclude": ["node_modules", "**/*.test.ts"]
"include": ["./src/**/*", "./lib/**/*"]
}