diff --git a/.config/tsaoptions.json b/.config/tsaoptions.json new file mode 100644 index 000000000..a581d13ad --- /dev/null +++ b/.config/tsaoptions.json @@ -0,0 +1,9 @@ +{ + "instanceUrl": "https://msazure.visualstudio.com", + "projectName": "One", + "areaPath": "One\\MGMT\\Compute\\PowerShell Desired State Configuration", + "notificationAliases": [ + "anmenaga@microsoft.com", + "slee@microsoft.com" + ] +} diff --git a/.pipelines/DSC-Official.yml b/.pipelines/DSC-Official.yml new file mode 100644 index 000000000..011b63a7d --- /dev/null +++ b/.pipelines/DSC-Official.yml @@ -0,0 +1,283 @@ +name: DSC-Release-$(Build.BuildId) +trigger: none + +pr: + branches: + include: + - onebranch + - release* + +variables: + BuildConfiguration: 'release' + PackageRoot: '$(System.ArtifactsDirectory)/Packages' + LinuxContainerImage: 'mcr.microsoft.com/onebranch/cbl-mariner/build:2.0' + WindowsContainerImage: onebranch.azurecr.io/windows/ltsc2019/vse2022:latest + +resources: + repositories: + - repository: onebranchTemplates + type: git + name: OneBranch.Pipelines/GovernedTemplates + ref: refs/heads/main + +extends: + template: v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates + parameters: + customTags: 'ES365AIMigrationTooling' + globalSdl: + disableLegacyManifest: true + sbom: + enabled: true + packageName: Microsoft.DSC + codeql: + compiled: + enabled: true + asyncSdl: # https://aka.ms/obpipelines/asyncsdl + enabled: true + forStages: [Build] + credscan: + enabled: true + scanFolder: $(Build.SourcesDirectory)\DSC + binskim: + enabled: true + apiscan: + enabled: false + + stages: + - stage: BuildAndSign + displayName: Build Native Binaries + dependsOn: [] + jobs: + - job: SetPackageVersion + displayName: Set PackageVersion + pool: + type: windows + variables: + repoRoot: $(Build.SourcesDirectory)\DSC + ob_sdl_tsa_configFile: $(Build.SourcesDirectory)\DSC\.config\tsaoptions.json + ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' + steps: + - checkout: self + target: host + - pwsh: | + $packageVersion = $(repoRoot)/build.ps1 -GetPackageVersion + $vstsCommandString = "vso[task.setvariable variable=Version;isoutput=true]$packageVersion" + Write-Host ("sending " + $vstsCommandString) + Write-Host "##$vstsCommandString" + name: Package + + - job: BuildWin + dependsOn: SetPackageVersion + strategy: + matrix: + Windows x64: + buildName: x86_64-pc-windows-msvc + Windows x64_arm64: + buildName: aarch64-pc-windows-msvc + variables: + PackageVersion: $[ dependencies.SetPackageVersion.outputs['Package.Version'] ] + ob_sdl_tsa_configFile: $(Build.SourcesDirectory)\DSC\.config\tsaoptions.json + ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' + repoRoot: $(Build.SourcesDirectory)\DSC + signSrcPath: $(repoRoot)/out + ob_artifactBaseName: 'DSC-$(buildName)' + ob_sdl_sbom_enabled: true + ob_signing_setup_enabled: true + ob_sdl_codeql_compiled_enabled: false + pool: + type: windows + displayName: Build + steps: + - checkout: self + target: host + - task: CodeQL3000Init@0 # Add CodeQL Init task right before your 'Build' step. + inputs: + Enabled: true + AnalyzeInPipeline: true + Language: rust + - pwsh: | + $tmpdir = Join-Path ([System.IO.Path]::GetTempPath()) ([System.Guid]::NewGuid()) + New-Item -ItemType Directory -Path $tmpdir + Write-Host "##vso[task.setvariable variable=CARGO_TARGET_DIR;]$tmpdir" + displayName: 🛠️ Workaround for the LoadLibrary ACCESS_VIOLATION OneBranch issue + - pwsh: | + Set-Location "$(Build.SourcesDirectory)/DSC" + ./build.ps1 -Release -Architecture $(buildName) -SkipLinkCheck + displayName: 'Build $(buildName)' + condition: succeeded() + - task: CodeQL3000Finalize@0 # Add CodeQL Finalize task right after your 'Build' step. + condition: always() + - pwsh: | + $null = New-Item -ItemType Directory -Path "$(PackageRoot)" -ErrorAction Ignore + $null = New-Item -ItemType Directory -Path "$(PackageRoot)/out" -ErrorAction Ignore + $outPath = New-Item -ItemType Directory -Path "$(PackageRoot)/out/$(buildName)" -ErrorAction Ignore + # workaround known issue of building in OneBranch copying from TMP folder + $null = New-Item -ItemType Directory -Path "$(signSrcPath)" -ErrorAction Ignore + # copy only the exes from the TMP folder since it contains intermediately built files we don't want to sign + Copy-Item "$env:CARGO_TARGET_DIR/*.exe" "$(signSrcPath)" + # Copy-Item -Path "$(Build.SourcesDirectory)/DSC/bin/$(buildName)/$(BuildConfiguration)/*" -Destination $outPath -Verbose -Force + displayName: Copy binaries + condition: succeeded() + - task: onebranch.pipeline.signing@1 + displayName: Sign 1st party files + inputs: + command: 'sign' + signing_profile: external_distribution + files_to_sign: | + *.exe; + *.json; + *.ps1; + search_root: $(signSrcPath) + - task: CopyFiles@2 + displayName: "Copy signed files to ob_outputDirectory - '$(ob_outputDirectory)'" + inputs: + SourceFolder: "$(signSrcPath)" + Contents: '*' + TargetFolder: $(ob_outputDirectory) + - pwsh: | + compress-archive -Path "$(ob_outputDirectory)/*" -DestinationPath "$(ob_outputDirectory)/DSC-$(PackageVersion)-$(buildName).zip" + displayName: 'Compress $(buildName)' + condition: succeeded() + - pwsh: | + Set-Location "$(Build.SourcesDirectory)/DSC" + ./build.ps1 -msix -skipbuild + Copy-Item *.msix "$(ob_outputDirectory)" + displayName: 'Create msix for $(buildName)' + condition: succeeded() + + - job: CreateMsixBundle + dependsOn: BuildWin + variables: + ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' + pool: + type: windows + steps: + - pwsh: | + Set-Location "$(Build.SourcesDirectory)/DSC" + ./build.ps1 -msixbundle + displayName: 'Create msixbundle' + condition: succeeded() + + - job: PublishSigned + dependsOn: BuildWin + variables: + signOutPath: $[ dependencies.BuildWin.outputs['signOutPath.signOutPath'] ] + ob_sdl_tsa_configFile: $(Build.SourcesDirectory)\DSC\.config\tsaoptions.json + ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' + pool: + type: windows + steps: + - task: CopyFiles@2 + displayName: "Copy Files for 'PublishPipelineArtifact@1' publish task" + inputs: + SourceFolder: $(signOutPath) + Contents: '**' + TargetFolder: $(Build.ArtifactStagingDirectory)/signed + + - job: BuildLinux + dependsOn: SetPackageVersion + variables: + PackageVersion: $[ dependencies.SetPackageVersion.outputs['Package.Version'] ] + ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' + displayName: Linux-x64-gnu + pool: + type: linux + steps: + - pwsh: | + ./build.ps1 -Release -Architecture x86_64-unknown-linux-gnu + displayName: 'Build x86_64-unknown-linux-gnu' + condition: succeeded() + - pwsh: | + tar czf '$(ob_outputDirectory)/DSC-$(PackageVersion)-x86_64-unknown-linux-gnu.tar.gz' -C $(Build.SourcesDirectory)/bin/x86_64-unknown-linux-gnu/$(BuildConfiguration) . + displayName: 'Compress x86_64-unknown-linux-gnu' + condition: succeeded() + + - job: BuildLinuxArm64 + dependsOn: SetPackageVersion + variables: + PackageVersion: $[ dependencies.SetPackageVersion.outputs['Package.Version'] ] + ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' + displayName: Linux-ARM64-gnu + pool: + type: linux + hostArchitecture: arm64 + steps: + - pwsh: | + ./build.ps1 -Release -Architecture aarch64-unknown-linux-gnu + displayName: 'Build aarch64-unknown-linux-gnu' + condition: succeeded() + - pwsh: | + tar czf '$(ob_outputDirectory)/DSC-$(PackageVersion)-aarch64-unknown-linux-gnu.tar.gz' -C $(Build.SourcesDirectory)/bin/aarch64-unknown-linux-gnu/$(BuildConfiguration) . + displayName: 'Compress aarch64-unknown-linux-gnu' + condition: succeeded() + + - job: BuildMac + dependsOn: SetPackageVersion + variables: + PackageVersion: $[ dependencies.SetPackageVersion.outputs['Package.Version'] ] + ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' + displayName: Build + pool: + type: linux + isCustom: true + name: Azure Pipelines + vmImage: 'macOS-latest' + strategy: + matrix: + macOS x64: + buildName: x86_64-apple-darwin + macOS arm64: + buildName: aarch64-apple-darwin + steps: + - pwsh: | + ./build.ps1 -Release -Architecture $(buildName) + displayName: 'Build $(buildName)' + condition: succeeded() + - pwsh: | + tar czf '$(ob_outputDirectory)/DSC-$(PackageVersion)-$(buildName).tar.gz' -C $(Build.SourcesDirectory)/bin/$(buildName)/$(BuildConfiguration) . + displayName: 'Compress $(buildName)' + condition: succeeded() + + - stage: Release + dependsOn: BuildAndSign + variables: + PackageVersion: $[ dependencies.SetPackageVersion.outputs['Package.Version'] ] + drop: $(Pipeline.Workspace)/drop_build_main + jobs: + - job: Validation + displayName: Manual validation + pool: + type: agentless + timeoutInMinutes: 1440 + steps: + - task: ManualValidation@0 + displayName: Wait 24 hours for validation + inputs: + notifyUsers: $(Build.RequestedForEmail) + instructions: Please validate the release + timeoutInMinutes: 1440 + - job: GitHub + dependsOn: validation + displayName: Publish draft to GitHub + pool: + type: windows + variables: + ob_outputDirectory: '$(Build.SourcesDirectory)' + steps: + - download: current + displayName: Download artifacts + - task: GitHubRelease@1 + displayName: Create GitHub release + inputs: + gitHubConnection: GitHub + repositoryName: PowerShell/DSC + action: create + assets: | + *.zip; + *.tar.gz; + addChangeLog: true + changeLogType: commitBased + releaseNotesFilePath: CHANGELOG.md + tagSource: gitTag + tag: v$(version) + isDraft: true diff --git a/.vsts-ci/release.yml b/.vsts-ci/release.yml deleted file mode 100644 index 3267b7766..000000000 --- a/.vsts-ci/release.yml +++ /dev/null @@ -1,274 +0,0 @@ -trigger: none - -variables: - - name: BuildConfiguration - value: 'release' - - name: PackageRoot - value: '$(System.ArtifactsDirectory)/Packages' - - group: DSCAPIScan - -resources: - repositories: - - repository: ComplianceRepo - type: github - endpoint: ComplianceGHRepo - name: PowerShell/compliance - ref: master - -stages: -- stage: BuildAndSign - displayName: Build Native Binaries - dependsOn: [] - jobs: - - job: SetPackageVersion - displayName: Set PackageVersion - steps: - - checkout: self - - pwsh: | - $packageVersion = ./build.ps1 -GetPackageVersion - $vstsCommandString = "vso[task.setvariable variable=Version;isoutput=true]$packageVersion" - Write-Host ("sending " + $vstsCommandString) - Write-Host "##$vstsCommandString" - name: Package - - - job: BuildWin - dependsOn: SetPackageVersion - variables: - - group: ESRP - - name: PackageVersion - value: $[ dependencies.SetPackageVersion.outputs['Package.Version'] ] - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Rust-Secure - displayName: Build - strategy: - matrix: - Windows x64: - buildName: x86_64-pc-windows-msvc - Windows x64_arm64: - buildName: aarch64-pc-windows-msvc - - steps: - - checkout: self - - pwsh: | - Set-Location "$(Build.SourcesDirectory)/DSC" - ./build.ps1 -Release -Architecture $(buildName) -SkipLinkCheck - displayName: 'Build $(buildName)' - condition: succeeded() - - pwsh: | - $null = New-Item -ItemType Directory -Path "$(PackageRoot)" -ErrorAction Ignore - $null = New-Item -ItemType Directory -Path "$(PackageRoot)/out" -ErrorAction Ignore - $outPath = New-Item -ItemType Directory -Path "$(PackageRoot)/out/$(buildName)" -ErrorAction Ignore - Copy-Item -Path "$(Build.SourcesDirectory)/DSC/bin/$(buildName)/$(BuildConfiguration)/*" -Destination $outPath -Verbose -Force - displayName: Copy binaries - condition: succeeded() - - pwsh: | - Set-Location "$(PackageRoot)" - $signSrcPath = "$(PackageRoot)/out/$(buildName)" - # Set signing src path variable - $vstsCommandString = "vso[task.setvariable variable=signSrcPath]${signSrcPath}" - Write-Host ("sending " + $vstsCommandString) - Write-Host "##$vstsCommandString" - - pwsh: | - $signOutPath = "$(PackageRoot)/signed" - $null = New-Item -ItemType Directory -Path $signOutPath - # Set signing out path variable - $vstsCommandString = "vso[task.setvariable variable=signOutPath;isoutput=true]${signOutPath}" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - name: signOutPath - - pwsh: | - # Set path variable for guardian codesign validation - $vstsCommandString = "vso[task.setvariable variable=GDN_CODESIGN_TARGETDIRECTORY]$(signOutPath.signOutPath)" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - displayName: Setup variables for signing - - - checkout: ComplianceRepo - - - template: EsrpSign.yml@ComplianceRepo - parameters: - # the folder which contains the binaries to sign - buildOutputPath: $(Build.SourcesDirectory)/DSC/bin/$(buildName)/$(BuildConfiguration) - # the location to put the signed output - signOutputPath: $(signOutPath.signOutPath) - # the certificate ID to use - certificateId: "CP-230012" - # The file pattern to use - # If not using minimatch: comma separated, with * supported - # If using minimatch: newline separated, with !, **, and * supported. - # See link in the useMinimatch comments. - pattern: '*.exe,*.ps1' - # decides if the task should use minimatch for the pattern matching. - # https://github.com/isaacs/minimatch#features - useMinimatch: false - - - template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: $(signOutPath.signOutPath) - Build_Repository_Uri: 'https://github.com/powershell/DSC' - PackageName: 'DSC' - PackageVersion: $(PackageVersion) - - - pwsh: | - compress-archive -Path "$(signOutPath.signOutPath)/*" -DestinationPath "$(PackageRoot)/DSC-$(PackageVersion)-$(buildName).zip" - displayName: 'Compress $(buildName)' - condition: succeeded() - - pwsh: | - Write-Host "##vso[artifact.upload containerfolder=release;artifactname=release]$(PackageRoot)\DSC-$(PackageVersion)-$(buildName).zip" - displayName: Upload artifacts - condition: succeeded() - - - job: PublishSigned - dependsOn: BuildWin - variables: - - name: signOutPath - value: $[ dependencies.BuildWin.outputs['signOutPath.signOutPath'] ] - steps: - - task: PublishPipelineArtifact@1 - inputs: - targetpath: $(signOutPath) - artifactName: signed - - - job: BuildLinux - dependsOn: SetPackageVersion - variables: - PackageVersion: $[ dependencies.SetPackageVersion.outputs['Package.Version'] ] - displayName: Linux-x64-gnu - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMSUbuntu20.04-Secure - steps: - - pwsh: | - ./build.ps1 -Release -Architecture x86_64-unknown-linux-gnu - displayName: 'Build x86_64-unknown-linux-gnu' - condition: succeeded() - - template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: $(Build.SourcesDirectory)/bin/x86_64-unknown-linux-gnu/$(BuildConfiguration) - Build_Repository_Uri: 'https://github.com/powershell/DSC' - PackageName: 'DSC' - PackageVersion: $(PackageVersion) - - pwsh: | - new-item -itemType Directory $(PackageRoot) -Force - tar czf '$(PackageRoot)/DSC-$(PackageVersion)-x86_64-unknown-linux-gnu.tar.gz' -C $(Build.SourcesDirectory)/bin/x86_64-unknown-linux-gnu/$(BuildConfiguration) . - displayName: 'Compress x86_64-unknown-linux-gnu' - condition: succeeded() - - pwsh: | - Write-Host '##vso[artifact.upload containerfolder=release;artifactname=release]$(PackageRoot)/DSC-$(PackageVersion)-x86_64-unknown-linux-gnu.tar.gz' - displayName: Upload artifacts - condition: succeeded() - - - job: BuildLinuxArm64 - dependsOn: SetPackageVersion - variables: - PackageVersion: $[ dependencies.SetPackageVersion.outputs['Package.Version'] ] - displayName: Linux-ARM64-gnu - pool: - name: ps-powershell-rel-arm - demands: - - ImageOverride -equals PSMMSUbuntu20.04-ARM64-secure - steps: - - pwsh: | - ./build.ps1 -Release -Architecture aarch64-unknown-linux-gnu - displayName: 'Build aarch64-unknown-linux-gnu' - condition: succeeded() - - template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: $(Build.SourcesDirectory)/bin/aarch64-unknown-linux-gnu/$(BuildConfiguration) - Build_Repository_Uri: 'https://github.com/powershell/DSC' - PackageName: 'DSC' - PackageVersion: $(PackageVersion) - - pwsh: | - new-item -itemType Directory $(PackageRoot) -Force - tar czf '$(PackageRoot)/DSC-$(PackageVersion)-aarch64-unknown-linux-gnu.tar.gz' -C $(Build.SourcesDirectory)/bin/aarch64-unknown-linux-gnu/$(BuildConfiguration) . - displayName: 'Compress aarch64-unknown-linux-gnu' - condition: succeeded() - - pwsh: | - Write-Host '##vso[artifact.upload containerfolder=release;artifactname=release]$(PackageRoot)/DSC-$(PackageVersion)-aarch64-unknown-linux-gnu.tar.gz' - displayName: Upload artifacts - condition: succeeded() - - - job: BuildMac - dependsOn: SetPackageVersion - variables: - PackageVersion: $[ dependencies.SetPackageVersion.outputs['Package.Version'] ] - displayName: Build - pool: - vmImage: macOS-Latest - strategy: - matrix: - macOS x64: - buildName: x86_64-apple-darwin - macOS arm64: - buildName: aarch64-apple-darwin - steps: - - pwsh: | - ./build.ps1 -Release -Architecture $(buildName) - displayName: 'Build $(buildName)' - condition: succeeded() - - template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: $(Build.SourcesDirectory)/bin/$(buildName)/$(BuildConfiguration) - Build_Repository_Uri: 'https://github.com/powershell/DSC' - PackageName: 'DSC' - PackageVersion: $(PackageVersion) - - pwsh: | - new-item -itemType Directory $(PackageRoot) -Force - tar czf '$(PackageRoot)/DSC-$(PackageVersion)-$(buildName).tar.gz' -C $(Build.SourcesDirectory)/bin/$(buildName)/$(BuildConfiguration) . - displayName: 'Compress $(buildName)' - condition: succeeded() - - pwsh: | - Write-Host "##vso[artifact.upload containerfolder=release;artifactname=release]$(PackageRoot)/DSC-$(PackageVersion)-$(buildName).tar.gz" - displayName: Upload artifacts - condition: succeeded() - -- stage: compliance - displayName: Compliance - dependsOn: BuildAndSign - jobs: - - job: Compliance_Job - variables: - PackageVersion: $[ stageDependencies.BuildAndSign.SetPackageVersion.outputs['Package.Version'] ] - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Rust-Secure - steps: - - checkout: self - clean: true - - checkout: ComplianceRepo - clean: true - - - download: current - artifact: release - - - download: current - artifact: signed - - - pwsh: | - Get-ChildItem -Path 'ENV:' - displayName: Capture environment - - - template: assembly-module-compliance.yml@ComplianceRepo - parameters: - # binskim - AnalyzeTarget: '$(Build.SourcesDirectory)/DSC/bin/x86_64-pc-windows-msvc/release/*.exe' #'$(Pipeline.Workspace)/uncompressed/*.exe' - AnalyzeSymPath: 'SRV*' - # component-governance - sourceScanPath: '$(Build.SourcesDirectory)/DSC' - # credscan - suppressionsFile: '' - # TermCheck - optionsRulesDBPath: '' - optionsFTPath: '' - # tsa-upload - codeBaseName: 'DSC' - # selections - softwareName: 'DSC' - softwareNameFolder: '$(Build.SourcesDirectory)/DSC/bin/x86_64-pc-windows-msvc/release' #'$(Pipeline.Workspace)/uncompressed' - softwareVersion: '$(PackageVersion)' - connectionString: RunAs=App;AppId=$(APIScanClient);TenantId=$(APIScanTenant);AppKey=$(APIScanSecret) - APIScan: true # set to false when not using Windows APIs. diff --git a/build.ps1 b/build.ps1 index a9877906a..f893e2dc3 100644 --- a/build.ps1 +++ b/build.ps1 @@ -8,6 +8,7 @@ param( [switch]$Clippy, [switch]$SkipBuild, [switch]$Msix, + [switch]$MsixBundle, [switch]$Test, [switch]$GetPackageVersion, [switch]$SkipLinkCheck @@ -26,16 +27,22 @@ if ($GetPackageVersion) { if (!(Get-Command 'cargo' -ErrorAction Ignore)) { Write-Verbose -Verbose "Rust not found, installing..." if (!$IsWindows) { - curl https://sh.rustup.rs -sSf | sh + curl https://sh.rustup.rs -sSf | sh -s -- -y + $env:PATH += ":$env:HOME/.cargo/bin" } else { Invoke-WebRequest 'https://static.rust-lang.org/rustup/dist/i686-pc-windows-gnu/rustup-init.exe' -OutFile 'temp:/rustup-init.exe' Write-Verbose -Verbose "Use the default settings to ensure build works" - & 'temp:/rustup-init.exe' + & 'temp:/rustup-init.exe' -y + $env:PATH += ";$env:USERPROFILE\.cargo\bin" Remove-Item temp:/rustup-init.exe -ErrorAction Ignore } } +if ($IsLinux -and (Test-Path /etc/mariner-release)) { + tdnf install -y openssl-devel +} + rustup default stable $BuildToolsPath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC" @@ -54,6 +61,10 @@ function Find-LinkExe { } } +if ($Msix -or $MsixBundle) { + $SkipBuild = $true +} + if (!$SkipBuild -and !$SkipLinkCheck -and $IsWindows -and !(Get-Command 'link.exe' -ErrorAction Ignore)) { if (!(Test-Path $BuildToolsPath)) { Write-Verbose -Verbose "link.exe not found, installing C++ build tools" @@ -294,15 +305,7 @@ if ($Test) { Invoke-Pester -ErrorAction Stop } -if ($Msix) { - if (!$IsWindows) { - throw "MSIX is only supported on Windows" - } - - if ($architecture -eq 'current') { - throw 'MSIX requires a specific architecture' - } - +function Find-MakeAppx() { $makeappx = Get-Command makeappx -CommandType Application -ErrorAction Ignore if ($null -eq $makeappx) { # try to find @@ -319,6 +322,36 @@ if ($Msix) { } } + $makeappx +} + +if ($MsixBundle) { + if ($Msix) { + throw "Creating MsixBundle requires all msix packages to already be created" + } + + if (!$IsWindows) { + throw "MsixBundle is only supported on Windows" + } + + $productVersion = ((Get-Content $PSScriptRoot/dsc/Cargo.toml) -match '^version\s*=\s*') -replace 'version\s*=\s*"(.*?)"', '$1' + $isPreview = $productVersion -like '*-*' + $packageName = "DSC-$productVersion-Win" + $makeappx = Find-MakeAppx + & $makeappx bundle /d $PSScriptRoot /p "$PSScriptRoot\$packageName.msixbundle" + return +} + +if ($Msix) { + if (!$IsWindows) { + throw "MSIX is only supported on Windows" + } + + if ($architecture -eq 'current') { + throw 'MSIX requires a specific architecture' + } + + $makeappx = Find-MakeAppx $makepri = Get-Item (Join-Path $makeappx.Directory "makepri.exe") -ErrorAction Stop $displayName = "DesiredStateConfiguration" $productVersion = ((Get-Content $PSScriptRoot/dsc/Cargo.toml) -match '^version\s*=\s*') -replace 'version\s*=\s*"(.*?)"', '$1'