diff --git a/.github/RELEASENOTES.copy.md b/.github/RELEASENOTES.copy.md index a52c727265..85cee58531 100644 --- a/.github/RELEASENOTES.copy.md +++ b/.github/RELEASENOTES.copy.md @@ -6,6 +6,9 @@ Note that when using the preview version of AL-Go for GitHub, you need to Update Issue 542 Deploy Workflow fails +### New Settings +- `keyVaultCodesignCertificateName`: With this setting you can delegate the codesigning to an Azure Key Vault. This can be useful if your certificate has to be stored in a Hardware Security Module + ## v3.1 ### Issues @@ -34,6 +37,11 @@ All these actions now uses the selected branch in the **Run workflow** dialog as - `UseCompilerFolder`: Setting useCompilerFolder to true causes your pipelines to use containerless compiling. Unless you also set `doNotPublishApps` to true, setting useCompilerFolder to true won't give you any performance advantage, since AL-Go for GitHub will still need to create a container in order to publish and test the apps. In the future, publishing and testing will be split from building and there will be other options for getting an instance of Business Central for publishing and testing. - `vsixFile`: vsixFile should be a direct download URL to the version of the AL Language extension you want to use for building the project or repo. By default, AL-Go will use the AL Language extension that comes with the Business Central Artifacts. +### New Workflows + +- **_BuildALGoProject** is a reusable workflow that unites the steps for building an AL-Go projects. It has been reused in the following workflows: _CI/CD_, _Pull Request Build_, _NextMinor_, _NextMajor_ and _Current_. +The workflow appears under the _Actions_ tab in GitHub, but it is not actionable in any way. + ### New Actions - **DetermineArtifactUrl** is used to determine which artifacts to use for building a project in CI/CD, PullRequestHandler, Current, NextMinor and NextMajor workflows. diff --git a/.github/workflows/CICD.yaml b/.github/workflows/CICD.yaml index c1797fca22..98ad9d4f4a 100644 --- a/.github/workflows/CICD.yaml +++ b/.github/workflows/CICD.yaml @@ -38,6 +38,7 @@ jobs: projects: ${{ steps.determineProjectsToBuild.outputs.ProjectsJson }} projectDependenciesJson: ${{ steps.determineProjectsToBuild.outputs.ProjectDependenciesJson }} buildOrderJson: ${{ steps.determineProjectsToBuild.outputs.BuildOrderJson }} + workflowDepth: ${{ steps.DetermineWorkflowDepth.outputs.WorkflowDepth }} steps: - name: Checkout uses: actions/checkout@v3 @@ -58,6 +59,11 @@ jobs: shell: powershell parentTelemetryScopeJson: ${{ steps.init.outputs.telemetryScopeJson }} getEnvironments: '*' + + - name: Determine Workflow Depth + id: DetermineWorkflowDepth + run: | + Add-Content -Path $env:GITHUB_OUTPUT -Value "WorkflowDepth=$($env:workflowDepth)" - name: Determine Projects To Build id: determineProjectsToBuild @@ -171,362 +177,48 @@ jobs: Build1: needs: [ Initialization ] if: (!failure()) && (!cancelled()) && fromJson(needs.Initialization.outputs.buildOrderJson)[0].projectsCount > 0 - runs-on: ${{ fromJson(needs.Initialization.outputs.githubRunner) }} - defaults: - run: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} strategy: matrix: include: ${{ fromJson(needs.Initialization.outputs.buildOrderJson)[0].buildDimensions }} fail-fast: false name: Build ${{ matrix.project }} - ${{ matrix.buildMode }} - outputs: - AppsArtifactsName: ${{ steps.calculateArtifactNames.outputs.AppsArtifactsName }} - TestAppsArtifactsName: ${{ steps.calculateArtifactNames.outputs.TestAppsArtifactsName }} - TestResultsArtifactsName: ${{ steps.calculateArtifactNames.outputs.TestResultsArtifactsName }} - BcptTestResultsArtifactsName: ${{ steps.calculateArtifactNames.outputs.BcptTestResultsArtifactsName }} - BuildOutputArtifactsName: ${{ steps.calculateArtifactNames.outputs.BuildOutputArtifactsName }} - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - lfs: true - - - name: Download thisbuild artifacts - if: env.workflowDepth > 1 - uses: actions/download-artifact@v3 - with: - path: '.dependencies' - - - name: Read settings - uses: microsoft/AL-Go-Actions/ReadSettings@preview - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - project: ${{ matrix.project }} - - - name: Read secrets - uses: microsoft/AL-Go-Actions/ReadSecrets@preview - env: - secrets: ${{ toJson(secrets) }} - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - settingsJson: ${{ env.Settings }} - secrets: 'licenseFileUrl,insiderSasToken,codeSignCertificateUrl,codeSignCertificatePassword,keyVaultCertificateUrl,keyVaultCertificatePassword,keyVaultClientId,storageContext,gitHubPackagesContext' - - - name: Determine ArtifactUrl - uses: microsoft/AL-Go-Actions/DetermineArtifactUrl@preview - id: determineArtifactUrl - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - project: ${{ matrix.project }} - settingsJson: ${{ env.Settings }} - secretsJson: ${{ env.RepoSecrets }} - - - name: Cache Business Central Artifacts - if: env.useCompilerFolder == 'True' && steps.determineArtifactUrl.outputs.ArtifactUrl && !contains(env.artifact,'INSIDERSASTOKEN') - uses: actions/cache@v3 - with: - path: .artifactcache - key: ${{ steps.determineArtifactUrl.outputs.ArtifactUrl }} - - - name: Run pipeline - id: RunPipeline - uses: microsoft/AL-Go-Actions/RunPipeline@preview - env: - BuildMode: ${{ matrix.buildMode }} - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - project: ${{ matrix.project }} - projectDependenciesJson: ${{ needs.Initialization.outputs.projectDependenciesJson }} - settingsJson: ${{ env.Settings }} - secretsJson: ${{ env.RepoSecrets }} - buildMode: ${{ matrix.buildMode }} - - - name: Calculate Artifact names - id: calculateArtifactsNames - uses: microsoft/AL-Go-Actions/CalculateArtifactNames@preview - if: success() || failure() - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - settingsJson: ${{ env.Settings }} - project: ${{ matrix.project }} - buildMode: ${{ matrix.buildMode }} - branchName: ${{ github.ref_name }} - - - name: Upload thisbuild artifacts - apps - if: env.workflowDepth > 1 - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.calculateArtifactsNames.outputs.ThisBuildAppsArtifactsName }} - path: '${{ matrix.project }}/.buildartifacts/Apps/' - if-no-files-found: ignore - retention-days: 1 - - - name: Upload thisbuild artifacts - test apps - if: env.workflowDepth > 1 - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.calculateArtifactsNames.outputs.ThisBuildTestAppsArtifactsName }} - path: '${{ matrix.project }}/.buildartifacts/TestApps/' - if-no-files-found: ignore - retention-days: 1 - - - name: Publish artifacts - apps - uses: actions/upload-artifact@v3 - if: github.ref_name == 'main' || startswith(github.ref_name, 'release/') || needs.Initialization.outputs.deliveryTargetCount > 0 || needs.Initialization.outputs.environmentCount > 0 - with: - name: ${{ env.AppsArtifactsName }} - path: '${{ matrix.project }}/.buildartifacts/Apps/' - if-no-files-found: ignore - - - name: Publish artifacts - dependencies - uses: actions/upload-artifact@v3 - if: github.ref_name == 'main' || startswith(github.ref_name, 'release/') || needs.Initialization.outputs.deliveryTargetCount > 0 || needs.Initialization.outputs.environmentCount > 0 - with: - name: ${{ env.DependenciesArtifactsName }} - path: '${{ matrix.project }}/.buildartifacts/Dependencies/' - if-no-files-found: ignore - - - name: Publish artifacts - test apps - uses: actions/upload-artifact@v3 - if: github.ref_name == 'main' || startswith(github.ref_name, 'release/') || needs.Initialization.outputs.deliveryTargetCount > 0 || needs.Initialization.outputs.environmentCount > 0 - with: - name: ${{ env.TestAppsArtifactsName }} - path: '${{ matrix.project }}/.buildartifacts/TestApps/' - if-no-files-found: ignore - - - name: Publish artifacts - build output - uses: actions/upload-artifact@v3 - if: (success() || failure()) && (hashFiles(format('{0}/BuildOutput.txt',matrix.project)) != '') - with: - name: ${{ env.BuildOutputArtifactsName }} - path: '${{ matrix.project }}/BuildOutput.txt' - if-no-files-found: ignore - - - name: Publish artifacts - container event log - uses: actions/upload-artifact@v3 - if: (failure()) && (hashFiles(format('{0}/ContainerEventLog.evtx',matrix.project)) != '') - with: - name: ${{ env.ContainerEventLogArtifactsName }} - path: '${{ matrix.project }}/ContainerEventLog.evtx' - if-no-files-found: ignore - - - name: Publish artifacts - test results - uses: actions/upload-artifact@v3 - if: (success() || failure()) && (hashFiles(format('{0}/TestResults.xml',matrix.project)) != '') - with: - name: ${{ env.TestResultsArtifactsName }} - path: '${{ matrix.project }}/TestResults.xml' - if-no-files-found: ignore - - - name: Publish artifacts - bcpt test results - uses: actions/upload-artifact@v3 - if: (success() || failure()) && (hashFiles(format('{0}/bcptTestResults.json',matrix.project)) != '') - with: - name: ${{ env.BcptTestResultsArtifactsName }} - path: '${{ matrix.project }}/bcptTestResults.json' - if-no-files-found: ignore - - - name: Analyze Test Results - id: analyzeTestResults - if: success() || failure() - uses: microsoft/AL-Go-Actions/AnalyzeTests@preview - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - Project: ${{ matrix.project }} - - - name: Cleanup - if: always() - uses: microsoft/AL-Go-Actions/PipelineCleanup@preview - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - Project: ${{ matrix.project }} + uses: ./.github/workflows/_BuildALGoProject.yaml + secrets: inherit + with: + shell: ${{ needs.Initialization.outputs.githubRunnerShell }} + runsOn: ${{ needs.Initialization.outputs.githubRunner }} + parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} + project: ${{ matrix.project }} + buildMode: ${{ matrix.buildMode }} + projectDependenciesJson: ${{ needs.Initialization.outputs.projectDependenciesJson }} + secrets: 'licenseFileUrl,insiderSasToken,codeSignCertificateUrl,codeSignCertificatePassword,keyVaultCertificateUrl,keyVaultCertificatePassword,keyVaultClientId,storageContext,gitHubPackagesContext' + publishThisBuildArtifacts: ${{ needs.Initialization.outputs.workflowDepth > 1 }} + publishArtifacts: ${{ github.ref_name == 'main' || startswith(github.ref_name, 'release/') || needs.Initialization.outputs.deliveryTargetCount > 0 || needs.Initialization.outputs.environmentCount > 0 }} + signArtifacts: true + useArtifactCache: true Build: needs: [ Initialization, Build1 ] if: (!failure()) && (!cancelled()) && (needs.Build1.result == 'success' || needs.Build1.result == 'skipped') && fromJson(needs.Initialization.outputs.buildOrderJson)[1].projectsCount > 0 - runs-on: ${{ fromJson(needs.Initialization.outputs.githubRunner) }} - defaults: - run: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} strategy: matrix: include: ${{ fromJson(needs.Initialization.outputs.buildOrderJson)[1].buildDimensions }} fail-fast: false name: Build ${{ matrix.project }} - ${{ matrix.buildMode }} - outputs: - AppsArtifactsName: ${{ steps.calculateArtifactNames.outputs.AppsArtifactsName }} - TestAppsArtifactsName: ${{ steps.calculateArtifactNames.outputs.TestAppsArtifactsName }} - TestResultsArtifactsName: ${{ steps.calculateArtifactNames.outputs.TestResultsArtifactsName }} - BcptTestResultsArtifactsName: ${{ steps.calculateArtifactNames.outputs.BcptTestResultsArtifactsName }} - BuildOutputArtifactsName: ${{ steps.calculateArtifactNames.outputs.BuildOutputArtifactsName }} - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - lfs: true - - - name: Download thisbuild artifacts - if: env.workflowDepth > 1 - uses: actions/download-artifact@v3 - with: - path: '.dependencies' - - - name: Read settings - uses: microsoft/AL-Go-Actions/ReadSettings@preview - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - project: ${{ matrix.project }} - - - name: Read secrets - uses: microsoft/AL-Go-Actions/ReadSecrets@preview - env: - secrets: ${{ toJson(secrets) }} - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - settingsJson: ${{ env.Settings }} - secrets: 'licenseFileUrl,insiderSasToken,codeSignCertificateUrl,codeSignCertificatePassword,keyVaultCertificateUrl,keyVaultCertificatePassword,keyVaultClientId,storageContext,gitHubPackagesContext' - - - name: Determine ArtifactUrl - uses: microsoft/AL-Go-Actions/DetermineArtifactUrl@preview - id: determineArtifactUrl - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - project: ${{ matrix.project }} - settingsJson: ${{ env.Settings }} - secretsJson: ${{ env.RepoSecrets }} - - - name: Cache Business Central Artifacts - if: env.useCompilerFolder == 'True' && steps.determineArtifactUrl.outputs.ArtifactUrl && !contains(env.artifact,'INSIDERSASTOKEN') - uses: actions/cache@v3 - with: - path: .artifactcache - key: ${{ steps.determineArtifactUrl.outputs.ArtifactUrl }} - - - name: Run pipeline - id: RunPipeline - uses: microsoft/AL-Go-Actions/RunPipeline@preview - env: - BuildMode: ${{ matrix.buildMode }} - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - project: ${{ matrix.project }} - projectDependenciesJson: ${{ needs.Initialization.outputs.projectDependenciesJson }} - settingsJson: ${{ env.Settings }} - secretsJson: ${{ env.RepoSecrets }} - buildMode: ${{ matrix.buildMode }} - - - name: Calculate Artifact names - id: calculateArtifactsNames - uses: microsoft/AL-Go-Actions/CalculateArtifactNames@preview - if: success() || failure() - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - settingsJson: ${{ env.Settings }} - project: ${{ matrix.project }} - buildMode: ${{ matrix.buildMode }} - branchName: ${{ github.ref_name }} - - - name: Upload thisbuild artifacts - apps - if: env.workflowDepth > 1 - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.calculateArtifactsNames.outputs.ThisBuildAppsArtifactsName }} - path: '${{ matrix.project }}/.buildartifacts/Apps/' - if-no-files-found: ignore - retention-days: 1 - - - name: Upload thisbuild artifacts - test apps - if: env.workflowDepth > 1 - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.calculateArtifactsNames.outputs.ThisBuildTestAppsArtifactsName }} - path: '${{ matrix.project }}/.buildartifacts/TestApps/' - if-no-files-found: ignore - retention-days: 1 - - - name: Publish artifacts - apps - uses: actions/upload-artifact@v3 - if: github.ref_name == 'main' || startswith(github.ref_name, 'release/') || needs.Initialization.outputs.deliveryTargetCount > 0 || needs.Initialization.outputs.environmentCount > 0 - with: - name: ${{ env.AppsArtifactsName }} - path: '${{ matrix.project }}/.buildartifacts/Apps/' - if-no-files-found: ignore - - - name: Publish artifacts - dependencies - uses: actions/upload-artifact@v3 - if: github.ref_name == 'main' || startswith(github.ref_name, 'release/') || needs.Initialization.outputs.deliveryTargetCount > 0 || needs.Initialization.outputs.environmentCount > 0 - with: - name: ${{ env.DependenciesArtifactsName }} - path: '${{ matrix.project }}/.buildartifacts/Dependencies/' - if-no-files-found: ignore - - - name: Publish artifacts - test apps - uses: actions/upload-artifact@v3 - if: github.ref_name == 'main' || startswith(github.ref_name, 'release/') || needs.Initialization.outputs.deliveryTargetCount > 0 || needs.Initialization.outputs.environmentCount > 0 - with: - name: ${{ env.TestAppsArtifactsName }} - path: '${{ matrix.project }}/.buildartifacts/TestApps/' - if-no-files-found: ignore - - - name: Publish artifacts - build output - uses: actions/upload-artifact@v3 - if: (success() || failure()) && (hashFiles(format('{0}/BuildOutput.txt',matrix.project)) != '') - with: - name: ${{ env.BuildOutputArtifactsName }} - path: '${{ matrix.project }}/BuildOutput.txt' - if-no-files-found: ignore - - - name: Publish artifacts - container event log - uses: actions/upload-artifact@v3 - if: (failure()) && (hashFiles(format('{0}/ContainerEventLog.evtx',matrix.project)) != '') - with: - name: ${{ env.ContainerEventLogArtifactsName }} - path: '${{ matrix.project }}/ContainerEventLog.evtx' - if-no-files-found: ignore - - - name: Publish artifacts - test results - uses: actions/upload-artifact@v3 - if: (success() || failure()) && (hashFiles(format('{0}/TestResults.xml',matrix.project)) != '') - with: - name: ${{ env.TestResultsArtifactsName }} - path: '${{ matrix.project }}/TestResults.xml' - if-no-files-found: ignore - - - name: Publish artifacts - bcpt test results - uses: actions/upload-artifact@v3 - if: (success() || failure()) && (hashFiles(format('{0}/bcptTestResults.json',matrix.project)) != '') - with: - name: ${{ env.BcptTestResultsArtifactsName }} - path: '${{ matrix.project }}/bcptTestResults.json' - if-no-files-found: ignore - - - name: Analyze Test Results - id: analyzeTestResults - if: success() || failure() - uses: microsoft/AL-Go-Actions/AnalyzeTests@preview - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - Project: ${{ matrix.project }} - - - name: Cleanup - if: always() - uses: microsoft/AL-Go-Actions/PipelineCleanup@preview - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - Project: ${{ matrix.project }} + uses: ./.github/workflows/_BuildALGoProject.yaml + secrets: inherit + with: + shell: ${{ needs.Initialization.outputs.githubRunnerShell }} + runsOn: ${{ needs.Initialization.outputs.githubRunner }} + parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} + project: ${{ matrix.project }} + buildMode: ${{ matrix.buildMode }} + projectDependenciesJson: ${{ needs.Initialization.outputs.projectDependenciesJson }} + secrets: 'licenseFileUrl,insiderSasToken,codeSignCertificateUrl,codeSignCertificatePassword,keyVaultCertificateUrl,keyVaultCertificatePassword,keyVaultClientId,storageContext,gitHubPackagesContext' + publishThisBuildArtifacts: ${{ needs.Initialization.outputs.workflowDepth > 1 }} + publishArtifacts: ${{ github.ref_name == 'main' || startswith(github.ref_name, 'release/') || needs.Initialization.outputs.deliveryTargetCount > 0 || needs.Initialization.outputs.environmentCount > 0 }} + signArtifacts: true + useArtifactCache: true Deploy: needs: [ Initialization, Build ] diff --git a/.github/workflows/PullRequestHandler.yaml b/.github/workflows/PullRequestHandler.yaml index be08501356..915f742afe 100644 --- a/.github/workflows/PullRequestHandler.yaml +++ b/.github/workflows/PullRequestHandler.yaml @@ -52,6 +52,7 @@ jobs: projects: ${{ steps.determineProjectsToBuild.outputs.ProjectsJson }} projectDependenciesJson: ${{ steps.determineProjectsToBuild.outputs.ProjectDependenciesJson }} buildOrderJson: ${{ steps.determineProjectsToBuild.outputs.BuildOrderJson }} + workflowDepth: ${{ steps.DetermineWorkflowDepth.outputs.WorkflowDepth }} steps: - name: Checkout uses: actions/checkout@v3 @@ -73,6 +74,11 @@ jobs: shell: powershell parentTelemetryScopeJson: ${{ steps.init.outputs.telemetryScopeJson }} getEnvironments: '*' + + - name: Determine Workflow Depth + id: DetermineWorkflowDepth + run: | + Add-Content -Path $env:GITHUB_OUTPUT -Value "WorkflowDepth=$($env:workflowDepth)" - name: Determine Projects To Build id: determineProjectsToBuild @@ -84,316 +90,44 @@ jobs: Build1: needs: [ Initialization ] if: (!failure()) && (!cancelled()) && fromJson(needs.Initialization.outputs.buildOrderJson)[0].projectsCount > 0 - runs-on: ${{ fromJson(needs.Initialization.outputs.githubRunner) }} - defaults: - run: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} strategy: matrix: include: ${{ fromJson(needs.Initialization.outputs.buildOrderJson)[0].buildDimensions }} fail-fast: false name: Build ${{ matrix.project }} - ${{ matrix.buildMode }} - outputs: - AppsArtifactsName: ${{ steps.calculateArtifactNames.outputs.AppsArtifactsName }} - TestAppsArtifactsName: ${{ steps.calculateArtifactNames.outputs.TestAppsArtifactsName }} - TestResultsArtifactsName: ${{ steps.calculateArtifactNames.outputs.TestResultsArtifactsName }} - BcptTestResultsArtifactsName: ${{ steps.calculateArtifactNames.outputs.BcptTestResultsArtifactsName }} - BuildOutputArtifactsName: ${{ steps.calculateArtifactNames.outputs.BuildOutputArtifactsName }} - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - lfs: true - ref: refs/pull/${{ github.event.number }}/merge - - - name: Download thisbuild artifacts - if: env.workflowDepth > 1 - uses: actions/download-artifact@v3 - with: - path: '.dependencies' - - - name: Read settings - uses: microsoft/AL-Go-Actions/ReadSettings@preview - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - project: ${{ matrix.project }} - - - name: Read secrets - uses: microsoft/AL-Go-Actions/ReadSecrets@preview - env: - secrets: ${{ toJson(secrets) }} - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - settingsJson: ${{ env.Settings }} - secrets: 'licenseFileUrl,insiderSasToken,keyVaultCertificateUrl,keyVaultCertificatePassword,keyVaultClientId,gitHubPackagesContext' - - - name: Determine ArtifactUrl - uses: microsoft/AL-Go-Actions/DetermineArtifactUrl@preview - id: determineArtifactUrl - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - project: ${{ matrix.project }} - settingsJson: ${{ env.Settings }} - secretsJson: ${{ env.RepoSecrets }} - - - name: Cache Business Central Artifacts - if: env.useCompilerFolder == 'True' && steps.determineArtifactUrl.outputs.ArtifactUrl && !contains(env.artifact,'INSIDERSASTOKEN') - uses: actions/cache@v3 - with: - path: .artifactcache - key: ${{ steps.determineArtifactUrl.outputs.ArtifactUrl }} - - - name: Run pipeline - id: RunPipeline - uses: microsoft/AL-Go-Actions/RunPipeline@preview - env: - BuildMode: ${{ matrix.buildMode }} - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - project: ${{ matrix.project }} - projectDependenciesJson: ${{ needs.Initialization.outputs.projectDependenciesJson }} - settingsJson: ${{ env.Settings }} - secretsJson: ${{ env.RepoSecrets }} - buildMode: ${{ matrix.buildMode }} - - - name: Calculate Artifact names - id: calculateArtifactsNames - uses: microsoft/AL-Go-Actions/CalculateArtifactNames@preview - if: success() || failure() - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - settingsJson: ${{ env.Settings }} - project: ${{ matrix.project }} - buildMode: ${{ matrix.buildMode }} - branchName: ${{ github.ref_name }} - - - name: Upload thisbuild artifacts - apps - if: env.workflowDepth > 1 - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.calculateArtifactsNames.outputs.ThisBuildAppsArtifactsName }} - path: '${{ matrix.project }}/.buildartifacts/Apps/' - if-no-files-found: ignore - retention-days: 1 - - - name: Upload thisbuild artifacts - test apps - if: env.workflowDepth > 1 - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.calculateArtifactsNames.outputs.ThisBuildTestAppsArtifactsName }} - path: '${{ matrix.project }}/.buildartifacts/TestApps/' - if-no-files-found: ignore - retention-days: 1 - - - name: Publish artifacts - build output - uses: actions/upload-artifact@v3 - if: (success() || failure()) && (hashFiles(format('{0}/BuildOutput.txt',matrix.project)) != '') - with: - name: ${{ env.BuildOutputArtifactsName }} - path: '${{ matrix.project }}/BuildOutput.txt' - if-no-files-found: ignore - - - name: Publish artifacts - container event log - uses: actions/upload-artifact@v3 - if: (failure()) && (hashFiles(format('{0}/ContainerEventLog.evtx',matrix.project)) != '') - with: - name: ${{ env.ContainerEventLogArtifactsName }} - path: '${{ matrix.project }}/ContainerEventLog.evtx' - if-no-files-found: ignore - - - name: Publish artifacts - test results - uses: actions/upload-artifact@v3 - if: (success() || failure()) && (hashFiles(format('{0}/TestResults.xml',matrix.project)) != '') - with: - name: ${{ env.TestResultsArtifactsName }} - path: '${{ matrix.project }}/TestResults.xml' - if-no-files-found: ignore - - - name: Publish artifacts - bcpt test results - uses: actions/upload-artifact@v3 - if: (success() || failure()) && (hashFiles(format('{0}/bcptTestResults.json',matrix.project)) != '') - with: - name: ${{ env.BcptTestResultsArtifactsName }} - path: '${{ matrix.project }}/bcptTestResults.json' - if-no-files-found: ignore - - - name: Analyze Test Results - id: analyzeTestResults - if: success() || failure() - uses: microsoft/AL-Go-Actions/AnalyzeTests@preview - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - Project: ${{ matrix.project }} - - - name: Cleanup - if: always() - uses: microsoft/AL-Go-Actions/PipelineCleanup@preview - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - Project: ${{ matrix.project }} + uses: ./.github/workflows/_BuildALGoProject.yaml + secrets: inherit + with: + shell: ${{ needs.Initialization.outputs.githubRunnerShell }} + runsOn: ${{ needs.Initialization.outputs.githubRunner }} + checkoutRef: refs/pull/${{ github.event.number }}/merge + parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} + project: ${{ matrix.project }} + buildMode: ${{ matrix.buildMode }} + projectDependenciesJson: ${{ needs.Initialization.outputs.projectDependenciesJson }} + secrets: 'licenseFileUrl,insiderSasToken,keyVaultCertificateUrl,keyVaultCertificatePassword,keyVaultClientId,gitHubPackagesContext' + publishThisBuildArtifacts: ${{ needs.Initialization.outputs.workflowDepth > 1 }} Build: needs: [ Initialization, Build1 ] if: (!failure()) && (!cancelled()) && (needs.Build1.result == 'success' || needs.Build1.result == 'skipped') && fromJson(needs.Initialization.outputs.buildOrderJson)[1].projectsCount > 0 - runs-on: ${{ fromJson(needs.Initialization.outputs.githubRunner) }} - defaults: - run: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} strategy: matrix: include: ${{ fromJson(needs.Initialization.outputs.buildOrderJson)[1].buildDimensions }} fail-fast: false name: Build ${{ matrix.project }} - ${{ matrix.buildMode }} - outputs: - AppsArtifactsName: ${{ steps.calculateArtifactNames.outputs.AppsArtifactsName }} - TestAppsArtifactsName: ${{ steps.calculateArtifactNames.outputs.TestAppsArtifactsName }} - TestResultsArtifactsName: ${{ steps.calculateArtifactNames.outputs.TestResultsArtifactsName }} - BcptTestResultsArtifactsName: ${{ steps.calculateArtifactNames.outputs.BcptTestResultsArtifactsName }} - BuildOutputArtifactsName: ${{ steps.calculateArtifactNames.outputs.BuildOutputArtifactsName }} - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - lfs: true - ref: refs/pull/${{ github.event.number }}/merge - - - name: Download thisbuild artifacts - if: env.workflowDepth > 1 - uses: actions/download-artifact@v3 - with: - path: '.dependencies' - - - name: Read settings - uses: microsoft/AL-Go-Actions/ReadSettings@preview - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - project: ${{ matrix.project }} - - - name: Read secrets - uses: microsoft/AL-Go-Actions/ReadSecrets@preview - env: - secrets: ${{ toJson(secrets) }} - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - settingsJson: ${{ env.Settings }} - secrets: 'licenseFileUrl,insiderSasToken,keyVaultCertificateUrl,keyVaultCertificatePassword,keyVaultClientId,gitHubPackagesContext' - - - name: Determine ArtifactUrl - uses: microsoft/AL-Go-Actions/DetermineArtifactUrl@preview - id: determineArtifactUrl - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - project: ${{ matrix.project }} - settingsJson: ${{ env.Settings }} - secretsJson: ${{ env.RepoSecrets }} - - - name: Cache Business Central Artifacts - if: env.useCompilerFolder == 'True' && steps.determineArtifactUrl.outputs.ArtifactUrl && !contains(env.artifact,'INSIDERSASTOKEN') - uses: actions/cache@v3 - with: - path: .artifactcache - key: ${{ steps.determineArtifactUrl.outputs.ArtifactUrl }} - - - name: Run pipeline - id: RunPipeline - uses: microsoft/AL-Go-Actions/RunPipeline@preview - env: - BuildMode: ${{ matrix.buildMode }} - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - project: ${{ matrix.project }} - projectDependenciesJson: ${{ needs.Initialization.outputs.projectDependenciesJson }} - settingsJson: ${{ env.Settings }} - secretsJson: ${{ env.RepoSecrets }} - buildMode: ${{ matrix.buildMode }} - - - name: Calculate Artifact names - id: calculateArtifactsNames - uses: microsoft/AL-Go-Actions/CalculateArtifactNames@preview - if: success() || failure() - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - settingsJson: ${{ env.Settings }} - project: ${{ matrix.project }} - buildMode: ${{ matrix.buildMode }} - branchName: ${{ github.ref_name }} - - - name: Upload thisbuild artifacts - apps - if: env.workflowDepth > 1 - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.calculateArtifactsNames.outputs.ThisBuildAppsArtifactsName }} - path: '${{ matrix.project }}/.buildartifacts/Apps/' - if-no-files-found: ignore - retention-days: 1 - - - name: Upload thisbuild artifacts - test apps - if: env.workflowDepth > 1 - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.calculateArtifactsNames.outputs.ThisBuildTestAppsArtifactsName }} - path: '${{ matrix.project }}/.buildartifacts/TestApps/' - if-no-files-found: ignore - retention-days: 1 - - - name: Publish artifacts - build output - uses: actions/upload-artifact@v3 - if: (success() || failure()) && (hashFiles(format('{0}/BuildOutput.txt',matrix.project)) != '') - with: - name: ${{ env.BuildOutputArtifactsName }} - path: '${{ matrix.project }}/BuildOutput.txt' - if-no-files-found: ignore - - - name: Publish artifacts - container event log - uses: actions/upload-artifact@v3 - if: (failure()) && (hashFiles(format('{0}/ContainerEventLog.evtx',matrix.project)) != '') - with: - name: ${{ env.ContainerEventLogArtifactsName }} - path: '${{ matrix.project }}/ContainerEventLog.evtx' - if-no-files-found: ignore - - - name: Publish artifacts - test results - uses: actions/upload-artifact@v3 - if: (success() || failure()) && (hashFiles(format('{0}/TestResults.xml',matrix.project)) != '') - with: - name: ${{ env.TestResultsArtifactsName }} - path: '${{ matrix.project }}/TestResults.xml' - if-no-files-found: ignore - - - name: Publish artifacts - bcpt test results - uses: actions/upload-artifact@v3 - if: (success() || failure()) && (hashFiles(format('{0}/bcptTestResults.json',matrix.project)) != '') - with: - name: ${{ env.BcptTestResultsArtifactsName }} - path: '${{ matrix.project }}/bcptTestResults.json' - if-no-files-found: ignore - - - name: Analyze Test Results - id: analyzeTestResults - if: success() || failure() - uses: microsoft/AL-Go-Actions/AnalyzeTests@preview - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - Project: ${{ matrix.project }} - - - name: Cleanup - if: always() - uses: microsoft/AL-Go-Actions/PipelineCleanup@preview - with: - shell: ${{ needs.Initialization.outputs.githubRunnerShell }} - parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} - Project: ${{ matrix.project }} + uses: ./.github/workflows/_BuildALGoProject.yaml + secrets: inherit + with: + shell: ${{ needs.Initialization.outputs.githubRunnerShell }} + runsOn: ${{ needs.Initialization.outputs.githubRunner }} + checkoutRef: refs/pull/${{ github.event.number }}/merge + parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} + project: ${{ matrix.project }} + buildMode: ${{ matrix.buildMode }} + projectDependenciesJson: ${{ needs.Initialization.outputs.projectDependenciesJson }} + secrets: 'licenseFileUrl,insiderSasToken,keyVaultCertificateUrl,keyVaultCertificatePassword,keyVaultClientId,gitHubPackagesContext' + publishThisBuildArtifacts: ${{ needs.Initialization.outputs.workflowDepth > 1 }} PostProcess: runs-on: [ windows-latest ] diff --git a/.github/workflows/_BuildALGoProject.yaml b/.github/workflows/_BuildALGoProject.yaml new file mode 100644 index 0000000000..49ceba098b --- /dev/null +++ b/.github/workflows/_BuildALGoProject.yaml @@ -0,0 +1,245 @@ +name: '_Build AL-GO project' + +run-name: 'Build project ${{ inputs.project }}' + +on: + workflow_call: + inputs: + shell: + description: Shell in which you want to run the action (powershell or pwsh) + required: false + default: powershell + type: string + runsOn: + description: JSON-formatted string og the types of machine to run the build job on + required: true + type: string + checkoutRef: + description: Ref to checkout + required: false + default: ${{ github.ref }} + type: string + project: + description: Name of the built project + required: true + type: string + projectDependenciesJson: + description: Dependencies of the built project in compressed Json format + required: false + default: '{}' + type: string + buildMode: + description: Build mode used when building the artifacts + required: true + type: string + secrets: + description: A comma-separated string with the names of the secrets, required for the workflow. + required: false + default: '' + type: string + publishThisBuildArtifacts: + description: Flag indicating whether this build artifacts should be published + required: false + default: false + type: boolean + publishArtifacts: + description: Flag indicating whether the artifacts should be published + required: false + default: false + type: boolean + artifactsNameSuffix: + description: Suffix to add to the artifacts names + required: false + default: '' + type: string + signArtifacts: + description: Flag indicating whether the apps should be signed + required: false + default: false + type: boolean + useArtifactCache: + description: Flag determining whether to use the Artifacts Cache + required: false + default: false + type: boolean + parentTelemetryScopeJson: + description: Specifies the telemetry scope for the telemetry signal + required: false + type: string +jobs: + BuildALGoProject: + runs-on: ${{ fromJson(inputs.runsOn) }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: ${{ inputs.checkoutRef }} + lfs: true + + - name: Download thisbuild artifacts + if: inputs.publishThisBuildArtifacts + uses: actions/download-artifact@v3 + with: + path: '.dependencies' + + - name: Read settings + uses: microsoft/AL-Go-Actions/ReadSettings@preview + with: + shell: ${{ inputs.shell }} + parentTelemetryScopeJson: ${{ inputs.parentTelemetryScopeJson }} + project: ${{ inputs.project }} + + - name: Read secrets + uses: microsoft/AL-Go-Actions/ReadSecrets@preview + env: + secrets: ${{ toJson(secrets) }} + with: + shell: ${{ inputs.shell }} + parentTelemetryScopeJson: ${{ inputs.parentTelemetryScopeJson }} + settingsJson: ${{ env.Settings }} + secrets: ${{ inputs.secrets }} + + - name: Determine ArtifactUrl + uses: microsoft/AL-Go-Actions/DetermineArtifactUrl@preview + id: determineArtifactUrl + with: + shell: ${{ inputs.shell }} + parentTelemetryScopeJson: ${{ inputs.parentTelemetryScopeJson }} + project: ${{ inputs.project }} + settingsJson: ${{ env.Settings }} + secretsJson: ${{ env.RepoSecrets }} + + - name: Cache Business Central Artifacts + if: env.useCompilerFolder == 'True' && inputs.useArtifactCache && steps.determineArtifactUrl.outputs.ArtifactCacheKey + uses: actions/cache@v3 + with: + path: .artifactcache + key: ${{ steps.determineArtifactUrl.outputs.ArtifactCacheKey }} + + - name: Run pipeline + id: RunPipeline + uses: microsoft/AL-Go-Actions/RunPipeline@preview + env: + BuildMode: ${{ inputs.buildMode }} + with: + shell: ${{ inputs.shell }} + parentTelemetryScopeJson: ${{ inputs.parentTelemetryScopeJson }} + project: ${{ inputs.project }} + projectDependenciesJson: ${{ inputs.projectDependenciesJson }} + settingsJson: ${{ env.Settings }} + secretsJson: ${{ env.RepoSecrets }} + buildMode: ${{ inputs.buildMode }} + + - name: Sign + if: inputs.signArtifacts && env.doNotSignApps == 'False' && env.keyVaultCodesignCertificateName != '' + id: sign + uses: microsoft/AL-Go-Actions/Sign@preview + with: + shell: ${{ needs.Initialization.outputs.githubRunnerShell }} + azureCredentialsJson: ${{ secrets.AZURE_CREDENTIALS }} + settingsJson: ${{ env.Settings }} + pathToFiles: '${{ matrix.project }}/.buildartifacts/Apps/*.app' + parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }} + + - name: Calculate Artifact names + id: calculateArtifactsNames + uses: microsoft/AL-Go-Actions/CalculateArtifactNames@preview + if: success() || failure() + with: + shell: ${{ inputs.shell }} + settingsJson: ${{ env.Settings }} + project: ${{ inputs.project }} + buildMode: ${{ inputs.buildMode }} + branchName: ${{ github.ref_name }} + suffix: ${{ inputs.artifactsNameSuffix }} + + - name: Upload thisbuild artifacts - apps + if: inputs.publishThisBuildArtifacts + uses: actions/upload-artifact@v3 + with: + name: ${{ steps.calculateArtifactsNames.outputs.ThisBuildAppsArtifactsName }} + path: '${{ inputs.project }}/.buildartifacts/Apps/' + if-no-files-found: ignore + retention-days: 1 + + - name: Upload thisbuild artifacts - test apps + if: inputs.publishThisBuildArtifacts + uses: actions/upload-artifact@v3 + with: + name: ${{ steps.calculateArtifactsNames.outputs.ThisBuildTestAppsArtifactsName }} + path: '${{ inputs.project }}/.buildartifacts/TestApps/' + if-no-files-found: ignore + retention-days: 1 + + - name: Publish artifacts - apps + uses: actions/upload-artifact@v3 + if: inputs.publishArtifacts + with: + name: ${{ env.AppsArtifactsName }} + path: '${{ inputs.project }}/.buildartifacts/Apps/' + if-no-files-found: ignore + + - name: Publish artifacts - dependencies + uses: actions/upload-artifact@v3 + if: inputs.publishArtifacts + with: + name: ${{ env.DependenciesArtifactsName }} + path: '${{ inputs.project }}/.buildartifacts/Dependencies/' + if-no-files-found: ignore + + - name: Publish artifacts - test apps + uses: actions/upload-artifact@v3 + if: inputs.publishArtifacts + with: + name: ${{ env.TestAppsArtifactsName }} + path: '${{ inputs.project }}/.buildartifacts/TestApps/' + if-no-files-found: ignore + + - name: Publish artifacts - build output + uses: actions/upload-artifact@v3 + if: (success() || failure()) && (hashFiles(format('{0}/BuildOutput.txt',inputs.project)) != '') + with: + name: ${{ env.BuildOutputArtifactsName }} + path: '${{ inputs.project }}/BuildOutput.txt' + if-no-files-found: ignore + + - name: Publish artifacts - container event log + uses: actions/upload-artifact@v3 + if: (failure()) && (hashFiles(format('{0}/ContainerEventLog.evtx',inputs.project)) != '') + with: + name: ${{ env.ContainerEventLogArtifactsName }} + path: '${{ inputs.project }}/ContainerEventLog.evtx' + if-no-files-found: ignore + + - name: Publish artifacts - test results + uses: actions/upload-artifact@v3 + if: (success() || failure()) && (hashFiles(format('{0}/TestResults.xml',inputs.project)) != '') + with: + name: ${{ env.TestResultsArtifactsName }} + path: '${{ inputs.project }}/TestResults.xml' + if-no-files-found: ignore + + - name: Publish artifacts - bcpt test results + uses: actions/upload-artifact@v3 + if: (success() || failure()) && (hashFiles(format('{0}/bcptTestResults.json',inputs.project)) != '') + with: + name: ${{ env.BcptTestResultsArtifactsName }} + path: '${{ inputs.project }}/bcptTestResults.json' + if-no-files-found: ignore + + - name: Analyze Test Results + id: analyzeTestResults + if: success() || failure() + uses: microsoft/AL-Go-Actions/AnalyzeTests@preview + with: + shell: ${{ inputs.shell }} + parentTelemetryScopeJson: ${{ inputs.parentTelemetryScopeJson }} + Project: ${{ inputs.project }} + + - name: Cleanup + if: always() + uses: microsoft/AL-Go-Actions/PipelineCleanup@preview + with: + shell: ${{ inputs.shell }} + parentTelemetryScopeJson: ${{ inputs.parentTelemetryScopeJson }} + Project: ${{ inputs.project }}