Wiki Alert #975
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Wiki Alert | |
| # The alert is not sent for all wiki changes: | |
| # | |
| # The "gollum" event only fires whenever the wiki HEAD changes, only considering the | |
| # changes in the latest commit, and only if the pages were created or modified, not | |
| # deleted. But pushing multiple commits is limited to GitHub collaborators (or above). | |
| on: gollum | |
| jobs: | |
| notify: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Secret Check | |
| id: secret | |
| run: echo "empty=${{secrets.WIKI_WEBHOOK == ''}}" >> $GITHUB_OUTPUT | |
| - name: Checkout | |
| if: steps.secret.outputs.empty == 'false' | |
| uses: actions/checkout@v6 | |
| with: | |
| repository: ${{github.repository}}.wiki | |
| - name: Send Webhook | |
| if: steps.secret.outputs.empty == 'false' | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| // https://docs.discord.com/developers/resources/message#embed-object-embed-limits | |
| const limits = { | |
| message: 6000, | |
| description: 4096, | |
| embeds: 10, | |
| fields: 25, | |
| }; | |
| const messageConfig = { | |
| username: "Wiki Updates", | |
| avatar: "https://files.jasperlorelai.eu/magicspells/images/webhook_icon.png" | |
| }; | |
| /** | |
| * @typedef {Object} EmbedFooter | |
| * @property {string=} text | |
| */ | |
| /** | |
| * @typedef {Object} EmbedAuthor | |
| * @property {string=} name | |
| * @property {string=} url | |
| * @property {string=} url_icon | |
| */ | |
| /** | |
| * @typedef {Object} EmbedField | |
| * @property {string} name | |
| * @property {string} value | |
| * @property {boolean=} inline | |
| */ | |
| /** | |
| * @typedef {Object} Embed | |
| * @property {string=} title | |
| * @property {string=} url | |
| * @property {string=} description | |
| * @property {EmbedFooter=} footer | |
| * @property {EmbedAuthor=} author | |
| * @property {EmbedField[]=} fields | |
| */ | |
| if (!context.payload.pages?.length) { | |
| core.info("No pages in payload."); | |
| return; | |
| } | |
| // Commit sha/message will be shared across pages in a "gollum" event. | |
| const {sha} = context.payload.pages[0]; | |
| const {stdout} = await exec.getExecOutput(`git log -1 --pretty=format:"%B" ${sha}`); | |
| let description = ""; | |
| for (const line of stdout.trim().split("\n")) { | |
| description += "\n> " + line; | |
| } | |
| if (description.length > limits.description) { | |
| description = description.substring(0, limits.description - 3) + "..."; | |
| } | |
| // Array of batched 10 max embeds per element. | |
| /** @type {Array<Embed[]>} */ | |
| const batches = []; | |
| for (const {title, html_url} of context.payload.pages) { | |
| /** @type {EmbedField} */ | |
| const field = { | |
| inline: true, | |
| name: title, | |
| value: `-# [Page](${html_url}/${sha}) • [Changes](${html_url}/_compare/${sha})` | |
| }; | |
| let messageSize = field.name.length + field.value.length; | |
| if (batches.length) { | |
| for (const embed of batches.at(-1)) { | |
| messageSize += (embed.title?.length || 0) + | |
| (embed.description?.length || 0) + | |
| (embed.footer?.text?.length || 0) + | |
| (embed.author?.name?.length || 0); | |
| if (!embed.fields?.length) continue; | |
| for (const field of embed.fields) { | |
| messageSize += field.name.length + field.value.length; | |
| } | |
| } | |
| } | |
| const needsNewBatch = !batches.length || | |
| batches.at(-1).length >= limits.embeds || | |
| messageSize >= limits.message; | |
| if (needsNewBatch) batches.push([{ | |
| title: "Pages Changed", | |
| url: `${html_url.substring(0, html_url.lastIndexOf("/"))}/_compare/${sha}`, | |
| description, | |
| author: { | |
| name: "Edited by: " + context.payload.sender.login, | |
| url: context.payload.sender.html_url, | |
| icon_url: context.payload.sender.avatar_url, | |
| }, | |
| fields: [] | |
| }]); | |
| const needsNewEmbed = batches.at(-1).at(-1).fields.length >= limits.fields; | |
| if (needsNewEmbed) batches.at(-1).push({fields: []}); | |
| batches.at(-1).at(-1).fields.push(field); | |
| } | |
| for (const embeds of batches) { | |
| const message = { | |
| username: messageConfig.username, | |
| avatar_url: messageConfig.avatar, | |
| embeds | |
| }; | |
| await fetch("${{secrets.WIKI_WEBHOOK}}", { | |
| method: "POST", | |
| headers: {"Content-Type": "application/json"}, | |
| body: JSON.stringify(message) | |
| }).catch(error => core.setFailed(error.message)); | |
| } |