Skip to content

Commit

Permalink
feat: added discord webhook
Browse files Browse the repository at this point in the history
  • Loading branch information
mandarini committed Oct 13, 2023
1 parent 0b5686d commit 4d0b526
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/ecosystem-ci-selected.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,11 @@ jobs:
STATUS: ${{ job.status }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- if: always()
run: pnpm tsx discord-webhook.ts
env:
WORKFLOW_NAME: ci-selected
SUITE: ${{ inputs.suite }}
STATUS: ${{ job.status }}
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8 changes: 8 additions & 0 deletions .github/workflows/ecosystem-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,11 @@ jobs:
STATUS: ${{ job.status }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- if: always()
run: pnpm tsx discord-webhook.ts
env:
WORKFLOW_NAME: ci
SUITE: ${{ matrix.suite }}
STATUS: ${{ job.status }}
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
173 changes: 173 additions & 0 deletions discord-webhook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import fetch from 'node-fetch'
import { setupEnvironment } from './utils'

type Status = 'success' | 'failure' | 'cancelled'
type Env = {
WORKFLOW_NAME?: string
SUITE?: string
STATUS?: Status
DISCORD_WEBHOOK_URL?: string
}

const statusConfig = {
success: {
color: parseInt('57ab5a', 16),
emoji: ':white_check_mark:',
},
failure: {
color: parseInt('e5534b', 16),
emoji: ':x:',
},
cancelled: {
color: parseInt('768390', 16),
emoji: ':stop_button:',
},
}

async function run() {
if (!process.env.GITHUB_ACTIONS) {
throw new Error('This script can only run on GitHub Actions.')
}
if (!process.env.DISCORD_WEBHOOK_URL) {
console.warn(
"Skipped beacuse process.env.DISCORD_WEBHOOK_URL was empty or didn't exist",
)
return
}
if (!process.env.GITHUB_TOKEN) {
console.warn(
"Not using a token because process.env.GITHUB_TOKEN was empty or didn't exist",
)
}

const env = process.env as Env

assertEnv('WORKFLOW_NAME', env.WORKFLOW_NAME)
assertEnv('SUITE', env.SUITE)
assertEnv('STATUS', env.STATUS)
assertEnv('DISCORD_WEBHOOK_URL', env.DISCORD_WEBHOOK_URL)

await setupEnvironment()
const nxText = await nxRepoInfo()

const webhookContent = {
username: `nx-ecosystem-ci (${env.WORKFLOW_NAME})`,
avatar_url:
'https://raw.githubusercontent.com/nrwl/nx-ecosystem-ci/main/nx-logo.png',
embeds: [
{
title: `${statusConfig[env.STATUS].emoji} ${env.SUITE}`,
description: await createDescription(env.SUITE, nxText),
color: statusConfig[env.STATUS].color,
},
],
}

const res = await fetch(env.DISCORD_WEBHOOK_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(webhookContent),
})
if (res.ok) {
console.log('Sent Webhook')
} else {
console.error(`Webhook failed ${res.status}:`, await res.text())
}
}

function assertEnv<T>(
name: string,
value: T,
): asserts value is Exclude<T, undefined> {
if (!value) {
throw new Error(`process.env.${name} is empty or does not exist.`)
}
}

async function createRunUrl(suite: string) {
const result = await fetchJobs()
if (!result) {
return undefined
}

if (result.total_count <= 0) {
console.warn('total_count was 0')
return undefined
}

const job = result.jobs.find((job) => job.name === process.env.GITHUB_JOB)
if (job) {
return job.html_url
}

// when matrix
const jobM = result.jobs.find(
(job) => job.name === `${process.env.GITHUB_JOB} (${suite})`,
)
return jobM?.html_url
}

interface GitHubActionsJob {
name: string
html_url: string
}

async function fetchJobs() {
const url = `${process.env.GITHUB_API_URL}/repos/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/jobs`
const res = await fetch(url, {
headers: {
Accept: 'application/vnd.github.v3+json',
...(process.env.GITHUB_TOKEN
? {
Authorization: `token ${process.env.GITHUB_TOKEN}`,
// eslint-disable-next-line no-mixed-spaces-and-tabs
}
: undefined),
},
})
if (!res.ok) {
console.warn(
`Failed to fetch jobs (${res.status} ${res.statusText}): ${res.text()}`,
)
return null
}

const result = await res.json()
return result as {
total_count: number
jobs: GitHubActionsJob[]
}
}

async function createDescription(suite: string, targetText: string) {
const runUrl = await createRunUrl(suite)
const open = runUrl === undefined ? 'Null' : `[Open](${runUrl})`

return `
:scroll:\u00a0\u00a0${open}\u3000\u3000:zap:\u00a0\u00a0${targetText}
`.trim()
}

async function nxRepoInfo() {
const repoText = 'nrwl/nx'
const nextVersion = await nextNxVersion()

const link = `https://github.com/nrwl/nx/commits/${nextVersion}`
return `[${repoText}@${nextVersion}](${link})`
}

async function nextNxVersion(): Promise<string> {
return fetch(`https://registry.npmjs.org/nx`)
.then((response) => response.json())
.then(
(jsonData) =>
(jsonData as any)?.['dist-tags']?.['next'] ??
(jsonData as any)?.['dist-tags']?.['latest'],
)
}

run().catch((e) => {
console.error('Error sending webhook:', e)
})
Binary file added nx-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 4d0b526

Please sign in to comment.