-
Notifications
You must be signed in to change notification settings - Fork 10
feat(pagerduty/alert): support integration with pagerduty #400
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
1fcc204
edf2955
3a061fd
17339db
5ba4bed
507ac4b
dfea28f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| name: test-pagerduty-alert | ||
|
|
||
| on: | ||
| merge_group: ~ | ||
| workflow_dispatch: ~ | ||
| pull_request: | ||
| branches: | ||
| - main | ||
| paths: | ||
| - '.github/workflows/test-pagerduty-alert.yml' | ||
| - 'pagerduty/alert/**' | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| test: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v5 | ||
| - uses: ./pagerduty/alert | ||
| if: github.event_name == 'pull_request' | ||
| id: pagerduty-alert | ||
| with: | ||
| summary: 'Test Alert from OBLT Actions' | ||
| source: 'OBLT Actions Test Suite' | ||
| api-key: ${{ secrets.PD_SECRET }} | ||
| component: 'OBLT Actions' | ||
| routing-key: ${{ secrets.PD_ROUTING_KEY }} | ||
| severity: 'critical' | ||
|
|
||
| - name: Assert output is not empty | ||
| if: github.event_name == 'pull_request' | ||
| run: | | ||
| [ -n "${{ steps.pagerduty-alert.outputs.incident-url }}" ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| # <!--name-->pagerduty-alert<!--/name--> | ||
|
|
||
| [](https://github.com/search?q=elastic%2Foblt-actions%2Fpagerduty%2Falert+%28path%3A.github%2Fworkflows+OR+path%3A**%2Faction.yml+OR+path%3A**%2Faction.yaml%29&type=code) | ||
| [](https://github.com/elastic/oblt-actions/actions/workflows/test-pagerduty-alert.yml) | ||
|
|
||
| <!--description--> | ||
| Raise a PagerDuty alert and return the incident URL | ||
| <!--/description--> | ||
|
|
||
| ## Inputs | ||
| <!--inputs--> | ||
| | Name | Description | Required | Default | | ||
| |---------------|------------------------------------|----------|------------| | ||
| | `summary` | The PagerDuty summary of the alert | `true` | ` ` | | ||
| | `source` | The PagerDuty source of the alert | `true` | ` ` | | ||
| | `api-key` | The PagerDuty API key | `true` | ` ` | | ||
| | `component` | The PagerDuty component | `true` | ` ` | | ||
| | `routing-key` | The PagerDuty integration key | `true` | ` ` | | ||
| | `severity` | The PagerDuty severity | `false` | `critical` | | ||
| <!--/inputs--> | ||
|
|
||
| ## Outputs | ||
|
|
||
| <!--outputs--> | ||
| | Name | Description | | ||
| |----------------|----------------------------------------| | ||
| | `incident-url` | The HTML URL of the PagerDuty incident | | ||
| <!--/outputs--> | ||
|
|
||
| ## Usage | ||
| <!--usage action="elastic/oblt-actions/**" version="env:VERSION"--> | ||
| ```yaml | ||
| jobs: | ||
| assign-engineer-urgent-now: | ||
| steps: | ||
| - uses: elastic/oblt-actions/pagerduty/alert@v1 | ||
| id: pagerduty | ||
| with: | ||
| summary: "Reported some errors with XYZ" | ||
| source: "https://..." | ||
| api-key: "${{ secrets.PD_SECRET }}" | ||
| component: "my-component" | ||
| severity: "critical" | ||
| routing-key: "${{ secrets.PD_ROUTING_KEY }}" | ||
|
|
||
| - name: Notify a pagerduty incident has been created | ||
| run: echo "${{steps.pagerduty.outputs.incident-url}} has been created" | ||
|
|
||
| ``` | ||
|
|
||
| <!--/usage--> |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,82 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: 'pagerduty-alert' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: 'Raise a PagerDuty alert and return the incident URL' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| inputs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| summary: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: 'The PagerDuty summary of the alert' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| source: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: 'The PagerDuty source of the alert' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| api-key: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: 'The PagerDuty API key' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| component: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: 'The PagerDuty component' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| routing-key: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: 'The PagerDuty integration key' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| severity: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: 'The PagerDuty severity' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| default: 'critical' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| outputs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| incident-url: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: 'The HTML URL of the PagerDuty incident' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| value: ${{ steps.get_incident.outputs.result }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| using: "composite" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - uses: actions/github-script@v8 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: sanitize | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SUMMARY: ${{ inputs.summary }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| script: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const sanitizedTitle = JSON.stringify(process.env.SUMMARY).slice(1, -1) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log(`sanitized summary is: ${sanitizedTitle}`) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| core.setOutput("summary", sanitizedTitle) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Time window (15 minutes) for searching recent incidents, in milliseconds | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const now = new Date() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const fifteenMinutesAgo = new Date(now.getTime() - (15 * 60 * 1000)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const isoDate = fifteenMinutesAgo.toISOString() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| core.setOutput("time-search", isoDate) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Trigger PagerDuty Alert | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: fjogeleit/http-request-action@1297c6fc63a79b147d1676540a3fd9d2e37817c5 # v1.16.5 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| url: 'https://events.pagerduty.com/v2/enqueue' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| method: 'POST' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| customHeaders: '{"Accept": "application/json", "Content-Type": "application/json", "Authorization" : "Token token=${{ inputs.api-key }}"}' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data: '{"event_action": "trigger", "routing_key": "${{ inputs.routing-key }}", "payload": {"summary": "${{steps.sanitize.outputs.summary}}", "source": "${{ inputs.source }}", "custom_details":"${{ inputs.source }}", "severity": "${{ inputs.severity }}", "component": "${{ inputs.component }}"}}' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
v1v marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data: '{"event_action": "trigger", "routing_key": "${{ inputs.routing-key }}", "payload": {"summary": "${{steps.sanitize.outputs.summary}}", "source": "${{ inputs.source }}", "custom_details":"${{ inputs.source }}", "severity": "${{ inputs.severity }}", "component": "${{ inputs.component }}"}}' | |
| data: '{"event_action": "trigger", "routing_key": "${{ inputs.routing-key }}", "payload": {"summary": "${{steps.sanitize.outputs.summary}}", "source": "${{ inputs.source }}", "custom_details": {"source": "${{ inputs.source }}", "component": "${{ inputs.component }}", "summary": "${{ steps.sanitize.outputs.summary }}"}, "severity": "${{ inputs.severity }}", "component": "${{ inputs.component }}"}}' |
Copilot
AI
Nov 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fetching all incidents from the last 15 minutes without pagination could be inefficient if there are many incidents. Consider adding pagination support or filtering by additional parameters to reduce response size.
| url: 'https://api.pagerduty.com/incidents?since=${{steps.sanitize.outputs.time-search}}&statuses[]=triggered&statuses[]=acknowledged' | |
| url: 'https://api.pagerduty.com/incidents?since=${{steps.sanitize.outputs.time-search}}&statuses[]=triggered&statuses[]=acknowledged&limit=20' |
Copilot
AI
Nov 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a potential race condition: the incident may not be immediately available when fetching. Consider adding retry logic or a small delay between triggering the alert (line 47) and fetching incidents (line 55).
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The incident search retrieves all triggered and acknowledged incidents from the last 15 minutes without pagination limits. In high-traffic environments, this could return many incidents. Consider adding &limit=100 parameter to bound the response size.
| url: 'https://api.pagerduty.com/incidents?since=${{steps.sanitize.outputs.time-search}}&statuses[]=triggered&statuses[]=acknowledged' | |
| url: 'https://api.pagerduty.com/incidents?since=${{steps.sanitize.outputs.time-search}}&statuses[]=triggered&statuses[]=acknowledged&limit=100' |
Copilot
AI
Nov 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parsing the response data without error handling could cause the action to fail silently if the API returns invalid JSON or the response is unexpectedly structured. Add try-catch error handling to provide meaningful error messages.
| const parsedData = JSON.parse(responseData) | |
| let parsedData; | |
| try { | |
| parsedData = JSON.parse(responseData) | |
| } catch (error) { | |
| console.error('Failed to parse PagerDuty incident response as JSON:', error) | |
| throw new Error('Invalid JSON response from PagerDuty incidents API') | |
| } |
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using template literals to embed GitHub Actions output can break if the response contains backticks or special characters. Use fromJSON directly: const parsedData = JSON.parse('${{ steps.pagerduty_incident.outputs.response }}')
| const responseData = `${{ steps.pagerduty_incident.outputs.response }}` | |
| const parsedData = JSON.parse(responseData) | |
| const summary = process.env.SUMMARY | |
| const parsedData = ${{ fromJSON(steps.pagerduty_incident.outputs.response) }} | |
| const summary = process.env.SUMMARY |
Copilot
AI
Nov 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The search assumes 'parsedData.incidents' exists and is an array. If the PagerDuty API returns an error or unexpected structure, this will throw an error. Add validation to check if 'incidents' exists before accessing it.
| const specificIncident = parsedData.incidents.find(incident => incident.title === summary) | |
| let specificIncident = null; | |
| if (parsedData && Array.isArray(parsedData.incidents)) { | |
| specificIncident = parsedData.incidents.find(incident => incident.title === summary) | |
| } else { | |
| console.log('No incidents array found in PagerDuty response.'); | |
| } |
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Race condition: The incident search queries PagerDuty immediately after triggering the alert (lines 56-62), but PagerDuty may not have processed and indexed the incident yet. Consider adding a retry mechanism with exponential backoff or a brief delay before searching.
| - name: Fetch PagerDuty Incidents | |
| id: pagerduty_incident | |
| uses: fjogeleit/http-request-action@1297c6fc63a79b147d1676540a3fd9d2e37817c5 # v1.16.5 | |
| with: | |
| url: 'https://api.pagerduty.com/incidents?since=${{steps.sanitize.outputs.time-search}}&statuses[]=triggered&statuses[]=acknowledged' | |
| method: 'GET' | |
| customHeaders: '{"Accept": "application/json", "Content-Type": "application/json", "Authorization" : "Token token=${{ inputs.api-key }}"}' | |
| - name: Search the incident | |
| uses: actions/github-script@v8 | |
| id: get_incident | |
| env: | |
| SUMMARY: ${{ steps.sanitize.outputs.summary }} | |
| with: | |
| script: | | |
| const responseData = `${{ steps.pagerduty_incident.outputs.response }}` | |
| const parsedData = JSON.parse(responseData) | |
| const summary = process.env.SUMMARY | |
| const specificIncident = parsedData.incidents.find(incident => incident.title === summary) | |
| if (specificIncident) { | |
| console.log(`Found HTML URL: ${specificIncident.html_url}`) | |
| return specificIncident.html_url | |
| } else { | |
| console.log('No incident found.') | |
| return '' | |
| } | |
| # Removed "Fetch PagerDuty Incidents" step; incident fetching and retry logic moved to next step. | |
| - name: Search the incident with retry | |
| uses: actions/github-script@v8 | |
| id: get_incident | |
| env: | |
| SUMMARY: ${{ steps.sanitize.outputs.summary }} | |
| API_KEY: ${{ inputs.api-key }} | |
| TIME_SEARCH: ${{ steps.sanitize.outputs.time-search }} | |
| with: | |
| script: | | |
| const fetch = require('node-fetch'); | |
| const summary = process.env.SUMMARY; | |
| const apiKey = process.env.API_KEY; | |
| const timeSearch = process.env.TIME_SEARCH; | |
| const maxAttempts = 5; | |
| let attempt = 0; | |
| let delay = 1000; // start with 1s | |
| let specificIncident = null; | |
| const url = `https://api.pagerduty.com/incidents?since=${encodeURIComponent(timeSearch)}&statuses[]=triggered&statuses[]=acknowledged`; | |
| const headers = { | |
| "Accept": "application/json", | |
| "Content-Type": "application/json", | |
| "Authorization": `Token token=${apiKey}` | |
| }; | |
| async function sleep(ms) { | |
| return new Promise(resolve => setTimeout(resolve, ms)); | |
| } | |
| async function findIncident() { | |
| for (attempt = 1; attempt <= maxAttempts; attempt++) { | |
| try { | |
| const res = await fetch(url, { method: 'GET', headers }); | |
| if (!res.ok) { | |
| throw new Error(`PagerDuty API error: ${res.status} ${res.statusText}`); | |
| } | |
| const parsedData = await res.json(); | |
| specificIncident = parsedData.incidents.find(incident => incident.title === summary); | |
| if (specificIncident) { | |
| console.log(`Found HTML URL: ${specificIncident.html_url} on attempt ${attempt}`); | |
| return specificIncident.html_url; | |
| } else { | |
| console.log(`Attempt ${attempt}: Incident not found, retrying after ${delay}ms...`); | |
| await sleep(delay); | |
| delay *= 2; // exponential backoff | |
| } | |
| } catch (err) { | |
| console.log(`Attempt ${attempt}: Error fetching incidents: ${err.message}`); | |
| await sleep(delay); | |
| delay *= 2; | |
| } | |
| } | |
| console.log('No incident found after retries.'); | |
| return ''; | |
| } | |
| return await findIncident(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use https://github.com/marketplace/actions/http-request-action?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because this is a copy of an existing composite action - so I prefered to keep the same implementation from now
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually that's the one we use