-
Notifications
You must be signed in to change notification settings - Fork 160
220 lines (184 loc) · 11.5 KB
/
Build AppControl Manager MSIX Package.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
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: |
# Retrieve the latest Winget 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 links to the latest Winget release assets
[string]$WingetURL = $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 = $LatestRelease.assets.browser_download_url | Where-Object -FilterScript { $_.EndsWith('DesktopAppInstaller_Dependencies.zip') } | Select-Object -First 1
[hashtable]$Downloads = @{
# 'Winget.msixbundle' = 'https://aka.ms/getwinget' This is updated slower than the GitHub release
'DesktopAppInstaller_Dependencies.zip' = $LatestWingetReleaseDependenciesZipURL
'Winget.msixbundle' = $WingetURL
'License1.xml' = $WingetLicense
}
$Downloads.GetEnumerator() | ForEach-Object -Parallel {
Invoke-RestMethod -Uri $_.Value -OutFile $_.Key
}
Expand-Archive -Path 'DesktopAppInstaller_Dependencies.zip' -DestinationPath .\ -Force
# Get the paths to all of the dependencies
[string[]]$DependencyPaths = (Get-ChildItem -Path .\x64 -Filter '*.appx' -File -Force).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 source update
winget install --id Microsoft.DotNet.SDK.9 --exact --accept-package-agreements --accept-source-agreements --uninstall-previous --force --source winget
winget install --id Microsoft.VisualStudio.2022.BuildTools --exact --accept-package-agreements --accept-source-agreements --uninstall-previous --force --source winget
winget install --id Microsoft.WindowsSDK.10.0.26100 --exact --accept-package-agreements --accept-source-agreements --uninstall-previous --force --source winget
# https://github.com/microsoft/winget-cli/issues/1705
winget install --id Microsoft.AppInstaller --exact --accept-package-agreements --accept-source-agreements --uninstall-previous --force --source winget
winget install --id Microsoft.VCRedist.2015+.x64 --exact --accept-package-agreements --accept-source-agreements --uninstall-previous --force --source winget
- name: Building the AppControl Manager
# https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-build
# https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-command-line-reference
# https://learn.microsoft.com/en-us/visualstudio/msbuild/common-msbuild-project-properties
run: dotnet build "AppControl Manager/AppControl Manager.sln" --configuration Release --verbosity minimal /p:Platform=x64
- name: Generating the MSIX Package
run: dotnet msbuild "AppControl Manager/AppControl Manager.sln" /p:Configuration=Release /p:AppxPackageDir="MSIXOutput\" /p:GenerateAppxPackageOnBuild=true /p:Platform=x64
- name: Capturing the Generated MSIX file Path
shell: pwsh
run: |
[string]$MSIXPath = (Get-ChildItem -File -Path '.\AppControl Manager\MSIXOutput\AppControl Manage*\AppControl Manager*.msix').FullName
[string]$MSIXName = (Get-ChildItem -File -Path '.\AppControl Manager\MSIXOutput\AppControl Manage*\AppControl Manager*.msix').Name
[XML]$CSProjXMLContent = Get-Content -Path '.\AppControl Manager\AppControl Manager.csproj' -Force
[string]$MSIXVersion = $CSProjXMLContent.Project.PropertyGroup.FileVersion
[string]$MSIXVersion = $MSIXVersion.Trim() # It would have trailing whitespaces
if ([string]::IsNullOrWhiteSpace($MSIXPath) -or [string]::IsNullOrWhiteSpace($MSIXName) -or [string]::IsNullOrWhiteSpace($MSIXVersion)) { throw "Couldn't find the generated MSIX package" }
# Write the MSIXPath, MSIXName and MSIXVersion 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"
Add-Content -Path $env:GITHUB_ENV -Value "MSIX_VERSION=$MSIXVersion"
- 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
Add-Content -Path $env:GITHUB_ENV -Value "DRAFT_RELEASE_ID=$DRAFT_RELEASE_ID"
Add-Content -Path $env:GITHUB_ENV -Value "DRAFT_RELEASE_TAG=$DRAFT_RELEASE_TAG"
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: |
[string]$DraftReleaseId = $env:DRAFT_RELEASE_ID
[string]$FilePath = "${{ env.MSIX_PATH }}"
[string]$FileName = "${{ env.MSIX_NAME }}"
[string]$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: |
[string]$DraftReleaseId = $env:DRAFT_RELEASE_ID
[string]$FilePath = "HardenWindowsSecurityRepoSBOM.spdx"
[string]$FileName = "HardenWindowsSecurityRepoSBOM.spdx"
[string]$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 Version via Pull Request
shell: pwsh
env:
GH_TOKEN: ${{ github.token }}
run: |
[string]$MSIXName = "${{ env.MSIX_NAME }}"
# Spaces in files added to the GitHub assets will be replaced with dots, so we need to do the same when constructing the download link
[string]$AdjustedMSIXName = $MSIXName.Replace('AppControl Manager', 'AppControl.Manager')
[string]$DRAFT_RELEASE_TAG = "${{ env.DRAFT_RELEASE_TAG }}"
[string]$GitHubRepository = "${{ github.repository }}"
[string]$MSIX_VERSION = "${{ env.MSIX_VERSION }}"
# Construct the download URL using the draft release tag and MSIX file name
[string]$DownloadURL = "https://github.com/$GitHubRepository/releases/download/$DRAFT_RELEASE_TAG/$AdjustedMSIXName"
# Path to the files that will be updated
[string]$DownloadURLFilePath = '.\AppControl Manager\DownloadURL.txt'
[string]$VersionFilePath = '.\AppControl Manager\version.txt'
# Update the file content with the new URL
Set-Content -Path $DownloadURLFilePath -Value $DownloadURL -Force
Write-Host -Object "Updated DownloadURL.txt with download URL: $DownloadURL"
Set-Content -Path $VersionFilePath -Value $MSIX_VERSION -Force
Write-Host -Object "Updated version.txt with version: $MSIX_VERSION"
# 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, making sure branch name has valid characters
[string]$NewBranchName = 'AppControl-Manager-DownloadLink-Version-Update'
git checkout -b $NewBranchName
[string]$CommitMessageAndPRTitle = "AppControl-Manager-DownloadLink-Version-Update-Version-$MSIX_VERSION"
# Stage and commit the change
git add $DownloadURLFilePath
git add $VersionFilePath
git commit -m $CommitMessageAndPRTitle
# Push the new branch to the remote repository
git push -u origin $NewBranchName
[string]$PRBody = @"
This PR updates DownloadURL.txt to
``````
$DownloadURL
``````
And version.txt to
``````
$MSIX_VERSION
``````
For the file: $AdjustedMSIXName
"@
# Create the pull request
gh pr create --title $CommitMessageAndPRTitle --body $PRBody --base main --label 'Automated 🤖' --assignee HotCakeX