Skip to content

Build AppControl Manager MSIX Package #14

Build AppControl Manager MSIX Package

Build AppControl Manager MSIX Package #14

name: Build AppControl Manager MSIX Package
permissions:
id-token: write
actions: read
contents: write
pull-requests: write
attestations: write
on:
workflow_dispatch:
jobs:
build:
runs-on: windows-latest
steps:
- name: Check out the repository code
uses: actions/checkout@v4
- name: Setting up and downloading Winget
shell: pwsh
run: |
# Set up URLs and retrieve Winget latest release information
[string]$WingetRepoURL = 'https://api.github.com/repos/microsoft/winget-cli/releases'
$WingetReleases = Invoke-RestMethod -Uri $WingetRepoURL
$LatestRelease = $WingetReleases | Select-Object -First 1
# Direct Winget package link from the latest release
[string]$WingetURL2 = $LatestRelease.assets.browser_download_url | Where-Object -FilterScript { $_.EndsWith('.msixbundle') } | Select-Object -First 1
[string]$WingetLicense = $LatestRelease.assets.browser_download_url | Where-Object -FilterScript { $_.EndsWith('License1.xml') } | Select-Object -First 1
[string]$LatestWingetReleaseDependenciesZipURL = "https://github.com/microsoft/winget-cli/releases/download/$($LatestRelease.tag_name)/DesktopAppInstaller_Dependencies.zip"
[hashtable]$Downloads = @{
'DesktopAppInstaller_Dependencies.zip' = $LatestWingetReleaseDependenciesZipURL
'Winget.msixbundle' = 'https://aka.ms/getwinget'
'License1.xml' = $WingetLicense
}
$Downloads.GetEnumerator() | ForEach-Object -Parallel {
$FileName = $_.Key
$URL = $_.Value
Invoke-RestMethod -Uri $URL -OutFile $FileName
}
Expand-Archive -Path 'DesktopAppInstaller_Dependencies.zip' -DestinationPath .\ -Force
[string[]]$DependencyPaths = (Get-ChildItem -Path .\x64 -Filter '*.appx' -File).FullName
Add-AppxProvisionedPackage -Online -PackagePath 'Winget.msixbundle' -DependencyPackagePath $DependencyPaths -LicensePath 'License1.xml'
# Add the dependency paths to the GitHub environment to be used in the next step
Add-Content -Path $env:GITHUB_ENV -Value "WINGET_DEPENDENCY1=$($DependencyPaths[0])"
Add-Content -Path $env:GITHUB_ENV -Value "WINGET_DEPENDENCY2=$($DependencyPaths[1])"
- name: Finishing setting up Winget
shell: powershell
run: |
Add-AppPackage -Path 'Winget.msixbundle' -DependencyPath "${{ env.WINGET_DEPENDENCY1 }}", "${{ env.WINGET_DEPENDENCY2 }}" -ForceTargetApplicationShutdown -ForceUpdateFromAnyVersion
# Add-AppPackage on Windows Server throws error so we use Windows PowerShell for this section.
- name: Installing the necessary programs
run: |
winget install --id Microsoft.DotNet.SDK.Preview --exact --accept-package-agreements --accept-source-agreements --uninstall-previous --force
winget install --id Microsoft.VisualStudio.2022.BuildTools --exact --accept-package-agreements --accept-source-agreements --uninstall-previous --force
winget install --id Microsoft.WindowsSDK.10.0.26100 --exact --accept-package-agreements --accept-source-agreements --uninstall-previous --force
winget install --id Microsoft.AppInstaller --exact --accept-package-agreements --accept-source-agreements --uninstall-previous --force
winget install --id Microsoft.VCRedist.2015+.x64 --exact --accept-package-agreements --accept-source-agreements --uninstall-previous --force
- name: Building the AppControl Manager
run: dotnet build "AppControl Manager/AppControl Manager.sln" --configuration Release --verbosity minimal
- name: Generating the MSIX Package
run: dotnet msbuild "AppControl Manager/AppControl Manager.sln" /p:Configuration=Release /p:AppxPackageDir="MSIXOutput\" /p:GenerateAppxPackageOnBuild=true
- name: Capturing the Generated MSIX file Path
shell: pwsh
run: |
[string]$MSIXPath = (Get-ChildItem -Path '.\AppControl Manager\MSIXOutput\AppControl Manage*\AppControl Manager*.msix').FullName
[string]$MSIXName = (Get-ChildItem -Path '.\AppControl Manager\MSIXOutput\AppControl Manage*\AppControl Manager*.msix').Name
if ([string]::IsNullOrWhiteSpace($MSIXPath)) { throw "Couldn't find the generated MSIX package" }
# Write the MSIXPath and MSIXName to GITHUB_ENV to set it as an environment variable for the entire workflow
Add-Content -Path $env:GITHUB_ENV -Value "MSIX_PATH=$MSIXPath"
Add-Content -Path $env:GITHUB_ENV -Value "MSIX_NAME=$MSIXName"
- name: Generating Artifact Attestation
uses: actions/attest-build-provenance@v1
with:
subject-path: ${{ env.MSIX_PATH }}
- name: Generating SBOM
uses: anchore/sbom-action@v0
with:
dependency-snapshot: true
upload-release-assets: false
upload-artifact: true
output-file: ./HardenWindowsSecurityRepoSBOM.spdx
artifact-name: HardenWindowsSecurityRepoSBOM.spdx
- name: Generating SBOM attestation
uses: actions/attest-sbom@v1
with:
subject-path: ${{ env.MSIX_PATH }}
sbom-path: ./HardenWindowsSecurityRepoSBOM.spdx
show-summary: true
- name: Finding the Latest Draft Release
id: find_draft_release
shell: pwsh
run: |
# Find the latest draft release via GitHub REST API
$Response = Invoke-RestMethod -Uri "https://api.github.com/repos/${{ github.repository }}/releases" -Headers @{ Authorization = "token ${{ secrets.GITHUB_TOKEN }}" }
$DraftRelease = $Response | Where-Object -FilterScript { $_.draft -eq $true } | Select-Object -First 1
if (!$DraftRelease) {
throw "No draft release found"
}
# Capture the draft release ID and tag
$DRAFT_RELEASE_ID = $DraftRelease.id
$DRAFT_RELEASE_TAG = $DraftRelease.tag_name
# Save both the release ID and tag to environment variables for later steps
Write-Output -InputObject "DRAFT_RELEASE_ID=$DRAFT_RELEASE_ID" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Force
Write-Output -InputObject "DRAFT_RELEASE_TAG=$DRAFT_RELEASE_TAG" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Force
Write-Host -Object "GitHub Draft ID: $DRAFT_RELEASE_ID"
Write-Host -Object "GitHub Draft Tag: $DRAFT_RELEASE_TAG"
- name: Uploading the MSIX Package to the Draft Release
shell: pwsh
run: |
$DraftReleaseId = $env:DRAFT_RELEASE_ID
$FilePath = "${{ env.MSIX_PATH }}"
$FileName = "${{ env.MSIX_NAME }}"
$uploadUrl = "https://uploads.github.com/repos/${{ github.repository }}/releases/$DraftReleaseId/assets?name=$FileName"
# Upload the package to the draft release
$Response = Invoke-RestMethod -Uri $uploadUrl -Method Put -InFile $FilePath -Headers @{
"Authorization" = "token ${{ secrets.GITHUB_TOKEN }}"
"Content-Type" = "application/octet-stream"
}
Write-Host -Object "Uploaded package to draft release: $Response.name"
- name: Uploading the SBOM file to the Draft Release
shell: pwsh
run: |
$DraftReleaseId = $env:DRAFT_RELEASE_ID
$FilePath = "HardenWindowsSecurityRepoSBOM.spdx"
$FileName = "HardenWindowsSecurityRepoSBOM.spdx"
$uploadUrl = "https://uploads.github.com/repos/${{ github.repository }}/releases/$DraftReleaseId/assets?name=$FileName"
$Response = Invoke-RestMethod -Uri $uploadUrl -Method Put -InFile $FilePath -Headers @{
"Authorization" = "token ${{ secrets.GITHUB_TOKEN }}"
"Content-Type" = "application/octet-stream"
}
Write-Host -Object "Uploaded the SBOM file to the draft release: $Response.name"
- name: Updating The MSIX Download Link and Creating Pull Request
shell: pwsh
run: |
# Construct the download URL using the draft release tag and MSIX file name
[string]$DownloadURL = "https://github.com/${{ github.repository }}/releases/download/${{ env.DRAFT_RELEASE_TAG }}/${{ env.MSIX_NAME }}"
# Path to the file that will be updated
[string]$FilePath = ".\AppControl Manager\DownloadURL.txt"
# Update the file content with the new URL
Set-Content -Path $FilePath -Value $DownloadURL -Force
Write-Host -Object "Updated DownloadURL.txt with download URL: $DownloadURL"
# Configure Git for committing changes
git config --global user.email '[email protected]'
git config --global user.name 'HotCakeX'
# Create a new branch for the pull request
[string]$NewBranch = "update-download-url-$([System.Guid]::NewGuid().ToString() -replace '-', '')"
git checkout -b $NewBranch
# Stage and commit the change
git add $FilePath
git commit -m "Update DownloadURL.txt with MSIX download link"
# Manual review of the PR for now
# git push -u origin $NewBranch
# Create the pull request with a label and assignee
gh pr create --title "AppControl Manager download link update" `
--body "This PR updates DownloadURL.txt with the latest MSIX download link for version ${{ env.MSIX_NAME }}." `
--base main `
--label "Automated 🤖" `
--assignee HotCakeX