Skip to content

Commit

Permalink
feat: update slackWebhookUrls to allow multiple hooks (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
thedaviddias authored Aug 3, 2023
1 parent 24cb334 commit f14c145
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ jobs:
uses: ./
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
slack_webhook_urls: ${{ secrets.SLACK_WEBHOOK_URL }}
sentry_project_name: ${{ secrets.SENTRY_PROJECT_NAME }}
sentry_project_id: ${{ secrets.SENTRY_PROJECT_ID }}
grafana_dashboard_link: https://example.grafana.net/d/xxxx/web-overview?orgId=1
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
uses: thedaviddias/[email protected]
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
slack_webhook_url: https://hooks.slack.com/services/XXXXXX/XXXXX/XXXXXXX
slack_webhook_urls: https://hooks.slack.com/services/XXXXXX/XXXXX/XXXXXXX
jira_ticket_prefix: ABC
jira_instance_url: https://your-jira-instance.com
sentry_project_name: MyProject
Expand All @@ -56,7 +56,7 @@ jobs:
| `tag_regex` | no | ^v[0-9]+\\.[0-9]+\\.[0-9]+$ | Regex to accommodate varying tag formatting |
| `contributor_replace_regex` | no | | Regular expression (regex) pattern to identify characters in the `contributor` name that will be replaced |
| `contributor_replace_char` | no | | The character that will replace specific characters in the `contributor` name |
| `slack_webhook_url` | no | | Slack webhook URL to receive release notifications |
| `slack_webhook_urls` | no | | Slack webhook URL to receive release notifications |
| `jira_ticket_prefix` | no | | Prefix for JIRA ticket references in PR titles (e.g. ABC) |
| `jira_instance_url` | no | | URL for your JIRA instance to generate JIRA ticket links (e.g. https://your-jira-instance.com) |
| `sentry_project_name` | no | | ID of the Sentry project for error tracking |
Expand Down
4 changes: 2 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ inputs:
description: The custom URL of the JIRA instance.
required: false

slack_webhook_url:
description: The URL of the Slack Webhook to which the action will send a message with the changelog and release details.
slack_webhook_urls:
description: Comma-separated list of Slack Webhook URLs to which the action will send a message with the changelog and release details.
required: false

sentry_project_name:
Expand Down
2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ describe('run function', () => {
grafanaDashboardLink: 'http://mock-grafana-link',
sentryProjectName: 'mock-sentry-project-name',
sentryProjectId: 'mock-sentry-project-id',
slackWebhookUrl: 'http://mock-webhook-url',
slackWebhookUrls: 'http://mock-webhook-url',
jiraInstanceUrl: 'http://mock-jira-instance-url',
jiraTicketPrefix: 'ABC',
contributorReplaceChar: '.',
contributorReplaceRegex: '-',
tagRegex: '^v[0-9]+\\.[0-9]+\\.[0-9]+$'
tagRegex: '^v[0-9]+\\.[0-9]+\\.[0-9]+$',
})

const getOwnerAndRepoMock = jest.spyOn(getOwnerAndRepoModule, 'getOwnerAndRepo')
Expand Down Expand Up @@ -107,7 +107,6 @@ describe('run function', () => {
)
generateReleaseLinkMock.mockReturnValue('http://mock-release-link')


// const getCommitOfTagMock = jest.spyOn(getCommitOfTagModule, 'getCommitOfTag')
// getCommitOfTagMock.mockResolvedValue({ data: { html_url: 'http://mock-commit-url' } })

Expand Down
20 changes: 11 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ export async function run(): Promise<void> {
return
}

// Use the first capture group as the version number
const currentVersion = currentVersionMatch[1];
const previousVersion = previousVersionMatch[1];
// Use the first capture group as the version number
const currentVersion = currentVersionMatch[1]
const previousVersion = previousVersionMatch[1]

const comparisonResult = compareSemVer(currentVersion, previousVersion)

Expand Down Expand Up @@ -97,14 +97,14 @@ export async function run(): Promise<void> {
)

// Get the Slack webhook URL from the GitHub Action input
const slackWebhookUrl = core.getInput('slack_webhook_url')
const slackWebhookUrls = core.getInput('slack_webhook_urls').split(',')

if (!slackWebhookUrl) {
if (!slackWebhookUrls.length) {
// If the Slack webhook URL is not provided, skip sending the notification to Slack
core.debug(
'Missing slack_webhook_url input, no publication to Slack with be done but the release info will be available as output.'
'Missing slack_webhook_urls input, no publication to Slack with be done but the release info will be available as output.'
)
// Prepare output data even if slackWebhookUrl is not present
// Prepare output data even if slackWebhookUrls is not present
const outputData = {
repo,
repoLink,
Expand Down Expand Up @@ -166,8 +166,10 @@ export async function run(): Promise<void> {
currentDate
)

await axios.post(slackWebhookUrl, slackData)
core.info('Message sent to Slack.')
for (const url of slackWebhookUrls) {
await axios.post(url.trim(), slackData)
core.info(`Message to Slack`)
}
} catch (error) {
// If an error occurs during the script execution, fail the GitHub Action and output the error message
if (error instanceof Error) {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/__tests__/__mocks__/testData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export const MOCK_GET_INPUTS = {
sentryProjectName: 'myProject',
sentryProjectId: '123',
grafanaDashboardLink: 'https://grafana.myProject.com',
slackWebhookUrl: 'https://hooks.slack.com/services/123/456/789',
slackWebhookUrls: 'https://hooks.slack.com/services/123/456/789',
jiraTicketPrefix: 'ABC',
jiraInstanceUrl: 'https://jira.myProject.com',
contributorReplaceChar: '.',
Expand Down
2 changes: 1 addition & 1 deletion src/utils/__tests__/generateSlackMessage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ describe('generateSlackMessage', () => {
sentryProjectName: '',
sentryProjectId: '',
grafanaDashboardLink: '',
slackWebhookUrl: '',
slackWebhookUrls: '',
}
const slackMessage = generateSlackMessage(
MOCK_REPO_LINK,
Expand Down
17 changes: 9 additions & 8 deletions src/utils/__tests__/getInputs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('getInputs', () => {
return 'my-project-name'
case 'sentry_project_id':
return 'invalid-project-id' // Note: this is not a valid numeric ID
case 'slack_webhook_url':
case 'slack_webhook_urls':
return 'invalid-webhook-url' // Note: this is not a valid URL that starts with 'https://hooks.slack.com'
case 'jira_instance_url':
return 'invalid-jira-ticket-link' // Note: this is not a valid URL
Expand All @@ -39,20 +39,20 @@ describe('getInputs', () => {
grafanaDashboardLink: 'my-dashboard-link',
sentryProjectName: 'my-project-name',
sentryProjectId: 'invalid-project-id',
slackWebhookUrl: 'invalid-webhook-url',
slackWebhookUrls: 'invalid-webhook-url',
jiraInstanceUrl: 'invalid-jira-ticket-link/browse/',
jiraTicketPrefix: 'ABC',
contributorReplaceChar: '.',
contributorReplaceRegex: '-',
tagRegex: 'my-tag-regex'
tagRegex: 'my-tag-regex',
}

expect(getInputs()).toEqual(expectedInputs)
expect(core.getInput).toHaveBeenCalledWith('repo')
expect(core.getInput).toHaveBeenCalledWith('grafana_dashboard_link')
expect(core.getInput).toHaveBeenCalledWith('sentry_project_name')
expect(core.getInput).toHaveBeenCalledWith('sentry_project_id')
expect(core.getInput).toHaveBeenCalledWith('slack_webhook_url')
expect(core.getInput).toHaveBeenCalledWith('slack_webhook_urls')
expect(core.getInput).toHaveBeenCalledWith('jira_instance_url')
expect(core.getInput).toHaveBeenCalledWith('jira_ticket_prefix')
expect(core.getInput).toHaveBeenCalledWith('tag_regex')
Expand Down Expand Up @@ -85,8 +85,8 @@ describe('getInputs', () => {
return 'my-project-name'
case 'sentry_project_id':
return '1234'
case 'slack_webhook_url':
return 'https://hooks.slack.com/services/XXXX/XXXX/XXXX'
case 'slack_webhook_urls':
return 'https://hooks.slack.com/services/XXXX/XXXX/XXXX,https://hooks.slack.com/services/XXXX/XXXX/XXXX'
case 'jira_instance_url':
return 'https://example.atlassian.net' // Note: this is a valid URL
case 'jira_ticket_prefix':
Expand All @@ -110,7 +110,8 @@ describe('getInputs', () => {
grafanaDashboardLink: 'https://grafana.com/dashboards/my-dashboard-link',
sentryProjectName: 'my-project-name',
sentryProjectId: '1234',
slackWebhookUrl: 'https://hooks.slack.com/services/XXXX/XXXX/XXXX',
slackWebhookUrls:
'https://hooks.slack.com/services/XXXX/XXXX/XXXX,https://hooks.slack.com/services/XXXX/XXXX/XXXX',
jiraInstanceUrl: 'https://example.atlassian.net/browse/',
jiraTicketPrefix: 'ABC',
contributorReplaceChar: '.',
Expand All @@ -124,7 +125,7 @@ describe('getInputs', () => {
expect(core.getInput).toHaveBeenCalledWith('grafana_dashboard_link')
expect(core.getInput).toHaveBeenCalledWith('sentry_project_name')
expect(core.getInput).toHaveBeenCalledWith('sentry_project_id')
expect(core.getInput).toHaveBeenCalledWith('slack_webhook_url')
expect(core.getInput).toHaveBeenCalledWith('slack_webhook_urls')
expect(core.getInput).toHaveBeenCalledWith('jira_instance_url')
expect(core.getInput).toHaveBeenCalledWith('jira_ticket_prefix')
expect(core.getInput).toHaveBeenCalledWith('contributor_replace_char')
Expand Down
23 changes: 14 additions & 9 deletions src/utils/getInputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export interface GetInputsType {
sentryProjectName: string
sentryProjectId: string
grafanaDashboardLink: string
slackWebhookUrl: string
slackWebhookUrls: string
jiraTicketPrefix: string
jiraInstanceUrl: string
contributorReplaceChar: string
Expand All @@ -48,7 +48,7 @@ export function getInputs(): GetInputsType {
const grafanaDashboardLink = core.getInput('grafana_dashboard_link') || ''
const sentryProjectName = core.getInput('sentry_project_name') || ''
const sentryProjectId = core.getInput('sentry_project_id') || ''
const slackWebhookUrl = core.getInput('slack_webhook_url') || ''
const slackWebhookUrls = core.getInput('slack_webhook_urls') || ''
const contributorReplaceChar = core.getInput('contributor_replace_char') || ''
const contributorReplaceRegex = core.getInput('contributor_replace_regex') || ''

Expand All @@ -57,12 +57,17 @@ export function getInputs(): GetInputsType {
core.warning(`Invalid Grafana dashboard link: ${grafanaDashboardLink}`)
}

if (
slackWebhookUrl &&
(!isValidUrl(slackWebhookUrl) ||
!slackWebhookUrl.startsWith('https://hooks.slack.com'))
) {
core.warning(`Invalid Slack webhook URL: ${slackWebhookUrl}`)
// Now split the slackWebhookUrls and validate each one
const slackWebhookUrlArray = slackWebhookUrls.split(',')

for (const url of slackWebhookUrlArray) {
const trimmedUrl = url.trim()
if (
!isValidUrl(trimmedUrl) ||
!trimmedUrl.startsWith('https://hooks.slack.com')
) {
core.warning(`Invalid Slack webhook URL: ${trimmedUrl}`)
}
}

// Input value checking for repo format
Expand Down Expand Up @@ -100,7 +105,7 @@ export function getInputs(): GetInputsType {
grafanaDashboardLink,
sentryProjectName,
sentryProjectId,
slackWebhookUrl,
slackWebhookUrls,
jiraTicketPrefix,
jiraInstanceUrl: jiraInstanceUrlProcessed,
contributorReplaceChar,
Expand Down

0 comments on commit f14c145

Please sign in to comment.