diff --git a/.gitignore b/.gitignore index d328ed2984..6f54b9e6b7 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,7 @@ dotnet-uninstall-debian-packages.sh *.exe *.msi *.appx +*.msix # Ignore binaries and symbols *.pdb diff --git a/assets/AppxManifest.xml b/assets/AppxManifest.xml new file mode 100644 index 0000000000..586562ac6b --- /dev/null +++ b/assets/AppxManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + PowerShell Core 6 + Microsoft Corporation + assets\StoreLogo.png + disabled + disabled + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/Square150x150Logo.png b/assets/Square150x150Logo.png new file mode 100644 index 0000000000..bba1843f12 Binary files /dev/null and b/assets/Square150x150Logo.png differ diff --git a/assets/Square44x44Logo.png b/assets/Square44x44Logo.png new file mode 100644 index 0000000000..16b1f6dd16 Binary files /dev/null and b/assets/Square44x44Logo.png differ diff --git a/assets/Square44x44Logo.targetsize-48.png b/assets/Square44x44Logo.targetsize-48.png new file mode 100644 index 0000000000..16b1f6dd16 Binary files /dev/null and b/assets/Square44x44Logo.targetsize-48.png differ diff --git a/assets/Square44x44Logo.targetsize-48_altform-unplated.png b/assets/Square44x44Logo.targetsize-48_altform-unplated.png new file mode 100644 index 0000000000..16b1f6dd16 Binary files /dev/null and b/assets/Square44x44Logo.targetsize-48_altform-unplated.png differ diff --git a/assets/StoreLogo.png b/assets/StoreLogo.png new file mode 100644 index 0000000000..afd20a3d9d Binary files /dev/null and b/assets/StoreLogo.png differ diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1 index ae1c21f968..4454b85b5b 100644 --- a/tools/packaging/packaging.psm1 +++ b/tools/packaging/packaging.psm1 @@ -25,7 +25,7 @@ function Start-PSPackage { [string]$Name = "powershell", # Ubuntu, CentOS, Fedora, macOS, and Windows packages are supported - [ValidateSet("deb", "osxpkg", "rpm", "msi", "zip", "nupkg", "tar", "tar-arm", "tar-arm64", "tar-alpine", "fxdependent")] + [ValidateSet("msix", "deb", "osxpkg", "rpm", "msi", "zip", "nupkg", "tar", "tar-arm", "tar-arm64", "tar-alpine", "fxdependent")] [string[]]$Type, # Generate windows downlevel package @@ -254,7 +254,7 @@ function Start-PSPackage { } elseif ($Environment.IsMacOS) { "osxpkg", "nupkg", "tar" } elseif ($Environment.IsWindows) { - "msi", "nupkg" + "msi", "nupkg", "msix" } Write-Warning "-Type was not specified, continuing with $Type!" } @@ -335,6 +335,18 @@ function Start-PSPackage { New-MSIPackage @Arguments } } + "msix" { + $Arguments = @{ + ProductNameSuffix = $NameSuffix + ProductSourcePath = $Source + ProductVersion = $Version + Force = $Force + } + + if ($PSCmdlet.ShouldProcess("Create MSIX Package")) { + New-MSIXPackage @Arguments + } + } 'nupkg' { $Arguments = @{ PackageNameSuffix = $NameSuffix @@ -2726,6 +2738,107 @@ function New-MSIPackage } } +<# + .Synopsis + Creates a Windows AppX MSIX package and assumes that the binaries are already built using 'Start-PSBuild'. + This only works on a Windows machine due to the usage of makeappx.exe. + .EXAMPLE + # This example shows how to produce a Debug-x64 installer for development purposes. + cd $RootPathOfPowerShellRepo + Import-Module .\build.psm1; Import-Module .\tools\packaging\packaging.psm1 + New-MSIXPackage -Verbose -ProductSourcePath '.\src\powershell-win-core\bin\Debug\netcoreapp2.1\win7-x64\publish' -ProductTargetArchitecture x64 -ProductVersion '1.2.3' +#> +function New-MSIXPackage +{ + [CmdletBinding(SupportsShouldProcess, ConfirmImpact='Low')] + param ( + + # Name of the Product + [ValidateNotNullOrEmpty()] + [string] $ProductName = 'PowerShell', + + # Suffix of the Name + [string] $ProductNameSuffix, + + # Version of the Product + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] $ProductVersion, + + # Source Path to the Product Files - required to package the contents into an MSIX + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] $ProductSourcePath, + + # Force overwrite of package + [Switch] $Force + ) + + $makeappx = Get-Command makeappx -CommandType Application -ErrorAction Ignore + if ($null -eq $makeappx) { + # This is location in our dockerfile + $dockerPath = Join-Path $env:SystemDrive "makeappx" + if (Test-Path $dockerPath) { + $makeappx = Get-ChildItem $dockerPath -Include makeappx.exe -Recurse | Select-Object -First 1 + } + + if ($null -eq $makeappx) { + # Try to find in well known location + $makeappx = Get-ChildItem "${env:ProgramFiles(x86)}\Windows Kits\10\bin\*\x64" -Include makeappx.exe -Recurse | Select-Object -First 1 + if ($null -eq $makeappx) { + throw "Could not locate makeappx.exe, make sure Windows 10 SDK is installed" + } + } + } + + $makepri = Get-Item (Join-Path $makeappx.Directory "makepri.exe") -ErrorAction Stop + + $ProductSemanticVersion = Get-PackageSemanticVersion -Version $ProductVersion + $productSemanticVersionWithName = $ProductName + '-' + $ProductSemanticVersion + $packageName = $productSemanticVersionWithName + if ($ProductNameSuffix) { + $packageName += "-$ProductNameSuffix" + } + + $ProductVersion = Get-PackageVersionAsMajorMinorBuildRevision -Version $ProductVersion + if (([Version]$ProductVersion).Revision -eq -1) { + $ProductVersion += ".0" + } + + # Appx manifest needs to be in root of source path, but the embedded version needs to be updated + $appxManifest = Get-Content "$RepoRoot\assets\AppxManifest.xml" -Raw + $appxManifest = $appxManifest.Replace('$VERSION$', $ProductVersion) + Set-Content -Path "$ProductSourcePath\AppxManifest.xml" -Value $appxManifest -Force + # Necessary image assets need to be in source assets folder + $assets = @( + 'Square150x150Logo.png' + 'Square44x44Logo.png' + 'Square44x44Logo.targetsize-48.png' + 'Square44x44Logo.targetsize-48_altform-unplated.png' + 'StoreLogo.png' + ) + + if (!(Test-Path "$ProductSourcePath\assets")) { + $null = New-Item -ItemType Directory -Path "$ProductSourcePath\assets" + } + + $assets | ForEach-Object { + Copy-Item -Path "$RepoRoot\assets\$_" -Destination "$ProductSourcePath\assets\" + } + + if ($PSCmdlet.ShouldProcess("Create .msix package?")) { + Write-Verbose "Creating priconfig.xml" -Verbose + Start-NativeExecution -VerboseOutputOnError { & $makepri createconfig /o /cf (Join-Path $ProductSourcePath "priconfig.xml") /dq en-US } + Write-Verbose "Creating resources.pri" -Verbose + Push-Location $ProductSourcePath + Start-NativeExecution -VerboseOutputOnError { & $makepri new /v /o /pr $ProductSourcePath /cf (Join-Path $ProductSourcePath "priconfig.xml") } + Pop-Location + Write-Verbose "Creating msix package" -Verbose + Start-NativeExecution -VerboseOutputOnError { & $makeappx pack /o /v /h SHA256 /d $ProductSourcePath /p (Join-Path -Path $PWD -ChildPath "$packageName.msix") } + Write-Verbose "Created $packageName.msix" -Verbose + } +} + # verify no files have been added or removed # if so, write an error with details function Test-FileWxs diff --git a/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/Dockerfile b/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/Dockerfile index 6902ec62e8..ef24e3aa7e 100644 --- a/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/Dockerfile +++ b/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/Dockerfile @@ -19,6 +19,10 @@ COPY wix.psm1 containerFiles/wix.psm1 RUN Import-Module ./containerFiles/wix.psm1; ` Install-WixZip -zipPath \wix.Zip +# Install makeappx and makepri +ADD https://pscoretestdata.blob.core.windows.net/build-files/makeappx/makeappx.zip?sp=r&st=2019-04-05T18:02:52Z&se=2020-04-06T02:02:52Z&spr=https&sv=2018-03-28&sig=t07uC1K3uFLtINQsmorHobgPh%2B%2BBgjFnmHEJGNZT6Hk%3D&sr=b /makeappx.zip +RUN Expand-Archive /makeappx.zip + COPY PowerShellPackage.ps1 / ENV DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 diff --git a/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 b/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 index f4bbe70313..ffa5832c11 100644 --- a/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 +++ b/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 @@ -116,12 +116,19 @@ try{ $pspackageParams = @{'Type'='msi'; 'WindowsRuntime'=$Runtime} } - if (!$ComponentRegistration.IsPresent -and !$Symbols.IsPresent -and $Runtime -notmatch "arm" -and $Runtime -ne 'fxdependent') + if (!$ComponentRegistration.IsPresent -and !$Symbols.IsPresent -and $Runtime -notmatch 'arm' -and $Runtime -ne 'fxdependent') { Write-Verbose "Starting powershell packaging(msi)..." -verbose Start-PSPackage @pspackageParams @releaseTagParam } + if (!$ComponentRegistration.IsPresent -and !$Symbols.IsPresent -and $Runtime -notin 'win7-x86','fxdependent') + { + $pspackageParams['Type']='msix' + Write-Verbose "Starting powershell packaging(msix)..." -verbose + Start-PSPackage @pspackageParams @releaseTagParam + } + if (!$ComponentRegistration.IsPresent -and $Runtime -ne 'fxdependent') { $pspackageParams['Type']='zip' @@ -131,7 +138,7 @@ try{ Write-Verbose "Exporting packages ..." -verbose - Get-ChildItem $location\*.msi,$location\*.zip,$location\*.wixpdb | ForEach-Object { + Get-ChildItem $location\*.msi,$location\*.zip,$location\*.wixpdb,$location\*.msix | ForEach-Object { $file = $_.FullName Write-Verbose "Copying $file to $destination" -verbose Copy-Item -Path $file -Destination "$destination\" -Force diff --git a/tools/releaseBuild/azureDevOps/templates/upload.yml b/tools/releaseBuild/azureDevOps/templates/upload.yml index 5bc36404e5..2d965c434a 100644 --- a/tools/releaseBuild/azureDevOps/templates/upload.yml +++ b/tools/releaseBuild/azureDevOps/templates/upload.yml @@ -2,6 +2,7 @@ parameters: architecture: x86 version: 6.2.0 msi: yes + msix: yes steps: - template: upload-final-results.yml @@ -34,3 +35,19 @@ steps: storage: '$(StorageAccount)' ContainerName: '$(AzureVersion)' condition: and(succeeded(), eq(variables['Build.Reason'], 'Manual')) + +- template: upload-final-results.yml + parameters: + artifactPath: $(Build.StagingDirectory)\signedPackages + artifactFilter: PowerShell-${{ parameters.version }}-win-${{ parameters.architecture }}.msix + condition: and(succeeded(), eq('${{ parameters.msix }}', 'yes')) + +- task: AzureFileCopy@1 + displayName: 'upload signed msix to Azure - ${{ parameters.architecture }}' + inputs: + SourcePath: '$(Build.StagingDirectory)\signedPackages\PowerShell-${{ parameters.version }}-win-${{ parameters.architecture }}.msix' + azureSubscription: '$(AzureFileCopySubscription)' + Destination: AzureBlob + storage: '$(StorageAccount)' + ContainerName: '$(AzureVersion)' + condition: and(succeeded(), eq('${{ parameters.msix }}', 'yes'), eq(variables['Build.Reason'], 'Manual')) diff --git a/tools/releaseBuild/azureDevOps/templates/windows-package-signing.yml b/tools/releaseBuild/azureDevOps/templates/windows-package-signing.yml index 1397bf6848..da05a52d04 100644 --- a/tools/releaseBuild/azureDevOps/templates/windows-package-signing.yml +++ b/tools/releaseBuild/azureDevOps/templates/windows-package-signing.yml @@ -34,7 +34,14 @@ jobs: continueOnError: true - powershell: | - tools/releaseBuild/generatePackgeSigning.ps1 -AuthenticodeFiles "$(System.ArtifactsDirectory)\signed\PowerShell-$(Version)-win-x64.msi","$(System.ArtifactsDirectory)\signed\PowerShell-$(Version)-win-x86.msi" -path "$(System.ArtifactsDirectory)\package.xml" + $authenticodefiles = @( + "$(System.ArtifactsDirectory)\signed\PowerShell-$(Version)-win-x64.msi" + "$(System.ArtifactsDirectory)\signed\PowerShell-$(Version)-win-x86.msi" + "$(System.ArtifactsDirectory)\signed\PowerShell-$(Version)-win-x64.msix" + "$(System.ArtifactsDirectory)\signed\PowerShell-$(Version)-win-arm32.msix" + "$(System.ArtifactsDirectory)\signed\PowerShell-$(Version)-win-arm64.msix" + ) + tools/releaseBuild/generatePackgeSigning.ps1 -AuthenticodeFiles $authenticodeFiles -path "$(System.ArtifactsDirectory)\package.xml" displayName: 'Generate Package Signing Xml' - powershell: | @@ -56,6 +63,7 @@ jobs: parameters: architecture: x86 version: $(version) + msix: no - template: upload.yml parameters: @@ -79,6 +87,7 @@ jobs: architecture: fxdependent version: $(version) msi: no + msix: no - task: securedevelopmentteam.vss-secure-development-tools.build-task-antimalware.AntiMalware@3 displayName: 'Run Defender Scan' diff --git a/tools/releaseBuild/build.json b/tools/releaseBuild/build.json index 1584bf6611..a2a31c5bf3 100644 --- a/tools/releaseBuild/build.json +++ b/tools/releaseBuild/build.json @@ -152,7 +152,7 @@ ], "DockerImageName": "ps-winsrvcore", "BinaryBucket": "signed", - "ArtifactsExpected": 3, + "ArtifactsExpected": 4, "EnableFeature": [ "ArtifactAsFolder" ] }, { @@ -190,7 +190,7 @@ ], "DockerImageName": "ps-winsrvcore", "BinaryBucket": "signed", - "ArtifactsExpected": 1, + "ArtifactsExpected": 2, "EnableFeature": [ "ArtifactAsFolder" ] }, { @@ -209,7 +209,7 @@ ], "DockerImageName": "ps-winsrvcore", "BinaryBucket": "signed", - "ArtifactsExpected": 1, + "ArtifactsExpected": 2, "EnableFeature": [ "ArtifactAsFolder" ] }, {