-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Update labeled PR CI checks #12344
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?
Update labeled PR CI checks #12344
Conversation
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.
Pull Request Overview
This PR enhances the CI by adding jobs to monitor and cancel remote workflow runs, introduces reusable helper modules for GitHub API interactions, and refactors the dispatch step.
- Add
wait-completion
andcancel-workflow
jobs to poll a triggered workflow and cancel it on cancellation. - Introduce
GitHubApi.psm1
andWaitWorkflowCompletion.ps1
helpers for dispatching and polling workflows. - Refactor
trigger-workflow
step intrigger-ubuntu-win-build.yml
to use the new GitHubApi module.
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
File | Description |
---|---|
helpers/WaitWorkflowCompletion.ps1 | New script to locate, poll, retry, and cancel a triggered workflow run |
helpers/GitHubApi.psm1 | New PowerShell module encapsulating GitHub REST API calls (dispatch, list, cancel, rerun) |
.github/workflows/trigger-ubuntu-win-build.yml | Updated CI workflow: dispatch step refactored; added wait-completion and cancel-workflow jobs |
Comments suppressed due to low confidence (3)
helpers/GitHubApi.psm1:1
- Rename the class to
GitHubApi
to match the module/file name casing and maintain consistency with GitHub branding.
class GithubApi
helpers/WaitWorkflowCompletion.ps1:17
- [nitpick] Add comment-based help (e.g.,
<# .SYNOPSIS ... #>
) for this public function to describe its purpose and parameters.
function Find-TriggeredWorkflow($WorkflowFileName, $WorkflowSearchPattern) {
helpers/WaitWorkflowCompletion.ps1:1
- There are no unit or integration tests covering these new helper scripts; consider adding tests to validate the polling, retry, and cancellation logic.
Param (
if ([string]::IsNullOrEmpty($AccessToken)) { | ||
return $null | ||
} | ||
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("'':${AccessToken}")) |
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 string ''
before the colon will produce an invalid credential; use ":${AccessToken}"
or include a username (e.g., username:${AccessToken}
) when encoding.
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("'':${AccessToken}")) | |
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":${AccessToken}")) |
Copilot uses AI. Check for mistakes.
helpers/WaitWorkflowCompletion.ps1
Outdated
"CI_WORKFLOW_RUN_RESULT=$($workflowRun.status)/timeout" | Out-File -Append -FilePath $env:GITHUB_ENV | ||
"CI_WORKFLOW_RUN_URL=$($workflowRun.html_url)" | Out-File -Append -FilePath $env:GITHUB_ENV |
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.
Specify the file encoding (e.g., -Encoding UTF8
) when writing to $GITHUB_ENV
to ensure the environment file is parsed correctly.
"CI_WORKFLOW_RUN_RESULT=$($workflowRun.status)/timeout" | Out-File -Append -FilePath $env:GITHUB_ENV | |
"CI_WORKFLOW_RUN_URL=$($workflowRun.html_url)" | Out-File -Append -FilePath $env:GITHUB_ENV | |
"CI_WORKFLOW_RUN_RESULT=$($workflowRun.status)/timeout" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding UTF8 | |
"CI_WORKFLOW_RUN_URL=$($workflowRun.html_url)" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding UTF8 |
Copilot uses AI. Check for mistakes.
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.
New changes and updates help fix problems and improve the build process,
- name: Trigger Build workflow | ||
env: | ||
CI_PR_TOKEN: ${{ secrets.CI_PR_TOKEN }} | ||
PR_TITLE: ${{ github.event.pull_request.title }} | ||
CI_PR: ${{ secrets.CI_REPO }} | ||
CI_REPO: ${{ vars.CI_REPO }} |
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 would expose CI repo name. Probably not a big deal but curious if this is a deliberate change?
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.
Change is intentional, as we want to get run URL for easier troubleshooting
} | ||
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("'':${AccessToken}")) | ||
return @{ | ||
Authorization = "Basic ${base64AuthInfo}" |
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.
Previously we used Bearer auth and passed token directly, which also helps with secret masking because token value is unchanged. Is there a particular reason in switching to Basic auth? It looks like you use the same API.
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 is no particular reason other than reusing the code. As far as I know, Actions mask popular encodings of the secret in the logs with base64
being one of them
helpers/WaitWorkflowCompletion.ps1
Outdated
|
||
if ($finishedWorkflowRun.conclusion -eq "success") { | ||
exit 0 | ||
} elseif ($finishedWorkflowRun.conclusion -in ("failure", "cancelled")) { |
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.
Are there any other choices for the workflow conclusion that could fall through into else
?
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 are, should probably add timed_out
as fail case
helpers/WaitWorkflowCompletion.ps1
Outdated
"CI_WORKFLOW_RUN_RESULT=$($workflowRun.status)/timeout" | Out-File -Append -FilePath $env:GITHUB_ENV | ||
"CI_WORKFLOW_RUN_URL=$($workflowRun.html_url)" | Out-File -Append -FilePath $env:GITHUB_ENV | ||
$gitHubApi.CancelWorkflowRun($workflowRunId) | ||
throw "The workflow run is still in the '$($workflowRun.status)' state for $AttemptTimeoutInMinutes minutes. Cancelling the run." |
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 is a way to define workflow timeout on the yaml. If we want to terminate CI earlier than the default 6 hours then we probably should define the timeout on the CI workflow. I do not think this code should act as a watchdog for the CI, it just needs to wait...
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.
Makes sense, don't really see $AttemptTimeoutInMinutes usefulness at the moment, will remove related code
runs-on: ubuntu-latest | ||
needs: trigger-workflow | ||
outputs: | ||
ci_workflow_run_id: ${{ steps.wait.outputs.ci_workflow_run_id }} |
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.
nit: Consider resolving workflow run ID in the trigger
job. The this job is solely responsible for awaiting the given workflow run and cancellation job would not need to depend on it (except for ordering reasons).
Ideally repo dispatch event would return workflow run id (which is a feature community has been longing for) and once it is supported in Actions we would simply switch to using it instead of resolving workflow id from the title.
helpers/WaitWorkflowCompletion.ps1
Outdated
} elseif ($finishedWorkflowRun.conclusion -eq "failure") { | ||
if ($attempt -le $MaxRetryCount) { | ||
Write-Host "Workflow run will be restarted. Attempt $attempt of $MaxRetryCount" | ||
$gitHubApi.ReRunFailedJobs($workflowRunId) |
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.
Can we restart this job by restarting the failed check run on the PR? This would make it a natural fit into the PR experience. Normally when a check fails it requires a manual rerun. And if it already works today then we do not need these retries (besides I do not think you use them anyway)
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.
From what I have seen, while workflow run is in progress its jobs cannot be restarted. Such functionality will require something like a separate workflow, which is run on failure of the PR check and restarts it.
It will surely make things more robust if we want to consider retries in the future, in cases such as windows build failing due to sporadic issue 3 hours into the run, but will add complexity
helpers/WaitWorkflowCompletion.ps1
Outdated
|
||
function Find-TriggeredWorkflow($WorkflowFileName, $WorkflowSearchPattern) { | ||
$workflowRuns = $gitHubApi.GetWorkflowRuns($WorkflowFileName).workflow_runs | ||
$workflowRunId = ($workflowRuns | Where-Object {$_.display_title -match $WorkflowSearchPattern}).id | Select-Object -First 1 |
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.
If job is retried I assume there will be multiple runs that match the pattern? Will it pick latest? Or should we filter only the "running" workflows?
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.
Retry in this case refers to re-running the workflow run, which increases attempt count. Filtering will pick up the latest
Description
This PR:
wait-completion
will periodically check status of the remote workflow runcancel-workflow
will cancel remote workflow run if check is cancelledtrigger-workflow
jobRelated issue: https://github.com/github/hosted-runners-images/issues/98
Check list