-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
chore: rerun workflow from failed #28143
Merged
Merged
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
936457d
rerun from failed
seaona 789ea52
failure on purpose to test
seaona 8ac2c9a
remove extra lines
seaona 78de128
rerun script always
seaona 7068048
required completed or canceled
seaona f911c7f
run always
seaona 8098eea
rerun using trigger
seaona 26da987
typo
seaona 02cde93
add description
seaona 29a895e
description
seaona f801957
rerun from failed
seaona 2cc00ae
remov extre deps
seaona 4c0ef28
config fix
seaona 08d53b1
edit name
seaona 6e99343
Merge branch 'develop' into rerun-workflow-failed
seaona 894483d
testing
seaona 6aad247
add logs
seaona 1fac883
parse response
seaona 65a2bc2
add more logs
seaona 81baf57
api-v2
seaona bc5d452
add logging on each step
seaona 6f1a1d0
final logs
seaona 8206ed0
finished testing, adding filter back
seaona 6a45bf8
another test for rerun
seaona a0d82ee
id
seaona 63fd294
add filters back
seaona 48529ba
remove token for get requests, and remove filter for tesst
seaona 39017df
add filter back
seaona 88c0e66
Merge branch 'develop' into rerun-workflow-failed
seaona e95eec3
addressed comment: uncaught promise error
seaona a4dd676
address comment for tsx use
seaona eb7ef3a
remove filters to test last changes
seaona e01f7ee
tested successfully - add filters back
seaona File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
const CIRCLE_TOKEN = process.env.API_V2_TOKEN; | ||
|
||
interface Actor { | ||
login: string; | ||
avatar_url: string | null; | ||
} | ||
|
||
interface Trigger { | ||
received_at: string; | ||
type: string; | ||
actor: Actor; | ||
} | ||
|
||
interface VCS { | ||
origin_repository_url: string; | ||
target_repository_url: string; | ||
revision: string; | ||
provider_name: string; | ||
branch: string; | ||
} | ||
|
||
interface WorkflowItem { | ||
id: string; | ||
errors: string[]; | ||
project_slug: string; | ||
updated_at: string; | ||
number: number; | ||
state: string; | ||
created_at: string; | ||
trigger: Trigger; | ||
vcs: VCS; | ||
} | ||
|
||
interface CircleCIResponse { | ||
next_page_token: string | null; | ||
items: WorkflowItem[]; | ||
} | ||
|
||
interface WorkflowStatusItem { | ||
pipeline_id: string; | ||
id: string; | ||
name: string; | ||
project_slug: string; | ||
tag?: string; | ||
status: string; | ||
started_by: string; | ||
pipeline_number: number; | ||
created_at: string; | ||
stopped_at: string; | ||
} | ||
|
||
interface WorkflowStatusResponse { | ||
next_page_token: string | null; | ||
items: WorkflowStatusItem[]; | ||
} | ||
|
||
/** | ||
* Fetches the last 20 CircleCI workflows for the given branch. | ||
* Note: the API returns the first 20 workflows by default. | ||
* If we wanted to get older workflows, we would need to use the 'page-token' we would get in the first response | ||
* and perform a subsequent request with the 'page-token' parameter. | ||
* This seems unnecessary as of today, as the amount of daily PRs merged to develop is not that high. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good decision. Easier to run this multiple times throughout the day, rather than support paging through more runs. |
||
* | ||
* @returns {Promise<WorkflowItem[]>} A promise that resolves to an array of workflow items. | ||
* @throws Will throw an error if the CircleCI token is not defined or if the HTTP request fails. | ||
*/ | ||
async function getCircleCiWorkflowsByBranch(branch: string): Promise<WorkflowItem[]> { | ||
if (!CIRCLE_TOKEN) { | ||
throw new Error('CircleCI token is not defined'); | ||
} | ||
|
||
const url = `https://circleci.com/api/v2/project/github/${process.env.CIRCLE_PROJECT_USERNAME}/${process.env.CIRCLE_PROJECT_REPONAME}/pipeline?branch=${branch}`; | ||
const options = { | ||
method: 'GET', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
} | ||
}; | ||
|
||
try { | ||
const response = await fetch(url, options); | ||
if (!response.ok) { | ||
const errorBody = await response.text(); | ||
console.error('HTTP error response:', errorBody); | ||
throw new Error(`HTTP error! status: ${response.status}`); | ||
} | ||
const body = await response.json(); | ||
console.log('Circle Ci workflows fetched successfully!'); | ||
return body.items; | ||
} catch (error) { | ||
console.error('Error:', error); | ||
throw error; | ||
} | ||
} | ||
|
||
/** | ||
* Fetches the status of a specific CircleCI workflow. | ||
* | ||
* @param {string} workflowId - The ID of the workflow to fetch the status for. | ||
* @returns {Promise<WorkflowStatusResponse>} A promise that resolves to the workflow status response. | ||
* @throws Will throw an error if the CircleCI token is not defined or if the HTTP request fails. | ||
*/ | ||
async function getWorkflowStatusById(workflowId: string): Promise<WorkflowStatusResponse> { | ||
if (!CIRCLE_TOKEN) { | ||
throw new Error('CircleCI token is not defined'); | ||
} | ||
|
||
const url = `https://circleci.com/api/v2/pipeline/${workflowId}/workflow`; | ||
const options = { | ||
method: 'GET', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
} | ||
}; | ||
|
||
try { | ||
console.log(`Fetching workflow ${workflowId}...`); | ||
|
||
const response = await fetch(url, options); | ||
if (!response.ok) { | ||
const errorBody = await response.text(); | ||
console.error('HTTP error response:', errorBody); | ||
throw new Error(`HTTP error! status: ${response.status}`); | ||
} | ||
const workflowStatus = await response.json(); | ||
|
||
console.log(`Number of runs: ${workflowStatus.items.length}`); | ||
console.log(`Workflow status from last run: ${workflowStatus.items[0].status}`); | ||
|
||
return workflowStatus; | ||
|
||
} catch (error) { | ||
console.error('Error:', error); | ||
throw error; | ||
} | ||
} | ||
|
||
/** | ||
* Reruns a CircleCI workflow by its ID. | ||
* | ||
* @param {string} workflowId - The ID of the workflow to rerun. | ||
* @throws Will throw an error if the CircleCI token is not defined or if the HTTP request fails. | ||
*/ | ||
async function rerunWorkflowById(workflowId: string) { | ||
if (!CIRCLE_TOKEN) { | ||
throw new Error('CircleCI token is not defined'); | ||
} | ||
|
||
const url = `https://circleci.com/api/v2/workflow/${workflowId}/rerun`; | ||
const options = { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
'Circle-Token': CIRCLE_TOKEN, | ||
}, | ||
body: JSON.stringify({ | ||
enable_ssh: false, | ||
from_failed: true, | ||
sparse_tree: false, // mutually exclusive with the from_failed parameter | ||
}) | ||
}; | ||
|
||
try { | ||
console.log(`Rerunning workflow ${workflowId}...`); | ||
const response = await fetch(url, options); | ||
if (!response.ok) { | ||
const errorBody = await response.text(); | ||
console.error('HTTP error response:', errorBody); | ||
throw new Error(`HTTP error! status: ${response.status}`); | ||
} | ||
const body = await response.json(); | ||
console.log('Workflow rerun successfully!'); | ||
console.log(body); | ||
} catch (error) { | ||
console.error('Error:', error); | ||
} | ||
} | ||
|
||
/** | ||
* Re-runs failed CircleCI workflows from develop branch. | ||
* The workflow will only be re-runed if: | ||
* 1. It has the status of 'failed' | ||
* 2. It has only been run once | ||
* 3. It is among the most recent 20 workflows | ||
* 4. It was triggered by the 'github-merge-queue[bot]' user | ||
* | ||
* @throws Will throw an error if fetching the workflows or re-running a workflow fails. | ||
*/ | ||
async function rerunFailedWorkflowsFromDevelop() { | ||
console.log('Getting Circle Ci workflows from develop branch...'); | ||
const workflows = await getCircleCiWorkflowsByBranch('develop'); | ||
|
||
console.log('Assessing if any of the workflows needs to be rerun...'); | ||
for (const item of workflows) { | ||
if (item.trigger.actor.login === 'github-merge-queue[bot]') { | ||
const workflowStatus = await getWorkflowStatusById(item.id); | ||
|
||
if (workflowStatus.items.length === 1 && workflowStatus.items[0].status === 'failed') { | ||
await rerunWorkflowById(workflowStatus.items[0].id); | ||
console.log(`Rerun workflow with ID: ${workflowStatus.items[0].id}`); | ||
} | ||
} | ||
} | ||
console.log('Task completed successfully!'); | ||
} | ||
|
||
rerunFailedWorkflowsFromDevelop() | ||
.catch((error) => { | ||
console.error(error); | ||
process.exitCode = 1; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
this workflow will only run in develop, and if it's triggered with this exact name