From c74ae6c1ca0ce50f01a48e8ad19bc9b5a3ca76d5 Mon Sep 17 00:00:00 2001 From: LekoArts Date: Wed, 23 Oct 2024 13:39:54 -0400 Subject: [PATCH] initial --- .github/utils/slack-notify.mjs | 76 +++++++++++++++++++++++ .github/workflows/linear-notification.yml | 31 +++++++++ .github/workflows/slack-notification.yml | 37 +++++++++++ 3 files changed, 144 insertions(+) create mode 100644 .github/utils/slack-notify.mjs create mode 100644 .github/workflows/linear-notification.yml create mode 100644 .github/workflows/slack-notification.yml diff --git a/.github/utils/slack-notify.mjs b/.github/utils/slack-notify.mjs new file mode 100644 index 0000000..32507e2 --- /dev/null +++ b/.github/utils/slack-notify.mjs @@ -0,0 +1,76 @@ +/** + * @typedef {Object} Actor + * @property {string} username + * @property {string} avatarUrl + * @property {string} profileUrl + */ + +/** + * @typedef {Object} PRData + * @property {string} title + * @property {string} body + * @property {Actor} actor + */ + +/** + * @typedef {Object} Formatter + * @property {(data: PRData) => string} generateMsg + */ + +/** + * Slack is using their own Markdown format, see: + * https://api.slack.com/reference/surfaces/formatting#basics + * https://app.slack.com/block-kit-builder + * @type {Formatter} + */ +const slackFormatter = { + generateMsg: ({ title, body, actor }) => { + const markdown = text => ({ type: 'section', text: { type: 'mrkdwn', text } }); + const header = text => ({ type: 'header', text: { type: 'plain_text', text } }); + const context = (imgUrl, text) => ({ + type: 'context', + elements: [ + ...(imgUrl ? [{ type: 'image', image_url: imgUrl, alt_text: 'avatar' }] : []), + { type: 'mrkdwn', text }, + ], + }); + const blocks = []; + + blocks.push(header(`openapi-specs: ${title}`)); + + blocks.push(markdown(body)); + blocks.push(markdown('\n')); + blocks.push(context(actor.avatarUrl, `<${actor.profileUrl}|*${actor.username}*> created this PR.`)); + + return JSON.stringify({ blocks }); + }, +}; + +/** + * @type {Record} + */ +const formatters = { + slack: slackFormatter, +}; + +/* + * @returns {Actor} + */ +const createActor = username => { + return { username, avatarUrl: `https://github.com/${username}.png`, profileUrl: `https://github.com/${username}` }; +}; + +const run = async () => { + const { title, user } = JSON.parse(process.argv[2]); + const body = process.argv[3]; + const actor = createActor(user.login); + + const formatter = formatters['slack']; + if (!formatter) { + throw new Error('Invalid formatter, supported formatters are: ' + Object.keys(formatters).join(', ')); + } + + console.log(formatter.generateMsg({ title, body, actor })); +} + +run() \ No newline at end of file diff --git a/.github/workflows/linear-notification.yml b/.github/workflows/linear-notification.yml new file mode 100644 index 0000000..eec0a0e --- /dev/null +++ b/.github/workflows/linear-notification.yml @@ -0,0 +1,31 @@ +name: Create Linear ticket + +on: + pull_request: + types: [opened] + +jobs: + linear-ticket: + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - name: Create Linear ticket + id: createIssue + uses: ctriolo/action-create-linear-issue@v0.5 + with: + linear-api-key: ${{ secrets.LINEAR_API_KEY }} + linear-team-key: "ECO" + linear-issue-title: ${{ github.event.pull_request.title }} + linear-issue-description: ${{ github.event.pull_request.body }} + linear-attachment-url: ${{ github.event.pull_request.html_url }} + linear-attachment-title: ${{ github.event.pull_request.title }} + + - name: Create comment for Linear ticket link + uses: marocchino/sticky-pull-request-comment@v2.8.0 + with: + GITHUB_TOKEN: ${{ secrets.CLERK_COOKIE_PAT }} + number: ${{ github.event.issue.number }} + header: linear-issue-url + message: | + A Linear ticket has been created for this PR: ${{ steps.createIssue.outputs.linear-issue-url }} \ No newline at end of file diff --git a/.github/workflows/slack-notification.yml b/.github/workflows/slack-notification.yml new file mode 100644 index 0000000..c4d571b --- /dev/null +++ b/.github/workflows/slack-notification.yml @@ -0,0 +1,37 @@ +name: Slack Notification + +on: + pull_request: + types: [opened] + +jobs: + slack-notify: + name: Slack Notification + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + show-progress: false + - name: Convert PR body to Slack format + id: slackify + uses: LoveToKnow/slackify-markdown-action@v1.1.1 + with: + text: ${{ github.event.pull_request.body }} + - name: Generate notification payload + id: notification + env: + BODY: ${{ github.event.pull_request.body }} + PULL_REQUEST_DATA: ${{ toJson(github.event.pull_request) }} + run: | + payload=$(node ./.github/utils/slack-notify.mjs '${{ env.PULL_REQUEST_DATA }}' '${{ steps.slackify.outputs.text }}') + echo "payload=${payload//$'\n'/'%0A'}" >> $GITHUB_OUTPUT + - name: Send PR to Slack + id: slack + uses: slackapi/slack-github-action@v1.27.0 + with: + payload: ${{ steps.notification.outputs.payload }} + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CHANGELOG_WEBHOOK_URL }} + SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK \ No newline at end of file