From e6c0fa5c335e0d1853a41195065f10b2f9fe3635 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Tue, 23 Jan 2024 15:28:28 -0600 Subject: [PATCH] chore(ci): fix release announcement script (#9796) --- .../index.js => .github/scripts/announce.js | 66 +++++++++---------- .github/scripts/utils.mjs | 59 +++++++++++++++++ .github/workflows/release.yml | 13 +++- 3 files changed, 99 insertions(+), 39 deletions(-) rename scripts/notify/index.js => .github/scripts/announce.js (80%) create mode 100644 .github/scripts/utils.mjs diff --git a/scripts/notify/index.js b/.github/scripts/announce.js similarity index 80% rename from scripts/notify/index.js rename to .github/scripts/announce.js index 7dd8a37517..6ac4c2d3ba 100755 --- a/scripts/notify/index.js +++ b/.github/scripts/announce.js @@ -1,6 +1,7 @@ import { globby as glob } from 'globby'; import { fileURLToPath } from 'node:url'; import { readFile } from 'node:fs/promises'; +import { setOutput } from './utils.mjs'; const { GITHUB_REF = 'main' } = process.env; const baseUrl = new URL(`https://github.com/withastro/astro/blob/${GITHUB_REF}/`); @@ -17,34 +18,34 @@ const descriptors = [ 'updates', ]; const verbs = [ - 'just went out!', - 'just launched!', - 'now available!', - 'in the wild!', - 'now live!', - 'hit the registry!', - 'to share!', - 'for you!', - 'for y’all! 🤠', - 'comin’ your way!', - 'comin’ atcha!', - 'comin’ in hot!', - 'freshly minted on the blockchain! (jk)', - '[is] out (now with 100% more reticulated splines!)', - '(as seen on TV!)', - 'just dropped!', - '– artisanally hand-crafted just for you.', - '– oh happy day!', - '– enjoy!', - 'now out. Be the first on your block to download!', - 'made with love 💕', - '[is] out! Our best [version] yet!', - '[is] here. DOWNLOAD! DOWNLOAD! DOWNLOAD!', - '... HUZZAH!', - '[has] landed!', - 'landed! The internet just got a little more fun.', - '– from our family to yours.', - '– go forth and build!', + "just went out!", + "just launched!", + "now available!", + "in the wild!", + "now live!", + "hit the registry!", + "to share!", + "for you!", + "for y’all! 🤠", + "comin’ your way!", + "comin’ atcha!", + "comin’ in hot!", + "freshly minted on the blockchain! (jk)", + "[is] out (now with 100% more reticulated splines!)", + "(as seen on TV!)", + "just dropped!", + "– artisanally hand-crafted just for you.", + "– oh happy day!", + "– enjoy!", + "now out. Be the first on your block to download!", + "made with love 💕", + "[is] out! Our best [version] yet!", + "[is] here. DOWNLOAD! DOWNLOAD! DOWNLOAD!", + "... HUZZAH!", + "[has] landed!", + "landed! The internet just got a little more fun.", + "– from our family to yours.", + "– go forth and build!" ]; const extraVerbs = [ 'new', @@ -162,14 +163,7 @@ async function run() { process.exit(1); } const content = await generateMessage(); - - await fetch(`${process.env.DISCORD_WEBHOOK}?wait=true`, { - method: 'POST', - body: JSON.stringify({ content }), - headers: { - 'content-type': 'application/json', - }, - }); + setOutput('DISCORD_MESSAGE', content); } run(); diff --git a/.github/scripts/utils.mjs b/.github/scripts/utils.mjs new file mode 100644 index 0000000000..da5befc2c2 --- /dev/null +++ b/.github/scripts/utils.mjs @@ -0,0 +1,59 @@ +import * as fs from 'node:fs' +import * as os from 'node:os' +import * as crypto from 'node:crypto' + +/** Based on https://github.com/actions/toolkit/blob/4e3b068ce116d28cb840033c02f912100b4592b0/packages/core/src/file-command.ts */ +export function setOutput(key, value) { + const filePath = process.env['GITHUB_OUTPUT'] || '' + if (filePath) { + return issueFileCommand('OUTPUT', prepareKeyValueMessage(key, value)) + } + process.stdout.write(os.EOL) +} + +function issueFileCommand(command, message) { + const filePath = process.env[`GITHUB_${command}`] + if (!filePath) { + throw new Error( + `Unable to find environment variable for file command ${command}` + ) + } + if (!fs.existsSync(filePath)) { + throw new Error(`Missing file at path: ${filePath}`) + } + + fs.appendFileSync(filePath, `${toCommandValue(message)}${os.EOL}`, { + encoding: 'utf8' + }) +} + +function prepareKeyValueMessage(key, value) { + const delimiter = `gh-delimiter-${crypto.randomUUID()}` + const convertedValue = toCommandValue(value) + + // These should realistically never happen, but just in case someone finds a + // way to exploit uuid generation let's not allow keys or values that contain + // the delimiter. + if (key.includes(delimiter)) { + throw new Error( + `Unexpected input: name should not contain the delimiter "${delimiter}"` + ) + } + + if (convertedValue.includes(delimiter)) { + throw new Error( + `Unexpected input: value should not contain the delimiter "${delimiter}"` + ) + } + + return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}` +} + +function toCommandValue(input) { + if (input === null || input === undefined) { + return '' + } else if (typeof input === 'string' || input instanceof String) { + return input + } + return JSON.stringify(input) +} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d25ec07e56..3f8eb59369 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -59,9 +59,16 @@ jobs: # Needs access to publish to npm NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - - name: Generate Notification - id: notification + - name: Generate Announcement + id: message if: steps.changesets.outputs.published == 'true' env: DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} - run: node scripts/notify/index.js '${{ steps.changesets.outputs.publishedPackages }}' + run: node .github/scripts/announce.mjs '${{ steps.changesets.outputs.publishedPackages }}' + + - name: Send message on Discord + env: + DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} + uses: Ilshidur/action-discord@0.3.2 + with: + args: "${{ steps.message.outputs.DISCORD_MESSAGE }}"