diff --git a/Actions/GetWorkflowMultiRunBranches/GetWorkflowMultiRunBranches.ps1 b/Actions/GetWorkflowMultiRunBranches/GetWorkflowMultiRunBranches.ps1 index 822daede31..1da9a963ca 100644 --- a/Actions/GetWorkflowMultiRunBranches/GetWorkflowMultiRunBranches.ps1 +++ b/Actions/GetWorkflowMultiRunBranches/GetWorkflowMultiRunBranches.ps1 @@ -1,4 +1,6 @@ param( + [Parameter(Mandatory = $false, HelpMessage = "The GitHub event name that triggered the workflow.")] + [string] $workflowEventName = $env:GITHUB_EVENT_NAME, [Parameter(Mandatory = $false, HelpMessage = "Comma-separated value of branch name patterns to include if they exist. If not specified, only the current branch is returned. Wildcards are supported.")] [string] $includeBranches ) @@ -6,7 +8,7 @@ $gitHubHelperPath = Join-Path $PSScriptRoot '../Github-Helper.psm1' -Resolve Import-Module $gitHubHelperPath -DisableNameChecking -switch ($env:GITHUB_EVENT_NAME) { +switch ($workflowEventName) { 'schedule' { Write-Host "Event is schedule: getting branches from settings" $settings = ConvertFrom-Json $env:Settings @@ -20,8 +22,8 @@ switch ($env:GITHUB_EVENT_NAME) { $branchPatterns = @() } } - 'workflow_dispatch' { - Write-Host "Event is workflow_dispatch: getting branches from input" + { $_ -in 'workflow_dispatch', 'workflow_call' } { + Write-Host "Event is $($_): getting branches from input" $branchPatterns = @($includeBranches.Split(',') | ForEach-Object { $_.Trim() }) } } diff --git a/Actions/GetWorkflowMultiRunBranches/README.md b/Actions/GetWorkflowMultiRunBranches/README.md index a253210c15..3ed5a4f32d 100644 --- a/Actions/GetWorkflowMultiRunBranches/README.md +++ b/Actions/GetWorkflowMultiRunBranches/README.md @@ -17,6 +17,7 @@ If the workflow is run on a schedule, the branches are determined based on the ` | Name | Required | Description | Default value | | :-- | :-: | :-- | :-- | | shell | false | The shell (powershell or pwsh) in which the PowerShell script in this action should run | powershell | +| workflowEventName | false | The GitHub event name that triggered the workflow. *(override for reusable workflows)* | github.event_name | | includeBranches | false | Comma-separated value of branch name patterns to include if they exist. If not specified, only the current branch is returned. Wildcards are supported. |''| ## OUTPUT diff --git a/Actions/GetWorkflowMultiRunBranches/action.yaml b/Actions/GetWorkflowMultiRunBranches/action.yaml index 75593060f6..3cee775851 100644 --- a/Actions/GetWorkflowMultiRunBranches/action.yaml +++ b/Actions/GetWorkflowMultiRunBranches/action.yaml @@ -5,6 +5,10 @@ inputs: description: Shell in which you want to run the action (powershell or pwsh) required: false default: powershell + workflowEventName: + description: The GitHub event name that triggered the workflow. + required: false + default: ${{ github.event_name }} includeBranches: description: Comma-separated value of branch name patterns to include if they exist. If not specified, only the current branch is returned. Wildcards are supported. required: false @@ -20,10 +24,11 @@ runs: shell: ${{ inputs.shell }} id: GetWorkflowMultiRunBranches env: + _workflowEventName: ${{ inputs.workflowEventName }} _includeBranches: ${{ inputs.includeBranches }} run: | ${{ github.action_path }}/../Invoke-AlGoAction.ps1 -ActionName "GetWorkflowMultiRunBranches" -Action { - ${{ github.action_path }}/GetWorkflowMultiRunBranches.ps1 -includeBranches $env:_includeBranches + ${{ github.action_path }}/GetWorkflowMultiRunBranches.ps1 -workflowEventName $env:_workflowEventName -includeBranches $env:_includeBranches } branding: icon: terminal diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 81b4228837..283a877c08 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -50,6 +50,7 @@ The new setting `postponeProjectInBuildOrder` allows you to delay long running j - Issue 2084 Multiple artifacts failure if you re-run failed jobs after flaky tests - Issue 2085 Projects that doesn't contain both Apps and TestApps are wrongly seen as not built. - Issue 2086 Postpone jobs, which doesn't have any dependents to the end of the build order. +- Rework input handling of workflow 'Update AL-Go System Files' for trigger 'workflow_call' ### New Settings diff --git a/Templates/AppSource App/.github/workflows/UpdateGitHubGoSystemFiles.yaml b/Templates/AppSource App/.github/workflows/UpdateGitHubGoSystemFiles.yaml index 204fa8810e..3f5504b7f0 100644 --- a/Templates/AppSource App/.github/workflows/UpdateGitHubGoSystemFiles.yaml +++ b/Templates/AppSource App/.github/workflows/UpdateGitHubGoSystemFiles.yaml @@ -21,6 +21,10 @@ on: default: '' workflow_call: inputs: + caller: + description: Name of the calling workflow (use github.workflow as value when calling) + type: string + required: true templateUrl: description: Template Repository URL (current is {TEMPLATEURL}) type: string @@ -50,6 +54,7 @@ defaults: shell: powershell env: + WorkflowEventName: ${{ inputs.caller && 'workflow_call' || github.event_name }} ALGoOrgSettings: ${{ vars.ALGoOrgSettings }} ALGoRepoSettings: ${{ vars.ALGoRepoSettings }} @@ -76,12 +81,13 @@ jobs: uses: microsoft/AL-Go-Actions/GetWorkflowMultiRunBranches@main with: shell: powershell - includeBranches: ${{ github.event.inputs.includeBranches }} + workflowEventName: ${{ env.WorkflowEventName }} + includeBranches: ${{ inputs.includeBranches }} - name: Determine Template URL id: DetermineTemplateUrl env: - TemplateUrlAsInput: '${{ github.event.inputs.templateUrl }}' + TemplateUrlAsInput: '${{ inputs.templateUrl }}' run: | $templateUrl = $env:templateUrl # Available from ReadSettings step if ($ENV:TemplateUrlAsInput) { @@ -133,12 +139,12 @@ jobs: - name: Calculate Commit Options env: - directCommit: '${{ github.event.inputs.directCommit }}' - downloadLatest: '${{ github.event.inputs.downloadLatest }}' + directCommit: '${{ inputs.directCommit }}' + downloadLatest: '${{ inputs.downloadLatest }}' run: | $errorActionPreference = "Stop"; $ProgressPreference = "SilentlyContinue"; Set-StrictMode -Version 2.0 - if('${{ github.event_name }}' -in 'workflow_dispatch', 'workflow_call') { - Write-Host "Using inputs from ${{ github.event_name }} event" + if($env:WorkflowEventName -in 'workflow_dispatch', 'workflow_call') { + Write-Host "Using inputs from $($env:WorkflowEventName) event" $directCommit = $env:directCommit $downloadLatest = $env:downloadLatest } diff --git a/Templates/Per Tenant Extension/.github/workflows/UpdateGitHubGoSystemFiles.yaml b/Templates/Per Tenant Extension/.github/workflows/UpdateGitHubGoSystemFiles.yaml index 204fa8810e..3f5504b7f0 100644 --- a/Templates/Per Tenant Extension/.github/workflows/UpdateGitHubGoSystemFiles.yaml +++ b/Templates/Per Tenant Extension/.github/workflows/UpdateGitHubGoSystemFiles.yaml @@ -21,6 +21,10 @@ on: default: '' workflow_call: inputs: + caller: + description: Name of the calling workflow (use github.workflow as value when calling) + type: string + required: true templateUrl: description: Template Repository URL (current is {TEMPLATEURL}) type: string @@ -50,6 +54,7 @@ defaults: shell: powershell env: + WorkflowEventName: ${{ inputs.caller && 'workflow_call' || github.event_name }} ALGoOrgSettings: ${{ vars.ALGoOrgSettings }} ALGoRepoSettings: ${{ vars.ALGoRepoSettings }} @@ -76,12 +81,13 @@ jobs: uses: microsoft/AL-Go-Actions/GetWorkflowMultiRunBranches@main with: shell: powershell - includeBranches: ${{ github.event.inputs.includeBranches }} + workflowEventName: ${{ env.WorkflowEventName }} + includeBranches: ${{ inputs.includeBranches }} - name: Determine Template URL id: DetermineTemplateUrl env: - TemplateUrlAsInput: '${{ github.event.inputs.templateUrl }}' + TemplateUrlAsInput: '${{ inputs.templateUrl }}' run: | $templateUrl = $env:templateUrl # Available from ReadSettings step if ($ENV:TemplateUrlAsInput) { @@ -133,12 +139,12 @@ jobs: - name: Calculate Commit Options env: - directCommit: '${{ github.event.inputs.directCommit }}' - downloadLatest: '${{ github.event.inputs.downloadLatest }}' + directCommit: '${{ inputs.directCommit }}' + downloadLatest: '${{ inputs.downloadLatest }}' run: | $errorActionPreference = "Stop"; $ProgressPreference = "SilentlyContinue"; Set-StrictMode -Version 2.0 - if('${{ github.event_name }}' -in 'workflow_dispatch', 'workflow_call') { - Write-Host "Using inputs from ${{ github.event_name }} event" + if($env:WorkflowEventName -in 'workflow_dispatch', 'workflow_call') { + Write-Host "Using inputs from $($env:WorkflowEventName) event" $directCommit = $env:directCommit $downloadLatest = $env:downloadLatest } diff --git a/Tests/DetermineProjectsToBuild.Test.ps1 b/Tests/DetermineProjectsToBuild.Test.ps1 index 0a9345a384..2d7ca5baf2 100644 --- a/Tests/DetermineProjectsToBuild.Test.ps1 +++ b/Tests/DetermineProjectsToBuild.Test.ps1 @@ -1044,7 +1044,7 @@ Describe "Get-ProjectsToBuild" { } It 'throws error when test project has buildable app folders' { - # TestProject has both projectsToTest setting AND an app folder — this should fail + # TestProject has both projectsToTest setting AND an app folder - this should fail $appFile = @{ id = '83fb8305-4079-415d-a25d-8132f0436fd1'; name = 'First App'; publisher = 'Contoso'; version = '1.0.0.0'; dependencies = @() } New-Item -Path "$baseFolder/Project1/.AL-Go/settings.json" -type File -Force @@ -1052,7 +1052,7 @@ Describe "Get-ProjectsToBuild" { New-Item -Path "$baseFolder/TestProject/.AL-Go/settings.json" -type File -Force @{ projectsToTest = @("Project1") } | ConvertTo-Json -Depth 99 -Compress | Out-File (Join-Path $baseFolder "TestProject/.AL-Go/settings.json") -Encoding UTF8 - # Add an app folder to the test project — this should be forbidden + # Add an app folder to the test project - this should be forbidden $testAppFile = @{ id = '83fb8305-4079-415d-a25d-8132f0436fd2'; name = 'Bad App'; publisher = 'Contoso'; version = '1.0.0.0'; dependencies = @() } New-Item -Path "$baseFolder/TestProject/app/app.json" -Value (ConvertTo-Json $testAppFile -Depth 10) -type File -Force @@ -1066,7 +1066,7 @@ Describe "Get-ProjectsToBuild" { } It 'throws error when test project has buildable test folders' { - # TestProject has both projectsToTest setting AND a test folder — this should fail + # TestProject has both projectsToTest setting AND a test folder - this should fail $appFile = @{ id = '83fb8305-4079-415d-a25d-8132f0436fd1'; name = 'First App'; publisher = 'Contoso'; version = '1.0.0.0'; dependencies = @() } New-Item -Path "$baseFolder/Project1/.AL-Go/settings.json" -type File -Force @@ -1089,7 +1089,7 @@ Describe "Get-ProjectsToBuild" { It 'throws error when one test project depends on another test project' { # Project1 is a normal project, TestProject1 and TestProject2 are both test projects - # TestProject2 tries to depend on TestProject1 — this should fail + # TestProject2 tries to depend on TestProject1 - this should fail Mock OutputError {} -ModuleName DetermineProjectsToBuild $appFile = @{ id = '83fb8305-4079-415d-a25d-8132f0436fd1'; name = 'First App'; publisher = 'Contoso'; version = '1.0.0.0'; dependencies = @() } diff --git a/Tests/GetWorkflowMultiRunBranches.Test.ps1 b/Tests/GetWorkflowMultiRunBranches.Test.ps1 index 0059df4d0d..9f44e7fff3 100644 --- a/Tests/GetWorkflowMultiRunBranches.Test.ps1 +++ b/Tests/GetWorkflowMultiRunBranches.Test.ps1 @@ -39,6 +39,9 @@ Describe "GetWorkflowMultiRunBranches Action" { $env:Settings = "" $env:GITHUB_REF_NAME = "main" + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'fetch' } -MockWith { } + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'for-each-ref'} -MockWith { return @("origin/main") } + # Call the action script . (Join-Path $scriptRoot "$actionName.ps1") @@ -52,6 +55,7 @@ Describe "GetWorkflowMultiRunBranches Action" { $env:Settings = "" $env:GITHUB_REF_NAME = "main" + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'fetch' } -MockWith { } Mock -CommandName invoke-git -ParameterFilter { $command -eq 'for-each-ref'} -MockWith { return @("origin/test-branch", "origin/main", "origin/some-other-branch", "origin") } # Call the action script @@ -67,6 +71,7 @@ Describe "GetWorkflowMultiRunBranches Action" { $env:Settings = "" $env:GITHUB_REF_NAME = "main" + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'fetch' } -MockWith { } Mock -CommandName invoke-git -ParameterFilter { $command -eq 'for-each-ref'} -MockWith { return @("origin/test-branch", "origin/main", "origin/some-other-branch", "origin") } # Call the action script @@ -82,6 +87,7 @@ Describe "GetWorkflowMultiRunBranches Action" { $env:Settings = "" $env:GITHUB_REF_NAME = "main" + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'fetch' } -MockWith { } Mock -CommandName invoke-git -ParameterFilter { $command -eq 'for-each-ref'} -MockWith { return @("origin/HEAD", "origin/main", "origin/develop", "origin/feature-1") } # Call the action script with wildcard to get all branches @@ -101,6 +107,7 @@ Describe "GetWorkflowMultiRunBranches Action" { $env:Settings = "{ 'workflowSchedule': { 'includeBranches': [] } }" $env:GITHUB_REF_NAME = "default-branch" + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'fetch' } -MockWith { } Mock -CommandName invoke-git -ParameterFilter { $command -eq 'for-each-ref'} -MockWith { return @("origin/test-branch", "origin/main", "origin/default-branch", "origin") } # Call the action script @@ -116,6 +123,7 @@ Describe "GetWorkflowMultiRunBranches Action" { $env:Settings = "{ 'workflowSchedule': { 'includeBranches': ['test-branch'] } }" $env:GITHUB_REF_NAME = "main" + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'fetch' } -MockWith { } Mock -CommandName invoke-git -ParameterFilter { $command -eq 'for-each-ref'} -MockWith { return @("origin/test-branch", "origin/main", "origin/some-other-branch", "origin") } # Call the action script @@ -131,6 +139,7 @@ Describe "GetWorkflowMultiRunBranches Action" { $env:Settings = "{ 'workflowSchedule': { 'includeBranches': ['*branch*'] } }" $env:GITHUB_REF_NAME = "main" + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'fetch' } -MockWith { } Mock -CommandName invoke-git -ParameterFilter { $command -eq 'for-each-ref'} -MockWith { return @("origin/test-branch", "origin/main", "origin/some-other-branch", "origin") } # Call the action script @@ -141,4 +150,89 @@ Describe "GetWorkflowMultiRunBranches Action" { $outputValue | Should -Be "{`"branches`":[`"test-branch`",`"some-other-branch`"]}" } } + + Context 'workflow_call event' { + It 'Action sets the current branch as result when no branch patterns are specified' { + $env:GITHUB_EVENT_NAME = "workflow_call" + $env:Settings = "" + $env:GITHUB_REF_NAME = "main" + + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'fetch' } -MockWith { } + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'for-each-ref'} -MockWith { return @("origin/main") } + + # Call the action script + . (Join-Path $scriptRoot "$actionName.ps1") + + $outputName, $outputValue = (Get-Content $env:GITHUB_OUTPUT) -split '=' + $outputName | Should -Be "Result" + $outputValue | Should -Be "{`"branches`":[`"main`"]}" + } + + It 'Action sets the input branch as result when a branch pattern is specified' { + $env:GITHUB_EVENT_NAME = "workflow_call" + $env:Settings = "" + $env:GITHUB_REF_NAME = "main" + + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'fetch' } -MockWith { } + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'for-each-ref'} -MockWith { return @("origin/test-branch", "origin/main", "origin/some-other-branch", "origin") } + + # Call the action script + . (Join-Path $scriptRoot "$actionName.ps1") -includeBranches "test-branch" + + $outputName, $outputValue = (Get-Content $env:GITHUB_OUTPUT) -split '=' + $outputName | Should -Be "Result" + $outputValue | Should -Be "{`"branches`":[`"test-branch`"]}" + } + + It 'Action sets the input branch as result when a branch pattern with wild card is specified' { + $env:GITHUB_EVENT_NAME = "workflow_call" + $env:Settings = "" + $env:GITHUB_REF_NAME = "main" + + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'fetch' } -MockWith { } + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'for-each-ref'} -MockWith { return @("origin/test-branch", "origin/main", "origin/some-other-branch", "origin") } + + # Call the action script + . (Join-Path $scriptRoot "$actionName.ps1") -includeBranches "*branch*" + + $outputName, $outputValue = (Get-Content $env:GITHUB_OUTPUT) -split '=' + $outputName | Should -Be "Result" + $outputValue | Should -Be "{`"branches`":[`"test-branch`",`"some-other-branch`"]}" + } + + It 'Action filters out HEAD symbolic reference when using wildcard' { + $env:GITHUB_EVENT_NAME = "workflow_call" + $env:Settings = "" + $env:GITHUB_REF_NAME = "main" + + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'fetch' } -MockWith { } + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'for-each-ref'} -MockWith { return @("origin/HEAD", "origin/main", "origin/develop", "origin/feature-1") } + + # Call the action script with wildcard to get all branches + . (Join-Path $scriptRoot "$actionName.ps1") -includeBranches "*" + + $outputName, $outputValue = (Get-Content $env:GITHUB_OUTPUT) -split '=' + $outputName | Should -Be "Result" + # Verify that HEAD is not included in the result + $outputValue | Should -Not -Match "HEAD" + $outputValue | Should -Be "{`"branches`":[`"main`",`"develop`",`"feature-1`"]}" + } + } + + Context 'Parameter override tests' { + It 'workflowEventName parameter overrides GITHUB_EVENT_NAME environment variable' { + $env:GITHUB_EVENT_NAME = "schedule" + $env:Settings = "{ 'workflowSchedule': { 'includeBranches': ['schedule-branch'] } }" + $env:GITHUB_REF_NAME = "main" + + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'fetch' } -MockWith { } + Mock -CommandName invoke-git -ParameterFilter { $command -eq 'for-each-ref'} -MockWith { return @("origin/call-branch", "origin/schedule-branch", "origin/main") } + + # Parameter should override environment variable + . (Join-Path $scriptRoot "$actionName.ps1") -workflowEventName "workflow_call" -includeBranches "call-branch" + + $outputName, $outputValue = (Get-Content $env:GITHUB_OUTPUT) -split '=' + $outputValue | Should -Be "{`"branches`":[`"call-branch`"]}" + } + } }