Skip to content

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

shamil-mubarakshin
Copy link
Contributor

Description

This PR:

  1. Adds 2 jobs to trigger-ubuntu-win-build.yml:
    • wait-completion will periodically check status of the remote workflow run
    • cancel-workflow will cancel remote workflow run if check is cancelled
  2. Adds GitHubApi.psm1 and WaitWorkflowCompletion.ps1 to support new functionality
  3. Refactors trigger-workflow job

Related issue: https://github.com/github/hosted-runners-images/issues/98

Check list

  • Related issue / work item is attached
  • Tests are written (if applicable)
  • Documentation is updated (if applicable)
  • Changes are tested and related VM images are successfully generated

@Copilot Copilot AI review requested due to automatic review settings June 9, 2025 15:52
Copy link
Contributor

@Copilot Copilot AI left a 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 and cancel-workflow jobs to poll a triggered workflow and cancel it on cancellation.
  • Introduce GitHubApi.psm1 and WaitWorkflowCompletion.ps1 helpers for dispatching and polling workflows.
  • Refactor trigger-workflow step in trigger-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}"))
Copy link
Preview

Copilot AI Jun 9, 2025

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.

Suggested change
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("'':${AccessToken}"))
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":${AccessToken}"))

Copilot uses AI. Check for mistakes.

Comment on lines 34 to 35
"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
Copy link
Preview

Copilot AI Jun 9, 2025

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.

Suggested change
"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.

Copy link

@yalan2ny yalan2ny left a 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 }}
Copy link
Contributor

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?

Copy link
Contributor Author

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}"
Copy link
Contributor

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.

Copy link
Contributor Author

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


if ($finishedWorkflowRun.conclusion -eq "success") {
exit 0
} elseif ($finishedWorkflowRun.conclusion -in ("failure", "cancelled")) {
Copy link
Contributor

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?

Copy link
Contributor Author

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

"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."
Copy link
Contributor

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...

Copy link
Contributor Author

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 }}
Copy link
Contributor

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.

} elseif ($finishedWorkflowRun.conclusion -eq "failure") {
if ($attempt -le $MaxRetryCount) {
Write-Host "Workflow run will be restarted. Attempt $attempt of $MaxRetryCount"
$gitHubApi.ReRunFailedJobs($workflowRunId)
Copy link
Contributor

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)

Copy link
Contributor Author

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


function Find-TriggeredWorkflow($WorkflowFileName, $WorkflowSearchPattern) {
$workflowRuns = $gitHubApi.GetWorkflowRuns($WorkflowFileName).workflow_runs
$workflowRunId = ($workflowRuns | Where-Object {$_.display_title -match $WorkflowSearchPattern}).id | Select-Object -First 1
Copy link
Contributor

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?

Copy link
Contributor Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants