Compare commits

...
22 Commits
Author SHA1 Message Date
SethCohen e1dc0826fe chore(master): release 1.17.0 (#47) 2025-06-16 22:50:30 -04:00
SethCohen e768ce1023 feat(workflow): add GitHub Actions workflow to automatically update SemVer tags on tag push events 2025-06-16 22:49:57 -04:00
SethCohen 6ac5abea42 chore(master): release 1.16.2 (#40) 2024-10-18 00:14:56 -04:00
SethCohen 6aa0dd988c docs: update README output example 2024-10-18 00:09:28 -04:00
SethCohen 1e7bdfd173 chore(master): release 1.16.1 (#39) 2024-10-18 00:03:36 -04:00
SethCohen 47869497ed fix: correct conversion of standalone PR, issue, and changelog URLs to markdown format
resolves #38
2024-10-18 00:02:43 -04:00
SethCohen 9737dc9002 docs: update README with details on markdown link conversion and other features 2024-10-17 23:37:47 -04:00
SethCohen 26399c645d chore(master): release 1.16.0 (#37) 2024-10-17 23:08:50 -04:00
SethCohen 07c2e1c3e6 feat: add function to convert PR, issue, and changelog links to markdown format
resolves #32
2024-10-17 23:07:57 -04:00
SethCohen f184bc59c7 chore(master): release 1.15.3 (#36) 2024-10-17 22:54:26 -04:00
SethCohen 3449e38629 chore: update .gitignore 2024-10-17 22:52:48 -04:00
SethCohen 93d02ce871 docs: update version reference in README.md 2024-10-17 22:52:48 -04:00
SethCohen 5dc41089e6 chore: update package-lock.json 2024-10-17 22:52:48 -04:00
SethCohen 5fd64bf266 docs: add contribution guidelines to README.md 2024-10-17 22:52:48 -04:00
SethCohen 60a5c60e64 chore(master): release 1.15.2 (#35) 2024-10-17 21:16:41 -04:00
Doug Richar 925765f099 fix: improve @mention parsing for GitHub usernames (#33)
- Update regex to correctly identify valid GitHub usernames
- Prevent false positives for package names and email addresses
- Exclude matches within code snippets, URLs, and Markdown links
2024-10-17 21:08:36 -04:00
SethCohen 37afa88c8c chore(master): release 1.15.1 (#31) 2024-10-04 17:44:13 -04:00
SethCohen 735cca9de3 chore: added test envs to .gitignore 2024-10-04 17:42:56 -04:00
SethCohen 5ca1453a69 refactor: code cleanup 2024-10-04 17:42:25 -04:00
SethCohen 305fe9299d chore: updated test action 2024-10-04 17:26:19 -04:00
SethCohen 613ba269d7 docs: updated README.md 2024-10-04 17:25:52 -04:00
Kamron Batman 940a1bd2d2 Adds usernames to formatDescription (#28)
* Adds usernames to formatDescription

* Formatting
2024-10-04 08:40:24 -04:00
9 changed files with 383 additions and 147 deletions
+11 -1
View File
@@ -11,4 +11,14 @@ jobs:
- name: Github Releases To Discord - name: Github Releases To Discord
uses: ./ # Uses an action in the root directory uses: ./ # Uses an action in the root directory
with: with:
webhook_url: ${{ secrets.WEBHOOK_URL }} webhook_url: ${{ inputs.WEBHOOK_URL }}
color: ${{ inputs.COLOR }}
username: ${{ inputs.USERNAME }}
avatar_url: ${{ inputs.AVATAR_URL }}
content: ${{ inputs.CONTENT }}
footer_title: ${{ inputs.FOOTER_TITLE }}
footer_icon_url: ${{ inputs.FOOTER_ICON_URL }}
footer_timestamp: ${{ inputs.FOOTER_TIMESTAMP }}
max_description: ${{ inputs.MAX_DESCRIPTION }}
reduce_headings: ${{ inputs.REDUCE_HEADINGS }}
+15
View File
@@ -0,0 +1,15 @@
name: Update SemVer Tags
on:
push:
branches-ignore:
- '**'
tags:
- 'v*.*.*'
jobs:
update_semver:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Update semver tags
uses: haya14busa/action-update-semver@v1
+6
View File
@@ -2,3 +2,9 @@
*.iml *.iml
out out
gen gen
.env
tests/sample-test-release.json
release.json
repository.json
user.json
tests/sample-test-release-v2.json
+72
View File
@@ -1,5 +1,77 @@
# Changelog # Changelog
## [1.17.0](https://github.com/SethCohen/github-releases-to-discord/compare/v1.16.2...v1.17.0) (2025-06-17)
### Features
* **workflow:** add GitHub Actions workflow to automatically update SemVer tags on tag push events ([e768ce1](https://github.com/SethCohen/github-releases-to-discord/commit/e768ce10237a6100cccd7e80b2e994e9a2609150))
## [1.16.2](https://github.com/SethCohen/github-releases-to-discord/compare/v1.16.1...v1.16.2) (2024-10-18)
### Documentation
* update README output example ([6aa0dd9](https://github.com/SethCohen/github-releases-to-discord/commit/6aa0dd988c547f3b3a73463bc6e69d944621c613))
## [1.16.1](https://github.com/SethCohen/github-releases-to-discord/compare/v1.16.0...v1.16.1) (2024-10-18)
### Bug Fixes
* correct conversion of standalone PR, issue, and changelog URLs to markdown format ([4786949](https://github.com/SethCohen/github-releases-to-discord/commit/47869497ed80cf0d6188692d82d71dff7a55dffe)), closes [#38](https://github.com/SethCohen/github-releases-to-discord/issues/38)
### Documentation
* update README with details on markdown link conversion and other features ([9737dc9](https://github.com/SethCohen/github-releases-to-discord/commit/9737dc900274be227db48f8e23c715aa00b4af59))
## [1.16.0](https://github.com/SethCohen/github-releases-to-discord/compare/v1.15.3...v1.16.0) (2024-10-18)
### Features
* add function to convert PR, issue, and changelog links to markdown format ([07c2e1c](https://github.com/SethCohen/github-releases-to-discord/commit/07c2e1c3e60591d601b5d4b5bd4fc90e599867f8)), closes [#32](https://github.com/SethCohen/github-releases-to-discord/issues/32)
## [1.15.3](https://github.com/SethCohen/github-releases-to-discord/compare/v1.15.2...v1.15.3) (2024-10-18)
### Documentation
* add contribution guidelines to README.md ([5fd64bf](https://github.com/SethCohen/github-releases-to-discord/commit/5fd64bf266cea87ab4952ef9a4c6aaf099f266bc))
* update version reference in README.md ([93d02ce](https://github.com/SethCohen/github-releases-to-discord/commit/93d02ce8714c5f3e201f5b379422e978b837774b))
### Miscellaneous
* update .gitignore ([3449e38](https://github.com/SethCohen/github-releases-to-discord/commit/3449e38629b0c40dde5af524e2fef220dab24ead))
* update package-lock.json ([5dc4108](https://github.com/SethCohen/github-releases-to-discord/commit/5dc41089e63d18b5b191533c34cdddeab34a07e8))
## [1.15.2](https://github.com/SethCohen/github-releases-to-discord/compare/v1.15.1...v1.15.2) (2024-10-18)
### Bug Fixes
* improve [@mention](https://github.com/mention) parsing for GitHub usernames ([#33](https://github.com/SethCohen/github-releases-to-discord/issues/33)) ([925765f](https://github.com/SethCohen/github-releases-to-discord/commit/925765f099dcdc3b12316eaa6dc3c17506734b51))
## [1.15.1](https://github.com/SethCohen/github-releases-to-discord/compare/v1.15.0...v1.15.1) (2024-10-04)
### Documentation
* updated README.md ([613ba26](https://github.com/SethCohen/github-releases-to-discord/commit/613ba269d7fe40e97040da19de58b0ae00b47aaf))
### Miscellaneous
* added test envs to .gitignore ([735cca9](https://github.com/SethCohen/github-releases-to-discord/commit/735cca9de37b345e69b0c74ff761610eab6f1fd1))
* updated test action ([305fe92](https://github.com/SethCohen/github-releases-to-discord/commit/305fe9299dddb3a514f2b1692773570862c34d46))
### Code Refactoring
* code cleanup ([5ca1453](https://github.com/SethCohen/github-releases-to-discord/commit/5ca1453a69f962930450a9f77d4e20cc37e4110f))
## [1.15.0](https://github.com/SethCohen/github-releases-to-discord/compare/v1.14.0...v1.15.0) (2023-12-14) ## [1.15.0](https://github.com/SethCohen/github-releases-to-discord/compare/v1.14.0...v1.15.0) (2023-12-14)
+83 -6
View File
@@ -1,9 +1,33 @@
# GitHub Releases To Discord Action # GitHub Releases To Discord Action
A GitHub action that parses a GitHub release and posts it to a Discord channel as a stylized Discord webhook.
A GitHub Action that sends a stylized Discord webhook containing the description of a GitHub Release to a specified Discord channel. It formats the description to improve readability and includes various configuration options to customize the message.
## Features
- **Text Cleanup:**
- **Carriage Return Removal:** Automatically removes carriage return characters for clean formatting.
- **HTML Comment Stripping:** Eliminates HTML comments to remove unnecessary information.
- **Whitespace Optimization:** Reduces redundant newlines and excess spaces while preserving proper paragraph spacing.
- **Mention Conversion:** Converts GitHub mentions (e.g., `@username`) into clickable GitHub profile links for easy navigation.
- **Markdown Link Conversion:**
- **PR Links:** Converts pull request URLs into Markdown links (e.g., `[PR #1](https://github.com/OWNER/REPO/pull/1)`).
- **Issue Links:** Converts issue URLs into Markdown links (e.g., `[Issue #1](https://github.com/OWNER/REPO/issues/1)`).
- **Changelog Links:** Converts changelog comparison URLs into concise Markdown links (e.g., `[v1.0.0...v1.1.0](https://github.com/OWNER/REPO/compare/v1.0.0...v1.1.0)`).
- **Heading Reduction (Optional):** If enabled, it reduces heading sizes for a cleaner, more compact display:
- H3 headings are converted to bold and underlined.
- H2 headings are converted to bold.
- **Description Length Management:** Ensures the release description fits within Discord's embed message limits (default 4096 characters), trimming excess text by cutting at newlines when possible or adding a continuation link.
- **Custom Embed Appearance:**
- Set a custom color for the Discord embed message.
- Optionally include a custom footer with a title, icon, and a timestamp to make the notification more informative.
- **Error Handling:** Provides clear error messages for any invalid or missing inputs, ensuring that the webhook action does not fail silently.
- **Webhook Delivery:** Sends the formatted message to the specified Discord channel via webhook, ensuring your release notifications are promptly delivered with the correct details.
--- ---
## Output ## Output
![output](https://i.imgur.com/Zf3TXtb.png)
![output](https://i.imgur.com/ovr0gTL.png)
## Configuration ## Configuration
@@ -23,6 +47,7 @@ A GitHub action that parses a GitHub release and posts it to a Discord channel a
## Example Usage ## Example Usage
`.github/workflows/github-releases-to-discord.yml` `.github/workflows/github-releases-to-discord.yml`
```yaml ```yaml
on: on:
release: release:
@@ -35,7 +60,7 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Github Releases To Discord - name: Github Releases To Discord
uses: SethCohen/github-releases-to-discord@v1.13.1 uses: SethCohen/github-releases-to-discord@v1
with: with:
webhook_url: ${{ secrets.WEBHOOK_URL }} webhook_url: ${{ secrets.WEBHOOK_URL }}
color: "2105893" color: "2105893"
@@ -45,17 +70,69 @@ jobs:
footer_title: "Changelog" footer_title: "Changelog"
footer_icon_url: "https://cdn.discordapp.com/avatars/487431320314576937/bd64361e4ba6313d561d54e78c9e7171.png" footer_icon_url: "https://cdn.discordapp.com/avatars/487431320314576937/bd64361e4ba6313d561d54e78c9e7171.png"
footer_timestamp: true footer_timestamp: true
max_description: '4096'
reduce_headings: true
``` ```
## Setup Instructions ## Setup Instructions
1. Open your **Server Settings** and head into the **Integrations** tab: 1. Open your **Server Settings** and head into the **Integrations** tab:
2. Click the "**Create Webhook**" button to create a new webhook! 2. Click the "**Create Webhook**" button to create a new webhook!
![](https://support.discord.com/hc/article_attachments/1500000463501/Screen_Shot_2020-12-15_at_4.41.53_PM.png) ![create webhook](https://support.discord.com/hc/article_attachments/1500000463501/Screen_Shot_2020-12-15_at_4.41.53_PM.png)
![](https://support.discord.com/hc/article_attachments/360101553853/Screen_Shot_2020-12-15_at_4.51.38_PM.png) ![created webhook](https://support.discord.com/hc/article_attachments/360101553853/Screen_Shot_2020-12-15_at_4.51.38_PM.png)
3. Copy the webhook url 3. Copy the webhook url
4. Create a new GitHub repository secret called WEBHOOK_URL and paste the webhook url into it. 4. Create a new GitHub repository secret called WEBHOOK_URL and paste the webhook url into it.
![](https://i.imgur.com/hAaNOds.png) ![repository secret](https://i.imgur.com/hAaNOds.png)
5. Save the secret. 5. Save the secret.
6. Add the secret to your action configuration. 6. Add the secret to your action configuration.
And you're done! Whenever you create a new release, the workflow should run and, if properly setup, post to your specified Discord channel. And you're done! Whenever you create a new release, the workflow should run and, if properly setup, post to your specified Discord channel.
## Contributing
If you have suggestions for how GitHub Releases To Discord Action could be improved, or want to report a bug, open an issue! We'd love all and any contributions.
1. Fork the repository.
2. Install node and run `npm install`.
3. Install [Github Action tester `act`](https://github.com/nektos/act)
4. Create a sample test Release file to simulate a webhook payload object such as `tests/sample-test-release.json` with the following structure:
```json
{
"action": "published",
"release": {
...
},
"repository": {
...
},
"sender": {
...
}
}
```
This file will be used to test the action locally and simulate a real release event webhook payload. Refer to the [GitHub Webhook documentation](https://docs.github.com/en/webhooks/webhook-events-and-payloads?actionType=published#release) and the [Github API Documentation](https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#get-a-release) for more information on the webhook payload structure.
6. Fill the test json file with the necessary fields to simulate a release event.
5. Create a test file called `.env` in the main root of the project with the following environmental variables:
```bash
INPUT_WEBHOOK_URL=
INPUT_COLOR=
INPUT_USERNAME=
INPUT_AVATAR_URL=
INPUT_CONTENT=
INPUT_FOOTER_TITLE=
INPUT_FOOTER_ICON_URL=
INPUT_FOOTER_TIMESTAMP=
INPUT_MAX_DESCRIPTION=
INPUT_REDUCE_HEADINGS=
```
8. Fill the `.env` file with your chosen environmental variables values.
9. Create a Discord webhook in your server, making sure to add the webhook url to the `.env` file under `INPUT_WEBHOOK_URL=`.
10. Run the action locally with `act release -e <your.json>` (e.g., `act release -e tests/sample-test-release.json`) and check the output in your Discord server.
11. Confirm that the action works as expected.
12. Make your changes and commit them: `git commit -m '<commit_message>'`. Please follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
13. Create the pull request.
+192 -136
View File
@@ -2,176 +2,232 @@ import core from '@actions/core';
import github from '@actions/github'; import github from '@actions/github';
import fetch from 'node-fetch'; import fetch from 'node-fetch';
/**
* Removes carriage return characters.
* @param {string} text The input text.
* @returns {string} The text without carriage return characters.
*/
const removeCarriageReturn = (text) => text.replace(/\r/g, '');
/**
* Removes HTML comments.
* @param {string} text The input text.
* @returns {string} The text without HTML comments.
*/
const removeHTMLComments = (text) => text.replace(/<!--.*?-->/gs, '');
/**
* Reduces redundant newlines and spaces.
* Keeps a maximum of 2 newlines to provide spacing between paragraphs.
* @param {string} text The input text.
* @returns {string} The text with reduced newlines.
*/
const reduceNewlines = (text) => text.replace(/\n\s*\n/g, (ws) => {
const nlCount = (ws.match(/\n/g) || []).length;
return nlCount >= 2 ? '\n\n' : '\n';
});
/**
* Converts @mentions to GitHub profile links for valid GitHub usernames.
* @param {string} text The input text.
* @returns {string} The text with valid @mentions converted to links.
*/
const convertMentionsToLinks = (text) => text.replace(
/(?<![/@\w])@((?!-)(?!.*?--)[a-zA-Z0-9](?:-?[a-zA-Z0-9]){0,37})(?![.\w/-])(?!.*\])/g,
(match, name) => `[@${name}](https://github.com/${name})`
);
/**
* Reduces headings to a smaller format if 'reduce_headings' is enabled.
* Converts H3 to bold+underline, H2 to bold.
* @param {string} text The input text.
* @returns {string} The text with reduced heading sizes.
*/
const reduceHeadings = (text) => text
.replace(/^###\s+(.+)$/gm, '**__$1__**') // Convert H3 to bold + underline
.replace(/^##\s+(.+)$/gm, '**$1**'); // Convert H2 to bold
/**
* Converts PR, issue, and changelog links to markdown format, ignoring existing markdown links.
* - PR links: `https://github.com/OWNER/REPO/pull/1` -> `[PR #1](https://github.com/OWNER/REPO/pull/1)`
* - Issue links: `https://github.com/OWNER/REPO/issues/1` -> `[Issue #30](https://github.com/OWNER/REPO/issues/1)`
* - Changelog links: `https://github.com/OWNER/REPO/compare/v1.0.0...v1.1.0` -> `[v1.0.0...v1.1.0](https://github.com/OWNER/REPO/compare/v1.0.0...v1.1.0)`
* @param {string} text The input text.
* @returns {string} The text with links converted to markdown format.
*/
const convertLinksToMarkdown = (text) => {
// Extract existing markdown links and replace them with placeholders
const markdownLinks = [];
const textWithoutMarkdownLinks = text.replace(/\[.*?\]\(.*?\)/g, (link) => {
markdownLinks.push(link);
return `__MARKDOWN_LINK_PLACEHOLDER_${markdownLinks.length - 1}__`;
});
// Convert standalone PR, issue, and changelog URLs to markdown format
let processedText = textWithoutMarkdownLinks
.replace(/https:\/\/github\.com\/([\w-]+)\/([\w-]+)\/pull\/(\d+)/g, (match, owner, repo, prNumber) => `[PR #${prNumber}](${match})`)
.replace(/https:\/\/github\.com\/([\w-]+)\/([\w-]+)\/issues\/(\d+)/g, (match, owner, repo, issueNumber) => `[Issue #${issueNumber}](${match})`)
.replace(/https:\/\/github\.com\/([\w-]+)\/([\w-]+)\/compare\/([v\w.-]+)\.\.\.([v\w.-]+)/g, (match, owner, repo, fromVersion, toVersion) => `[${fromVersion}...${toVersion}](${match})`);
// Reinsert the original markdown links
return processedText.replace(/__MARKDOWN_LINK_PLACEHOLDER_(\d+)__/g, (match, index) => markdownLinks[parseInt(index, 10)]);
};
/** /**
* Stylizes a markdown body into an appropriate embed message style. * Stylizes a markdown body into an appropriate embed message style.
* Remove Carriage Return character to reduce size * @param {string} description The description to format.
* Remove HTML comments (commonly added by 'Generate release notes' button) * @returns {string} The formatted description.
* Better URL linking for common Github links: PRs, Issues, Compare
* Redundant whitespace and newlines removed, keeping at max 2 to provide space between paragraphs
* Trim leading/trailing whitespace
* If reduce_headings:
* H3s converted to bold and underlined
* H2s converted to bold
* @param {string} description
*/ */
const formatDescription = (description) => { const formatDescription = (description) => {
let edit = description let edit = removeCarriageReturn(description);
.replace(/\r/g, '') edit = removeHTMLComments(edit);
.replace(/<!--.*?-->/gs, '') edit = reduceNewlines(edit);
.replace( edit = convertMentionsToLinks(edit);
new RegExp( edit = convertLinksToMarkdown(edit);
"https://github.com/(.+)/(.+)/(issues|pull|commit|compare)/(\\S+)", edit = edit.trim();
"g"
),
(match, user, repo, type, id) => {
return `[${getTypePrefix(type) + id}](${match})`
}
)
.replace(/\n\s*\n/g, (ws) => {
const nlCount = (ws.match(/\n/g) || []).length
return nlCount >= 2 ? '\n\n' : '\n'
})
.trim()
if (core.getBooleanInput('reduce_headings')) { if (core.getBooleanInput('reduce_headings')) {
edit = edit edit = reduceHeadings(edit);
.replace(/^###\s+(.+)$/gm, '**__$1__**')
.replace(/^##\s+(.+)$/gm, '**$1**')
} }
return edit return edit;
} };
/** /**
* Get a prefix to use for Github link display * Gets the max description length, defaulting to 4096 if not set or invalid.
* @param {'issues' | 'pull' | 'commit' | 'compare'} type * @returns {number} The max description length.
*/ */
function getTypePrefix (type) { const getMaxDescription = () => {
switch (type) {
case 'issues':
return 'Issue #'
case 'pull':
return 'PR #'
case 'commit':
return 'Commit #'
case 'compare':
return ''
default:
return '#'
}
}
/**
* Gets the max description length if set to a valid number,
* otherwise the default of 4096
*/
function getMaxDescription () {
try { try {
const max = core.getInput('max_description') const max = core.getInput('max_description');
if (typeof max === 'string' && max.length) { if (max && !isNaN(max)) {
// 4096 is max for Embed Description return Math.min(parseInt(max, 10), 4096);
// https://discord.com/developers/docs/resources/channel#embed-object-embed-limits
return Math.min(parseInt(max, 10), 4096)
} }
} catch (err) { } catch (err) {
core.warning(`max_description not a valid number: ${err}`) core.warning(`Invalid max_description: ${err}`);
} }
return 4096 return 4096;
} };
/** /**
* Get the context of the action, returns a GitHub Release payload. * Get the context of the action, returning a GitHub Release payload.
* @returns {object} The context with release details.
*/ */
function getContext () { const getContext = () => {
const payload = github.context.payload; const { release } = github.context.payload;
return { return {
body: payload.release.body, body: release.body,
name: payload.release.name, name: release.name,
html_url: payload.release.html_url html_url: release.html_url
} };
} };
/** /**
* * Limits the string to a maximum length, optionally adding a URL or clipping at a newline.
* @param {string} str * @param {string} str The string to limit.
* @param {number} maxLength * @param {number} maxLength The maximum allowed length.
* @param {string} [url] * @param {string} [url] Optional URL for linking the truncated text.
* @param {boolean} [clipAtLine=false] * @param {boolean} [clipAtLine=false] Whether to clip at the nearest newline.
* @returns {string} The limited string.
*/ */
function limit(str, maxLength, url, clipAtLine) { const limitString = (str, maxLength, url, clipAtLine = false) => {
clipAtLine ??= false if (str.length <= maxLength) return str;
if (str.length <= maxLength)
return str
let replacement = clipAtLine ? '\n…' : '…'
if (url) {
replacement = `${clipAtLine ? '\n' : ''}([…](${url}))`
}
maxLength = maxLength - replacement.length
str = str.substring(0, maxLength)
const lastNewline = str.search(new RegExp(`[^${clipAtLine ? '\n' : '\s'}]*$`)) const replacement = url
? `${clipAtLine ? '\n' : ''}([…](${url}))`
: (clipAtLine ? '\n…' : '…');
maxLength -= replacement.length;
str = str.substring(0, maxLength);
const lastNewline = str.search(new RegExp(`[^${clipAtLine ? '\n' : '\s'}]*$`));
if (lastNewline > -1) { if (lastNewline > -1) {
str = str.substring(0, lastNewline) str = str.substring(0, lastNewline);
} }
return str + replacement return str + replacement;
} };
/** /**
* Handles the action. * Builds the embed message for the Discord webhook.
* Get inputs, creates a stylized response webhook, and sends it to the channel. * @param {string} name The title or name of the release.
* @param {string} html_url The URL of the release.
* @param {string} description The formatted description of the release.
* @returns {object} The embed message to send in the webhook.
*/ */
async function run () { const buildEmbedMessage = (name, html_url, description) => {
const embedMsg = {
title: limitString(name, 256),
url: html_url,
color: core.getInput('color'),
description: limitString(description, Math.min(getMaxDescription(), 6000 - name.length)),
footer: {}
};
if (core.getInput('footer_title')) {
embedMsg.footer.text = limitString(core.getInput('footer_title'), 2048);
}
if (core.getInput('footer_icon_url')) {
embedMsg.footer.icon_url = core.getInput('footer_icon_url');
}
if (core.getInput('footer_timestamp') === 'true') {
embedMsg.timestamp = new Date().toISOString();
}
return embedMsg;
};
/**
* Sends the webhook request to Discord.
* @param {string} webhookUrl The URL of the Discord webhook.
* @param {object} requestBody The payload to send in the webhook.
*/
const sendWebhook = async (webhookUrl, requestBody) => {
try {
const response = await fetch(`${webhookUrl}?wait=true`, {
method: 'POST',
body: JSON.stringify(requestBody),
headers: { 'Content-Type': 'application/json' }
});
const data = await response.json();
core.info(JSON.stringify(data));
} catch (err) {
core.setFailed(err.message);
}
};
/**
* Builds the request body for the Discord webhook.
* @param {object} embedMsg The embed message to include in the request body.
* @returns {object} The request body for the webhook.
*/
const buildRequestBody = (embedMsg) => {
return {
embeds: [embedMsg],
...(core.getInput('username') && { username: core.getInput('username') }),
...(core.getInput('avatar_url') && { avatar_url: core.getInput('avatar_url') }),
...(core.getInput('content') && { content: core.getInput('content') })
};
};
/**
* Main function to handle the action: get inputs, format the message, and send the webhook.
*/
const run = async () => {
const webhookUrl = core.getInput('webhook_url'); const webhookUrl = core.getInput('webhook_url');
const color = core.getInput('color'); if (!webhookUrl) return core.setFailed('webhook_url not set.');
const username = core.getInput('username');
const avatarUrl = core.getInput('avatar_url');
const content = core.getInput('content');
const footerTitle = core.getInput('footer_title');
const footerIconUrl = core.getInput('footer_icon_url');
const footerTimestamp = core.getInput('footer_timestamp');
if (!webhookUrl) return core.setFailed('webhook_url not set. Please set it.');
const {body, html_url, name} = getContext();
const { body, html_url, name } = getContext();
const description = formatDescription(body); const description = formatDescription(body);
let embedMsg = { const embedMsg = buildEmbedMessage(name, html_url, description);
title: limit(name, 256),
url: html_url,
color: color,
description: description,
footer: {}
}
if (footerTitle != '') embedMsg.footer.text = limit(footerTitle, 2048); const requestBody = buildRequestBody(embedMsg);
if (footerIconUrl != '') embedMsg.footer.icon_url = footerIconUrl;
if (footerTimestamp == 'true') embedMsg.timestamp = new Date().toISOString();
let embedSize = embedMsg.title.length + (embedMsg.footer?.text?.length ?? 0) await sendWebhook(webhookUrl, requestBody);
embedMsg.description = limit(embedMsg.description, Math.min(getMaxDescription(), 6000 - embedSize), embedMsg.url, true) };
let requestBody = {
embeds: [embedMsg]
}
if (username != '') requestBody.username = username;
if (avatarUrl != '') requestBody.avatar_url = avatarUrl;
if (content != '') requestBody.content = content;
const url = `${webhookUrl}?wait=true`;
fetch(url, {
method: 'post',
body: JSON.stringify(requestBody),
headers: { 'Content-Type': 'application/json' }
})
.then(res => res.json())
.then(data => core.info(JSON.stringify(data)))
.catch(err => core.info(err))
}
run() run()
.then(() => {core.info('Action completed successfully')}) .then(() => core.info('Action completed successfully'))
.catch(err => {core.setFailed(err.message)}) .catch(err => core.setFailed(err.message));
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "github-releases-to-discord", "name": "github-releases-to-discord",
"version": "1.13.0", "version": "1.15.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "github-releases-to-discord", "name": "github-releases-to-discord",
"version": "1.15.0", "version": "1.17.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "github-releases-to-discord", "name": "github-releases-to-discord",
"version": "1.15.0", "version": "1.17.0",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/core": "^1.10.1", "@actions/core": "^1.10.1",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "github-releases-to-discord", "name": "github-releases-to-discord",
"version": "1.15.0", "version": "1.17.0",
"description": "A GitHub Action that automatically sends a stylized Discord webhook of a GitHub Release description to a specified Discord channel.", "description": "A GitHub Action that automatically sends a stylized Discord webhook of a GitHub Release description to a specified Discord channel.",
"type": "module", "type": "module",
"main": "index.js", "main": "index.js",