Skip to content
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

Fix partial build #837

Merged
merged 65 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
d427640
Add baselineWorkflowRunID to use for downloading dependencies in incr…
mazhelez Nov 27, 2023
2d96c24
Add baselineWorkflowRunId param to Download Project Dependencies action
mazhelez Nov 27, 2023
b1f7b8a
Integer --> int
mazhelez Nov 27, 2023
e42a35a
Add missing bracket
mazhelez Nov 28, 2023
53f1f95
Fix Calculate Baseline Workflow Run actions
mazhelez Nov 28, 2023
767b280
Import GitHub-Helper
mazhelez Nov 28, 2023
f40a928
Fix output name
mazhelez Nov 28, 2023
f167371
Use paranthessis for workflow input
mazhelez Nov 28, 2023
1ccbd8e
Use string for baselineWorkflowRunId
mazhelez Nov 28, 2023
2d9cdcb
Use string baselineWorkflowRunID (part 2)
mazhelez Nov 28, 2023
ecfaa8a
Use baselineWorkflowRunID as string
mazhelez Nov 28, 2023
d495975
Merge branch 'main' of https://github.com/microsoft/AL-Go into fix-in…
mazhelez Nov 28, 2023
0768764
Add "return $result" (merge issue)
mazhelez Nov 28, 2023
56ae4a6
Rename CalculateBaselineWorkflowRun => DetermineBaselineWorkflowRun
mazhelez Nov 28, 2023
060a9ad
Pass baselineWorkflowRunID as a parameter
mazhelez Dec 4, 2023
97332ad
Rename variable, areBuildJobsSuccessful
mazhelez Dec 4, 2023
479c694
Improve README
mazhelez Dec 4, 2023
380c330
Use PS module for DetermineProjectsToBuild
mazhelez Dec 4, 2023
583d33d
Add missing export in PS module
mazhelez Dec 4, 2023
56e4c32
Output IsFullBuild from DetermineProjectsToBuild action
mazhelez Dec 4, 2023
17e5ec7
Exclude PSUseSingularNouns PS analyzer rule
mazhelez Dec 4, 2023
9b12439
Supress PSReviewUnusedParameter (false-positive)
mazhelez Dec 4, 2023
b1b6486
Use IsPartialBuild instead of IsFullBuild
mazhelez Dec 4, 2023
d64f668
Move logging statement
mazhelez Dec 4, 2023
091522e
Rename function to Get-IsPatialBuild
mazhelez Dec 4, 2023
22f8473
Bring back AL-Go-Helper.ps1
mazhelez Dec 4, 2023
a44ec75
Force array
mazhelez Dec 4, 2023
c2a5296
Fix module export
mazhelez Dec 4, 2023
ce07310
Hardcode api_url to https://api.github.com/repos/
mazhelez Dec 4, 2023
069ee12
🤦‍♀️
mazhelez Dec 4, 2023
0061581
Fix jobs URI
mazhelez Dec 4, 2023
9c21271
Refator logic for determining modified projects
mazhelez Dec 4, 2023
33bc5c4
Add more logs
mazhelez Dec 4, 2023
31788b3
Temp fix to fgirure out logging
mazhelez Dec 4, 2023
a1f6cba
Include base folder in modified files
mazhelez Dec 4, 2023
bb2926c
Add workflow created date
mazhelez Dec 4, 2023
0755d1b
Revert "Temp fix to fgirure out logging"
mazhelez Dec 4, 2023
79f16fe
Make modifiedFiles non-mandatory in Get-IsPatialBuild
mazhelez Dec 4, 2023
e1bacb6
Fix Get-IsPatialBuild
mazhelez Dec 4, 2023
1a7104d
Fix tests
mazhelez Dec 4, 2023
b8105ad
Propagat changes to App Source App template
mazhelez Dec 4, 2023
1d6aed7
Merge branch 'main' into fix-incremental-build
mazhelez Dec 4, 2023
068faae
Suppress false-positive warning
mazhelez Dec 4, 2023
1dbfabc
Merge branch 'fix-incremental-build' of https://github.com/mazhelez/A…
mazhelez Dec 4, 2023
b03b24f
Merge branch 'main' into fix-incremental-build
mazhelez Dec 5, 2023
f746267
Supress PSReviewUnusedParameter properly
mazhelez Dec 5, 2023
80001b3
Merge branch 'fix-incremental-build' of https://github.com/mazhelez/A…
mazhelez Dec 5, 2023
0ba00b8
Improve logging when successful CICD run is found
mazhelez Dec 8, 2023
036eef3
Update Actions/DetermineProjectsToBuild/DetermineProjectsToBuild.psm1
mazhelez Dec 8, 2023
be92504
Update Actions/DetermineProjectsToBuild/DetermineProjectsToBuild.psm1
mazhelez Dec 8, 2023
f8baae9
Use isPartialBuild as plain boolean value
mazhelez Dec 8, 2023
3be1cd2
Document baselineWorkflowRunId
mazhelez Dec 8, 2023
dcc1579
Merge branch 'fix-incremental-build' of https://github.com/mazhelez/A…
mazhelez Dec 8, 2023
f84528a
🤦‍♀️ It's YAML
mazhelez Dec 8, 2023
144e1c0
Add defensive check for empty string
mazhelez Dec 8, 2023
3b516ee
Merge branch 'main' into fix-incremental-build
freddydk Dec 8, 2023
881e8ef
Fix casing of Github-Helper.psm1
mazhelez Dec 8, 2023
7f5599b
Merge branch 'fix-incremental-build' of https://github.com/mazhelez/A…
mazhelez Dec 8, 2023
cf595a8
Make $token param mandatory
mazhelez Dec 8, 2023
f326eb4
Remove unnecessary ${{ }} in YAML
mazhelez Dec 9, 2023
19c0abb
Calculate full paths of modified files before calling ShouldBuildProject
mazhelez Dec 10, 2023
a643489
Re-org module imports
mazhelez Dec 10, 2023
b4f6e90
Restructure code to avoid unused parameter warnings
mazhelez Dec 11, 2023
d152851
Change IsPartialBuild output to BuildAllProject
mazhelez Dec 11, 2023
0c9eeca
🤦‍♀️
mazhelez Dec 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/powershell.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
with:
path: .\
recurse: true
excludeRule: '"PSAvoidUsingInvokeExpression", "PSUseShouldProcessForStateChangingFunctions", "PSAvoidUsingWriteHost", "PSAvoidUsingCmdletAliases"'
excludeRule: '"PSAvoidUsingInvokeExpression", "PSUseShouldProcessForStateChangingFunctions", "PSAvoidUsingWriteHost", "PSAvoidUsingCmdletAliases", "PSUseSingularNouns"'
output: results.sarif

# Upload the SARIF file generated in the previous step
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
Param(
[Parameter(Mandatory = $true)]
[string] $repository,
[Parameter(Mandatory = $true)]
[string] $branch,
[Parameter(Mandatory = $true)]
[string] $token
)

Import-Module (Join-Path $PSScriptRoot '..\Github-Helper.psm1' -Resolve)

<#
Checks if all build jobs in a workflow run completed successfully.
#>
function CheckBuildJobsInWorkflowRun {
Param(
[Parameter(Mandatory = $true)]
[string] $token,
[Parameter(Mandatory = $true)]
[string] $repository,
[Parameter(Mandatory = $true)]
[string] $workflowRunId
)

$headers = GetHeader -token $token
$per_page = 100
$page = 1

$allSuccessful = $true
$anySuccessful = $false

while($true) {
$jobsURI = "https://api.github.com/repos/$repository/actions/runs/$workflowRunId/jobs?per_page=$per_page&page=$page"
Write-Host "- $jobsURI"
$workflowJobs = InvokeWebRequest -Headers $headers -Uri $jobsURI | ConvertFrom-Json

if($workflowJobs.jobs.Count -eq 0) {
# No more jobs, breaking out of the loop
break
}

$buildJobs = @($workflowJobs.jobs | Where-Object { $_.name.StartsWith('Build ') })

if($buildJobs.conclusion -eq 'success') {
$anySuccessful = $true
}

if($buildJobs.conclusion -ne 'success') {
# If there is a build job that is not successful, there is not need to check further
$allSuccessful = $false
break
}

$page += 1
}

return ($allSuccessful -and $anySuccessful)
}

<#
Gets the last successful CICD run ID for the specified repository and branch.
Successful CICD runs are those that have a workflow run named ' CI/CD' and successfully built all the projects.

If no successful CICD run is found, 0 is returned.
#>
function FindLatestSuccessfulCICDRun {
Param(
[Parameter(Mandatory = $true)]
[string] $repository,
[Parameter(Mandatory = $true)]
[string] $branch,
[Parameter(Mandatory = $true)]
[string] $token
)

$headers = GetHeader -token $token
$lastSuccessfulCICDRun = 0
$per_page = 100
$page = 1

Write-Host "Finding latest successful CICD run for branch $branch in repository $repository"

# Get the latest CICD workflow run
while($true) {
$runsURI = "https://api.github.com/repos/$repository/actions/runs?per_page=$per_page&page=$page&exclude_pull_requests=true&status=completed&branch=$branch"
Write-Host "- $runsURI"
$workflowRuns = InvokeWebRequest -Headers $headers -Uri $runsURI | ConvertFrom-Json

if($workflowRuns.workflow_runs.Count -eq 0) {
# No more workflow runs, breaking out of the loop
break
}

$CICDRuns = @($workflowRuns.workflow_runs | Where-Object { $_.name -eq ' CI/CD' })

foreach($CICDRun in $CICDRuns) {
if($CICDRun.conclusion -eq 'success') {
# CICD run is successful
$lastSuccessfulCICDRun = $CICDRun.id
break
}

# CICD run is considered successful if all build jobs were successful
$areBuildJobsSuccessful = CheckBuildJobsInWorkflowRun -workflowRunId $($CICDRun.id) -token $token -repository $repository

if($areBuildJobsSuccessful) {
$lastSuccessfulCICDRun = $CICDRun.id
Write-Host "Found last successful CICD run: $($lastSuccessfulCICDRun), from $($CICDRun.created_at)"
break
}

Write-Host "CICD run $($CICDRun.id) is not successful. Skipping."
}

if($lastSuccessfulCICDRun -ne 0) {
break
}

$page += 1
}

if($lastSuccessfulCICDRun -ne 0) {
Write-Host "Last successful CICD run for branch $branch in repository $repository is $lastSuccessfulCICDRun"
} else {
Write-Host "No successful CICD run found for branch $branch in repository $repository"
}

return $lastSuccessfulCICDRun
}

$workflowRunID = FindLatestSuccessfulCICDRun -token $token -repository $repository -branch $branch

# Set output variables
Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "WorkflowRunID=$workflowRunID"
23 changes: 23 additions & 0 deletions Actions/DetermineBaselineWorkflowRun/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Determine Baseline Workflow Run
Finds the latest CICD workflow run that completed and built all the AL-Go projects successfully.
This workflow run is to be used as a baseline for all the build jobs in the current workflow run in case incremental build is required.

## INPUT

### ENV variables
none

### Parameters
| Name | Required | Description | Default value |
| :-- | :-: | :-- | :-- |
| shell | | The shell (powershell or pwsh) in which the PowerShell script in this action should run | powershell |

## OUTPUT

### ENV variables
none

### OUTPUT variables
| Name | Description |
| :-- | :-- |
| BaselineWorkflowRunId | The workflow run ID to use as a baseline. 0, if no baseline CICD was found.
33 changes: 33 additions & 0 deletions Actions/DetermineBaselineWorkflowRun/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Determine Baseline Workflow Run
author: Microsoft Corporation
inputs:
shell:
description: Shell in which you want to run the action (powershell or pwsh)
required: false
default: powershell
outputs:
BaselineWorkflowRunId:
description: The ID of the baseline workflow run
value: ${{ steps.determineBaselineWorkflowRun.outputs.WorkflowRunID }}
runs:
using: composite
steps:
- name: Determine Projects to Build
shell: ${{ inputs.shell }}
id: determineBaselineWorkflowRun
env:
_gitHubToken: ${{ github.token }}
_branch: ${{ github.base_ref }}
_repository: ${{ github.repository }}
run: |
$errorActionPreference = "Stop"; $ProgressPreference = "SilentlyContinue"; Set-StrictMode -Version 2.0
try {
${{ github.action_path }}/DetermineBaselineWorkflowRun.ps1 -branch $env:_branch -repository $env:_repository -token $env:_gitHubToken
}
catch {
Write-Host "::ERROR::Unexpected error when running action. Error Message: $($_.Exception.Message.Replace("`r",'').Replace("`n",' ')), StackTrace: $($_.ScriptStackTrace.Replace("`r",'').Replace("`n",' <- '))";
exit 1
}
branding:
icon: terminal
color: blue
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
Param(
[Parameter(HelpMessage = "The folder to scan for projects to build", Mandatory = $true)]
[string] $baseFolder,
[Parameter(HelpMessage = "An array of changed files paths, used to filter the projects to build", Mandatory = $false)]
[string[]] $modifiedFiles = @(),
[Parameter(HelpMessage = "The maximum depth to build the dependency tree", Mandatory = $false)]
[int] $maxBuildDepth = 0,

[Parameter(HelpMessage = "The GitHub token to use to fetch the modified files", Mandatory = $true)]
[string] $token,
[Parameter(HelpMessage = "Specifies the parent telemetry scope for the telemetry signal", Mandatory = $false)]
[string] $parentTelemetryScopeJson = '7b7d'
)
Expand All @@ -15,16 +14,28 @@ $telemetryScope = $null
try {
#region Action: Setup
. (Join-Path -Path $PSScriptRoot -ChildPath "..\AL-Go-Helper.ps1" -Resolve)

DownloadAndImportBcContainerHelper -baseFolder $baseFolder
Import-Module (Join-Path -Path $PSScriptRoot -ChildPath "..\TelemetryHelper.psm1" -Resolve) -DisableNameChecking
Import-Module (Join-Path -Path $PSScriptRoot -ChildPath "DetermineProjectsToBuild.psm1" -Resolve) -DisableNameChecking
#endregion

$telemetryScope = CreateScope -eventId 'DO0085' -parentTelemetryScopeJson $parentTelemetryScopeJson

#region Action: Determine projects to build
. (Join-Path -Path $PSScriptRoot -ChildPath "DetermineProjectsToBuild.ps1" -Resolve)
$allProjects, $projectsToBuild, $projectDependencies, $buildOrder = Get-ProjectsToBuild -baseFolder $baseFolder -modifiedFiles $modifiedFiles -maxBuildDepth $maxBuildDepth
Write-Host "::group::Get Modified Files"
$modifiedFiles = @(Get-ModifiedFiles -token $token)
Write-Host "$($modifiedFiles.Count) modified file(s): $($modifiedFiles -join ', ')"
Write-Host "::endgroup::"

Write-Host "::group::Determine Partial Build"
$buildAllProjects = Get-BuildAllProjects -modifiedFiles $modifiedFiles -baseFolder $baseFolder
Write-Host "::endgroup::"

Write-Host "::group::Get Projects To Build"
$allProjects, $projectsToBuild, $projectDependencies, $buildOrder = Get-ProjectsToBuild -baseFolder $baseFolder -buildAllProjects $buildAllProjects -modifiedFiles $modifiedFiles -maxBuildDepth $maxBuildDepth
AddTelemetryProperty -telemetryScope $telemetryScope -key "projects" -value "$($allProjects -join ', ')"
Write-Host "::endgroup::"
#endregion

#region Action: Output
Expand All @@ -36,10 +47,12 @@ try {
Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "ProjectsJson=$projectsJson"
Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "ProjectDependenciesJson=$projectDependenciesJson"
Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "BuildOrderJson=$buildOrderJson"
Add-Content -Encoding UTF8 -Path $env:GITHUB_OUTPUT -Value "BuildAllProjects=$([int] $buildAllProjects)"

mazhelez marked this conversation as resolved.
Show resolved Hide resolved
Write-Host "ProjectsJson=$projectsJson"
Write-Host "ProjectDependenciesJson=$projectDependenciesJson"
Write-Host "BuildOrderJson=$buildOrderJson"
Write-Host "BuildAllProjects=$buildAllProjects"
#endregion

TrackTrace -telemetryScope $telemetryScope
Expand Down
Loading
Loading