mirror of
https://github.com/SethCohen/github-releases-to-discord
synced 2026-09-14 20:13:23 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de60879a86 | ||
|
|
82d906cc6f | ||
|
|
feb5a40237 | ||
|
|
9fe781fdc7 | ||
|
|
74ded4247d | ||
|
|
e1dc0826fe | ||
|
|
e768ce1023 | ||
|
|
6ac5abea42 | ||
|
|
6aa0dd988c | ||
|
|
1e7bdfd173 | ||
|
|
47869497ed | ||
|
|
9737dc9002 | ||
|
|
26399c645d | ||
|
|
07c2e1c3e6 | ||
|
|
f184bc59c7 | ||
|
|
3449e38629 | ||
|
|
93d02ce871 | ||
|
|
5dc41089e6 | ||
|
|
5fd64bf266 | ||
|
|
60a5c60e64 | ||
|
|
925765f099 |
@@ -15,10 +15,11 @@ jobs:
|
|||||||
color: ${{ inputs.COLOR }}
|
color: ${{ inputs.COLOR }}
|
||||||
username: ${{ inputs.USERNAME }}
|
username: ${{ inputs.USERNAME }}
|
||||||
avatar_url: ${{ inputs.AVATAR_URL }}
|
avatar_url: ${{ inputs.AVATAR_URL }}
|
||||||
|
custom_html_url: ${{ inputs.CUSTOM_HTML_URL }}
|
||||||
content: ${{ inputs.CONTENT }}
|
content: ${{ inputs.CONTENT }}
|
||||||
footer_title: ${{ inputs.FOOTER_TITLE }}
|
footer_title: ${{ inputs.FOOTER_TITLE }}
|
||||||
footer_icon_url: ${{ inputs.FOOTER_ICON_URL }}
|
footer_icon_url: ${{ inputs.FOOTER_ICON_URL }}
|
||||||
footer_timestamp: ${{ inputs.FOOTER_TIMESTAMP }}
|
footer_timestamp: ${{ inputs.FOOTER_TIMESTAMP }}
|
||||||
max_description: ${{ inputs.MAX_DESCRIPTION }}
|
max_description: ${{ inputs.MAX_DESCRIPTION }}
|
||||||
reduce_headings: ${{ inputs.REDUCE_HEADINGS }}
|
reduce_headings: ${{ inputs.REDUCE_HEADINGS }}
|
||||||
|
remove_github_reference_links: ${{ inputs.REMOVE_GITHUB_REFERENCE_LINKS }}
|
||||||
|
|||||||
@@ -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
|
||||||
+4
-1
@@ -3,4 +3,7 @@
|
|||||||
out
|
out
|
||||||
gen
|
gen
|
||||||
.env
|
.env
|
||||||
tests/sample-test-release.json
|
release.json
|
||||||
|
repository.json
|
||||||
|
user.json
|
||||||
|
tests/sample-test-release-v2.json
|
||||||
|
|||||||
@@ -1,5 +1,72 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [1.18.0](https://github.com/SethCohen/github-releases-to-discord/compare/v1.17.0...v1.18.0) (2025-06-17)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **index.js:** enhance sendWebhook function to handle rate limits with retries for improved reliability when sending requests to Discord ([feb5a40](https://github.com/SethCohen/github-releases-to-discord/commit/feb5a402377bc3da9cb9ea788964ece4e56f48cd))
|
||||||
|
|
||||||
|
|
||||||
|
### Miscellaneous
|
||||||
|
|
||||||
|
* remove unnecessary test file from .gitignore and add sample test release JSON for local testing ([82d906c](https://github.com/SethCohen/github-releases-to-discord/commit/82d906cc6f29adbe413b3f26b55deafc3f08ceee))
|
||||||
|
* update README for clarity and conciseness, improve formatting, and add new sections for better user guidance ([82d906c](https://github.com/SethCohen/github-releases-to-discord/commit/82d906cc6f29adbe413b3f26b55deafc3f08ceee))
|
||||||
|
|
||||||
|
## [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)
|
## [1.15.1](https://github.com/SethCohen/github-releases-to-discord/compare/v1.15.0...v1.15.1) (2024-10-04)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,42 +1,50 @@
|
|||||||
# GitHub Releases To Discord Action
|
# GitHub Releases to Discord Action
|
||||||
|
|
||||||
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.
|
Easily notify your Discord community about new GitHub releases! This GitHub Action automatically sends a beautifully formatted Discord embed message with your release notes whenever you publish a release on GitHub.
|
||||||
|
|
||||||
|
**Main Benefits:**
|
||||||
|
|
||||||
|
- Instantly share release changelogs with your Discord server.
|
||||||
|
- Highly customizable message appearance and content.
|
||||||
|
- Simple setup—no coding required.
|
||||||
|
- Supports advanced formatting and filtering for professional notifications.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Formats release descriptions by:
|
- **Automatic Release Notifications:** Sends a Discord embed when a GitHub release is published.
|
||||||
- Removing carriage returns and HTML comments.
|
- **Clean Formatting:**
|
||||||
- Styling headers for better readability in Discord (optional).
|
- Removes carriage returns and HTML comments.
|
||||||
- Cleaning up redundant whitespace and newlines.
|
- Optimizes whitespace and paragraph spacing.
|
||||||
- Converting common GitHub links (e.g., PRs, Issues) into clickable URLs.
|
- **Mention & Link Handling:**
|
||||||
- Limits description length to avoid exceeding Discord's character limits.
|
- Converts `@mentions` to clickable GitHub profile links.
|
||||||
- Provides customization for the Discord message, including:
|
- Converts PR, issue, and changelog URLs to Markdown links.
|
||||||
- Webhook URL, message color, footer text/icon, and timestamp.
|
- Optionally removes PR, commit, and issue links for cleaner messages.
|
||||||
- Username and avatar for the webhook.
|
- **Heading Reduction:**
|
||||||
- Optional message content outside the embed.
|
- Optionally reduces heading sizes for compact display.
|
||||||
|
- **Custom Embed Appearance:**
|
||||||
|
- Set color, username, avatar, footer, and more.
|
||||||
|
- **Length Management:**
|
||||||
|
- Ensures messages fit Discord's embed limits, trimming and linking as needed.
|
||||||
|
- **Error Handling:**
|
||||||
|
- Clear errors for missing or invalid inputs.
|
||||||
|
- **Easy Integration:**
|
||||||
|
- Works with any public or private repository.
|
||||||
|
|
||||||
---
|
---
|
||||||
## Output
|
|
||||||

|
|
||||||
|
|
||||||
## Configuration
|
## Quick Start
|
||||||
|
|
||||||
| Variable | Required | Default | Description |
|
### 1. Create a Discord Webhook
|
||||||
|-----------------|----------|-------------------------------------------------------------------------------------------------------|-------------------------------------------------|
|
|
||||||
| webhook_url | ✔ | | Discord's webhook url. Use GH repo secrets. |
|
|
||||||
| color | ❌ | "2105893" | Decimal color value for embed. |
|
|
||||||
| username | ❌ | | String username for webhook. |
|
|
||||||
| avatar_url | ❌ | | String url to webhook avatar picture. |
|
|
||||||
| content | ❌ | | String content for webhook. |
|
|
||||||
| footer_title | ❌ | | String title for the webhook footer. |
|
|
||||||
| footer_icon_url | ❌ | | String url for the webhook footer picture. |
|
|
||||||
| footer_timestamp| ❌ | | Boolean to enable footer timestamp. |
|
|
||||||
| max_description | ❌ | "4096" | Max length for the description. |
|
|
||||||
| reduce_headings | ❌ | false | Converts H3 to bold, h2 to bold & underline. |
|
|
||||||
|
|
||||||
## Example Usage
|
- Go to your Discord server settings → **Integrations** → **Webhooks**.
|
||||||
|
- Click **Create Webhook** and copy the webhook URL.
|
||||||
|
|
||||||
|
### 2. Add the Action to Your Workflow
|
||||||
|
|
||||||
|
Create (or update) `.github/workflows/github-releases-to-discord.yml`:
|
||||||
|
|
||||||
`.github/workflows/github-releases-to-discord.yml`
|
|
||||||
```yaml
|
```yaml
|
||||||
on:
|
on:
|
||||||
release:
|
release:
|
||||||
@@ -48,8 +56,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- 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.15.1
|
uses: SethCohen/github-releases-to-discord@v1
|
||||||
with:
|
with:
|
||||||
webhook_url: ${{ secrets.WEBHOOK_URL }}
|
webhook_url: ${{ secrets.WEBHOOK_URL }}
|
||||||
color: "2105893"
|
color: "2105893"
|
||||||
@@ -57,21 +65,118 @@ jobs:
|
|||||||
avatar_url: "https://cdn.discordapp.com/avatars/487431320314576937/bd64361e4ba6313d561d54e78c9e7171.png"
|
avatar_url: "https://cdn.discordapp.com/avatars/487431320314576937/bd64361e4ba6313d561d54e78c9e7171.png"
|
||||||
content: "||@everyone||"
|
content: "||@everyone||"
|
||||||
footer_title: "Changelog"
|
footer_title: "Changelog"
|
||||||
footer_icon_url: "https://cdn.discordapp.com/avatars/487431320314576937/bd64361e4ba6313d561d54e78c9e7171.png"
|
|
||||||
footer_timestamp: true
|
|
||||||
max_description: '4096'
|
|
||||||
reduce_headings: true
|
reduce_headings: true
|
||||||
```
|
```
|
||||||
|
|
||||||
## Setup Instructions
|
### 3. Add Your Webhook URL as a Secret
|
||||||
1. Open your **Server Settings** and head into the **Integrations** tab:
|
|
||||||
2. Click the "**Create Webhook**" button to create a new webhook!
|
|
||||||

|
|
||||||

|
|
||||||
3. Copy the webhook url
|
|
||||||
4. Create a new GitHub repository secret called WEBHOOK_URL and paste the webhook url into it.
|
|
||||||

|
|
||||||
5. Save the secret.
|
|
||||||
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.
|
- In your GitHub repo, go to **Settings → Secrets and variables → Actions**.
|
||||||
|
- Add a new secret named `WEBHOOK_URL` and paste your Discord webhook URL.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration Options
|
||||||
|
|
||||||
|
| Input Name | Required | Default | Description |
|
||||||
|
|-------------------------------|----------|-------------|--------------------------------------------------------------------|
|
||||||
|
| `webhook_url` | ✔ | | Discord webhook URL (use a GitHub secret). |
|
||||||
|
| `color` | ❌ | 2105893 | Embed color (decimal). |
|
||||||
|
| `username` | ❌ | | Webhook username. |
|
||||||
|
| `avatar_url` | ❌ | | Webhook avatar image URL. |
|
||||||
|
| `custom_html_url` | ❌ | | Custom URL for the embed title (overrides GitHub release URL). |
|
||||||
|
| `content` | ❌ | | Additional message content (e.g., `@everyone`). |
|
||||||
|
| `footer_title` | ❌ | | Footer title. |
|
||||||
|
| `footer_icon_url` | ❌ | | Footer icon image URL. |
|
||||||
|
| `footer_timestamp` | ❌ | false | Show timestamp in footer (`true`/`false`). |
|
||||||
|
| `max_description` | ❌ | 4096 | Max description length (Discord limit: 4096). |
|
||||||
|
| `remove_github_reference_links`| ❌ | false | Remove PR, commit, and issue links from the description. |
|
||||||
|
| `reduce_headings` | ❌ | false | Reduce heading sizes for compact display. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example Output
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Best Practices & Notes
|
||||||
|
|
||||||
|
- **Use Secrets for Webhook URLs:** Never commit your Discord webhook URL directly to your repository.
|
||||||
|
- **Discord Embed Limits:**
|
||||||
|
- Title: 256 characters max
|
||||||
|
- Description: 4096 characters max
|
||||||
|
- The action will trim and link if limits are exceeded.
|
||||||
|
- **Release Body Formatting:**
|
||||||
|
- Use Markdown in your release notes for best results.
|
||||||
|
- **Private Repos:**
|
||||||
|
- The action works for both public and private repositories.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting & FAQ
|
||||||
|
|
||||||
|
**Q: The action didn't post to Discord!**
|
||||||
|
|
||||||
|
- Check that your webhook URL is correct and not expired.
|
||||||
|
- Ensure the `webhook_url` secret is set in your repository.
|
||||||
|
- Review the Actions log for error messages.
|
||||||
|
|
||||||
|
**Q: My message is cut off.**
|
||||||
|
|
||||||
|
- Discord has strict embed limits. The action trims long messages and adds a link if needed.
|
||||||
|
|
||||||
|
**Q: How do I customize the embed?**
|
||||||
|
|
||||||
|
- Use the configuration options above to set color, username, avatar, footer, and more.
|
||||||
|
|
||||||
|
**Q: Can I mention everyone or specific roles?**
|
||||||
|
|
||||||
|
- Use the `content` input (e.g., `content: "@everyone"`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
We welcome contributions! To get started:
|
||||||
|
|
||||||
|
1. **Fork** this repository.
|
||||||
|
2. **Clone** your fork and run `npm install`.
|
||||||
|
3. **Create a test release payload:**
|
||||||
|
- Copy `tests/sample-test-release.json` and edit as needed.
|
||||||
|
4. **Create a `.env` file** in the root with your webhook and config (see below):
|
||||||
|
|
||||||
|
```env
|
||||||
|
INPUT_WEBHOOK_URL=your_webhook_url
|
||||||
|
INPUT_COLOR=2105893
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Test locally** with [`act`](https://github.com/nektos/act):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
act release -e tests/sample-test-release.json
|
||||||
|
```
|
||||||
|
|
||||||
|
6. **Make your changes** and commit using [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
|
||||||
|
7. **Open a pull request** with a clear description of your changes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[MIT License](LICENSE)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Support & Feedback
|
||||||
|
|
||||||
|
- **Issues:** [Open an issue](https://github.com/SethCohen/github-releases-to-discord/issues) for bugs, questions, or feature requests.
|
||||||
|
- **Pull Requests:** Contributions are welcome—see above!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Acknowledgements
|
||||||
|
|
||||||
|
- Inspired by the needs of open source maintainers and Discord communities.
|
||||||
|
- Built and maintained by [SethCohen](https://github.com/SethCohen).
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ inputs:
|
|||||||
avatar_url:
|
avatar_url:
|
||||||
description: String url to webhook avatar picture.
|
description: String url to webhook avatar picture.
|
||||||
required: false
|
required: false
|
||||||
|
custom_html_url:
|
||||||
|
description: If filled, replaces github's release url with your custom html url.
|
||||||
|
required: false
|
||||||
content:
|
content:
|
||||||
description: String content for webhook.
|
description: String content for webhook.
|
||||||
required: false
|
required: false
|
||||||
@@ -31,6 +34,10 @@ inputs:
|
|||||||
description: Max length for the description.
|
description: Max length for the description.
|
||||||
required: false
|
required: false
|
||||||
default: '4096'
|
default: '4096'
|
||||||
|
remove_github_reference_links:
|
||||||
|
description: Remove any PR, commit, and issue links from the description.
|
||||||
|
required: false
|
||||||
|
default: 'false'
|
||||||
reduce_headings:
|
reduce_headings:
|
||||||
description: Converts H3 to bold, h2 to bold & underline.
|
description: Converts H3 to bold, h2 to bold & underline.
|
||||||
required: false
|
required: false
|
||||||
|
|||||||
@@ -28,11 +28,31 @@ const reduceNewlines = (text) => text.replace(/\n\s*\n/g, (ws) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts @mentions to GitHub profile links.
|
* Converts @mentions to GitHub profile links for valid GitHub usernames.
|
||||||
* @param {string} text The input text.
|
* @param {string} text The input text.
|
||||||
* @returns {string} The text with @mentions converted to links.
|
* @returns {string} The text with valid @mentions converted to links.
|
||||||
*/
|
*/
|
||||||
const convertMentionsToLinks = (text) => text.replace(/@(\S+)/g, (match, name) => `[@${name}](https://github.com/${name})`);
|
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})`
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes any GitHub PR, commit, or issue links from the text, including markdown links.
|
||||||
|
* @param {string} text The input text.
|
||||||
|
* @returns {string} The text without GitHub PR and commit links.
|
||||||
|
*/
|
||||||
|
const removeGithubReferenceLinks = (text) => text
|
||||||
|
// Remove markdown links to PRs, commits, and issues
|
||||||
|
.replace(/\[[^\]]*\]\(https:\/\/github\.com\/[^(\s)]+\/pull\/\d+\)/g, '')
|
||||||
|
.replace(/\[[^\]]*\]\(https:\/\/github\.com\/[^(\s)]+\/commit\/\w+\)/g, '')
|
||||||
|
.replace(/\[[^\]]*\]\(https:\/\/github\.com\/[^(\s)]+\/issues\/\d+\)/g, '')
|
||||||
|
// Remove bare PR, commit, and issue URLs
|
||||||
|
.replace(/https:\/\/github\.com\/[^(\s)]+\/pull\/\d+/g, '')
|
||||||
|
.replace(/https:\/\/github\.com\/[^(\s)]+\/commit\/\w+/g, '')
|
||||||
|
.replace(/https:\/\/github\.com\/[^(\s)]+\/issues\/\d+/g, '')
|
||||||
|
// Remove empty parentheses left behind
|
||||||
|
.replace(/\(\s*\)/g, '');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reduces headings to a smaller format if 'reduce_headings' is enabled.
|
* Reduces headings to a smaller format if 'reduce_headings' is enabled.
|
||||||
@@ -44,6 +64,32 @@ const reduceHeadings = (text) => text
|
|||||||
.replace(/^###\s+(.+)$/gm, '**__$1__**') // Convert H3 to bold + underline
|
.replace(/^###\s+(.+)$/gm, '**__$1__**') // Convert H3 to bold + underline
|
||||||
.replace(/^##\s+(.+)$/gm, '**$1**'); // Convert H2 to bold
|
.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.
|
||||||
* @param {string} description The description to format.
|
* @param {string} description The description to format.
|
||||||
@@ -53,7 +99,12 @@ const formatDescription = (description) => {
|
|||||||
let edit = removeCarriageReturn(description);
|
let edit = removeCarriageReturn(description);
|
||||||
edit = removeHTMLComments(edit);
|
edit = removeHTMLComments(edit);
|
||||||
edit = reduceNewlines(edit);
|
edit = reduceNewlines(edit);
|
||||||
|
|
||||||
|
if (core.getBooleanInput('remove_github_reference_links')) {
|
||||||
|
edit = removeGithubReferenceLinks(edit);
|
||||||
|
}
|
||||||
edit = convertMentionsToLinks(edit);
|
edit = convertMentionsToLinks(edit);
|
||||||
|
edit = convertLinksToMarkdown(edit);
|
||||||
edit = edit.trim();
|
edit = edit.trim();
|
||||||
|
|
||||||
if (core.getBooleanInput('reduce_headings')) {
|
if (core.getBooleanInput('reduce_headings')) {
|
||||||
@@ -134,6 +185,9 @@ const buildEmbedMessage = (name, html_url, description) => {
|
|||||||
footer: {}
|
footer: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (core.getInput('custom_html_url')) {
|
||||||
|
embedMsg.url = core.getInput('custom_html_url');
|
||||||
|
}
|
||||||
if (core.getInput('footer_title')) {
|
if (core.getInput('footer_title')) {
|
||||||
embedMsg.footer.text = limitString(core.getInput('footer_title'), 2048);
|
embedMsg.footer.text = limitString(core.getInput('footer_title'), 2048);
|
||||||
}
|
}
|
||||||
@@ -148,21 +202,42 @@ const buildEmbedMessage = (name, html_url, description) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the webhook request to Discord.
|
* Sends the webhook request to Discord, handling rate limits (429) with retries.
|
||||||
* @param {string} webhookUrl The URL of the Discord webhook.
|
* @param {string} webhookUrl The URL of the Discord webhook.
|
||||||
* @param {object} requestBody The payload to send in the webhook.
|
* @param {object} requestBody The payload to send in the webhook.
|
||||||
|
* @param {number} [maxRetries=3] Maximum number of retries on rate limit.
|
||||||
*/
|
*/
|
||||||
const sendWebhook = async (webhookUrl, requestBody) => {
|
const sendWebhook = async (webhookUrl, requestBody, maxRetries = 3) => {
|
||||||
try {
|
let attempt = 0;
|
||||||
const response = await fetch(`${webhookUrl}?wait=true`, {
|
while (attempt <= maxRetries) {
|
||||||
method: 'POST',
|
try {
|
||||||
body: JSON.stringify(requestBody),
|
const response = await fetch(`${webhookUrl}?wait=true`, {
|
||||||
headers: { 'Content-Type': 'application/json' }
|
method: 'POST',
|
||||||
});
|
body: JSON.stringify(requestBody),
|
||||||
const data = await response.json();
|
headers: { 'Content-Type': 'application/json' }
|
||||||
core.info(JSON.stringify(data));
|
});
|
||||||
} catch (err) {
|
if (response.status === 429) {
|
||||||
core.setFailed(err.message);
|
// Rate limited, get retry-after
|
||||||
|
const retryAfter = parseInt(response.headers.get('retry-after') || '1', 10);
|
||||||
|
core.warning(`Rate limited by Discord. Retrying after ${retryAfter} seconds (attempt ${attempt + 1}/${maxRetries})`);
|
||||||
|
await new Promise(res => setTimeout(res, retryAfter * 1000));
|
||||||
|
attempt++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
if (!response.ok) {
|
||||||
|
core.setFailed(`Discord webhook error: ${JSON.stringify(data)}`);
|
||||||
|
} else {
|
||||||
|
core.info(JSON.stringify(data));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} catch (err) {
|
||||||
|
core.setFailed(err.message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (attempt > maxRetries) {
|
||||||
|
core.setFailed('Exceeded maximum Discord webhook retry attempts due to rate limiting.');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -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": {
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "github-releases-to-discord",
|
"name": "github-releases-to-discord",
|
||||||
"version": "1.15.1",
|
"version": "1.18.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "github-releases-to-discord",
|
"name": "github-releases-to-discord",
|
||||||
"version": "1.15.1",
|
"version": "1.18.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.10.1",
|
"@actions/core": "^1.10.1",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "github-releases-to-discord",
|
"name": "github-releases-to-discord",
|
||||||
"version": "1.15.1",
|
"version": "1.18.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",
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"action": "published",
|
||||||
|
"release": {
|
||||||
|
"html_url": "https://example.com/releases/tag/v1.0.0",
|
||||||
|
"name": "v1.0.0",
|
||||||
|
"body": "## [1.0.0](https://example.com/compare/v0.9.0...v1.0.0) (1970-01-01)\n\n### Features\n* **core:** added initial release ([abc1234](https://example.com/commit/abc1234))\n* **api:** implemented endpoints ([def5678](https://example.com/commit/def5678))\n\n### Bug Fixes\n* **ui:** fixed button alignment ([#42](https://example.com/issues/42)) ([789abcd](https://example.com/commit/789abcd))\n\n### Miscellaneous\n* see [PR #7](https://example.com/pull/7) for details\n"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"full_name": "example/repo",
|
||||||
|
"html_url": "https://example.com/example/repo"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user