-
Notifications
You must be signed in to change notification settings - Fork 180
Download installApps and installTestApps as part of "Download Project Dependencies" #2101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
aholstrup1
wants to merge
48
commits into
microsoft:main
Choose a base branch
from
aholstrup1:aholstrup/installApps_download
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+879
−28
Open
Changes from 14 commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
23ff383
Initial implementation
aholstrup1 abd86aa
Add PS5 compatibility
aholstrup1 a0b3ecd
Remove duplicate check
aholstrup1 2a2e1cf
Remove logic from Runpipeline
aholstrup1 323d90a
releasenotes
aholstrup1 e992e7f
Check secret exists
aholstrup1 37a1b20
handle empty sanitizedFileName
aholstrup1 840a612
Handle duplicate files
aholstrup1 3bbd0d1
Error message
aholstrup1 b0d5fa4
releasenotes
aholstrup1 15554dc
Use Invoke-CommandWithRetry
aholstrup1 c74fa44
Fix for how install apps is set
aholstrup1 1c2a9d3
Handling for .zip files
aholstrup1 7c2cc34
Add tests
aholstrup1 afab810
Merge branch 'main' of https://github.com/microsoft/al-go into aholst…
aholstrup1 0b446c0
Cleanup
aholstrup1 50b19d5
Import Github-Helper.psm1
aholstrup1 cc992ad
Add handling of local paths
aholstrup1 cc03d43
Make sure all app files are always copied to dependencies folder
aholstrup1 0ba2ae6
Update test
aholstrup1 25d5c24
Fix compatibility issue
aholstrup1 8995cc8
Fix test
aholstrup1 488057f
debugging
aholstrup1 7d393ce
Check if folder exists
aholstrup1 8f660fe
Better logging
aholstrup1 8c6e34e
Fix trailing whitespace and missing blank line
aholstrup1 4b9cf82
remove out folder
aholstrup1 697edbb
Change directory
aholstrup1 ff159c2
Suggestions batch 1
aholstrup1 324518c
suggestions batch 2
aholstrup1 0703fd4
Handling for missing secret
aholstrup1 f98b798
Merge branch 'main' of https://github.com/microsoft/al-go into aholst…
aholstrup1 291eb23
Update Actions/DownloadProjectDependencies/DownloadProjectDependencie…
aholstrup1 246de64
File name collisions
aholstrup1 68e6994
Add Parameter
aholstrup1 37c2a60
Merge branch 'main' of https://github.com/microsoft/al-go into aholst…
aholstrup1 ee0564c
Merge branch 'main' of https://github.com/microsoft/al-go into aholst…
aholstrup1 5bcb926
Suggestions
aholstrup1 b0e4718
Test-PathWithinWorkspace
aholstrup1 9419529
Harden Test-IsZipFile
aholstrup1 d97410d
test coverage
aholstrup1 5af1fde
Add a MaxDepth to Expand-ZipFileToAppFiles
aholstrup1 a86f485
-Raw
aholstrup1 5313313
Fix end-of-file newline in Github-Helper.psm1
aholstrup1 c71ad77
Fix wildcard path validation in Test-PathWithinWorkspace
aholstrup1 c4538c0
Cleanup
aholstrup1 efbbdfd
pre-commit
aholstrup1 bf76270
Merge branch 'main' of https://github.com/microsoft/al-go into aholst…
aholstrup1 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
154 changes: 154 additions & 0 deletions
154
Actions/DownloadProjectDependencies/DownloadProjectDependencies.psm1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,154 @@ | ||
| <# | ||
| .SYNOPSIS | ||
| Downloads a file from a URL to a specified download path. | ||
| .DESCRIPTION | ||
| Downloads a file from a URL to a specified download path. | ||
| It handles URL decoding and sanitizes the file name. | ||
| If the downloaded file is a zip file, it extracts the .app files from it. | ||
| .PARAMETER Url | ||
| The URL of the file to download. | ||
| .PARAMETER DownloadPath | ||
| The path where the file should be downloaded. | ||
| .OUTPUTS | ||
| An array of paths to the downloaded/extracted .app files. | ||
| #> | ||
| function Get-AppFilesFromUrl { | ||
| Param( | ||
| [string] $Url, | ||
| [string] $DownloadPath | ||
| ) | ||
| # Get the file name from the URL | ||
| $urlWithoutQuery = $Url.Split('?')[0].TrimEnd('/') | ||
| $rawFileName = [System.IO.Path]::GetFileName($urlWithoutQuery) | ||
| $decodedFileName = [Uri]::UnescapeDataString($rawFileName) | ||
| $decodedFileName = [System.IO.Path]::GetFileName($decodedFileName) | ||
|
|
||
| # Sanitize file name by removing invalid characters | ||
| $sanitizedFileName = $decodedFileName.Split([System.IO.Path]::getInvalidFileNameChars()) -join "" | ||
| $sanitizedFileName = $sanitizedFileName.Trim() | ||
|
|
||
| if ([string]::IsNullOrWhiteSpace($sanitizedFileName)) { | ||
| # Assume the file is an .app file if no valid name could be determined | ||
| $sanitizedFileName = "$([Guid]::NewGuid().ToString()).app" | ||
| } | ||
|
|
||
| # Get the final file path | ||
| $downloadedFile = Join-Path $DownloadPath $sanitizedFileName | ||
| if (Test-Path -LiteralPath $downloadedFile) { | ||
| OutputDebug -message "Overwriting existing file '$sanitizedFileName'. Multiple dependencies may resolve to the same filename." | ||
| } | ||
|
|
||
| # Download with retry logic | ||
| Invoke-CommandWithRetry -ScriptBlock { | ||
| Invoke-WebRequest -Method GET -UseBasicParsing -Uri $Url -OutFile $downloadedFile | Out-Null | ||
| } -RetryCount 3 -FirstDelay 5 -MaxWaitBetweenRetries 10 | ||
|
|
||
| # Check if the downloaded file is a zip file | ||
| $extension = [System.IO.Path]::GetExtension($downloadedFile).ToLowerInvariant() | ||
| if ($extension -eq '.zip') { | ||
| Write-Host "Extracting .app files from zip archive: $sanitizedFileName" | ||
|
|
||
Check noticeCode scanning / PSScriptAnalyzer Line has trailing whitespace Note
Line has trailing whitespace
|
||
| # Extract to runner temp folder | ||
| $extractPath = Join-Path $env:RUNNER_TEMP ([System.IO.Path]::GetFileNameWithoutExtension($sanitizedFileName)) | ||
| Expand-Archive -Path $downloadedFile -DestinationPath $extractPath -Force | ||
| Remove-Item -Path $downloadedFile -Force | ||
|
|
||
| # Find all .app files in the extracted folder and copy them to the download path | ||
| $appFiles = @() | ||
| foreach ($appFile in (Get-ChildItem -Path $extractPath -Filter '*.app' -Recurse)) { | ||
| $destFile = Join-Path $DownloadPath $appFile.Name | ||
| Copy-Item -Path $appFile.FullName -Destination $destFile -Force | ||
| $appFiles += $destFile | ||
| } | ||
|
|
||
| # Clean up the extracted folder | ||
| Remove-Item -Path $extractPath -Recurse -Force | ||
|
|
||
| if ($appFiles.Count -eq 0) { | ||
| throw "Zip archive '$sanitizedFileName' does not contain any .app files" | ||
| } | ||
| Write-Host "Found $($appFiles.Count) .app file(s) in zip archive" | ||
| return $appFiles | ||
| } | ||
|
|
||
| return @($downloadedFile) | ||
| } | ||
|
|
||
| <# | ||
| .SYNOPSIS | ||
| Downloads dependencies from URLs specified in installApps and installTestApps settings. | ||
| .DESCRIPTION | ||
| Reads the installApps and installTestApps arrays from the repository settings. | ||
| For each entry that is a URL (starts with http:// or https://): | ||
| - Resolves any secret placeholders in the format ${{ secretName }} by looking up the secret value | ||
| - Downloads the app file to the specified destination path | ||
| For entries that are not URLs (local paths), they are returned as-is. | ||
| .PARAMETER DestinationPath | ||
| The path where the app files should be downloaded. | ||
| .OUTPUTS | ||
| A hashtable with Apps and TestApps arrays containing the resolved local file paths. | ||
| #> | ||
| function Get-DependenciesFromInstallApps { | ||
| Param( | ||
| [string] $DestinationPath | ||
| ) | ||
|
|
||
| $settings = $env:Settings | ConvertFrom-Json | ConvertTo-HashTable | ||
|
|
||
| # ENV:Secrets is not set when running Pull_Request trigger | ||
| if ($env:Secrets) { | ||
| $secrets = $env:Secrets | ConvertFrom-Json | ConvertTo-HashTable | ||
| } | ||
| else { | ||
| $secrets = @{} | ||
| } | ||
|
|
||
| $install = @{ | ||
| "Apps" = @($settings.installApps) | ||
| "TestApps" = @($settings.installTestApps) | ||
| } | ||
|
|
||
| # Check if the installApps and installTestApps settings are empty | ||
| if (($settings.installApps.Count -eq 0) -and ($settings.installTestApps.Count -eq 0)) { | ||
aholstrup1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Write-Host "No installApps or installTestApps settings found." | ||
| return $install | ||
| } | ||
|
|
||
| # Replace secret names in install.apps and install.testApps and download files from URLs | ||
| foreach($list in @('Apps','TestApps')) { | ||
| $install."$list" = @($install."$list" | ForEach-Object { | ||
| $appFile = $_ | ||
|
|
||
| # If the app file is not a URL, return it as is | ||
| if ($appFile -notlike 'http*://*') { | ||
| Write-Host "install$($list) contains a local path: $appFile" | ||
| return $appFile | ||
| } | ||
|
|
||
| # Else, check for secrets in the URL and replace them | ||
| $appFileUrl = $appFile | ||
| $pattern = '.*(\$\{\{\s*([^}]+?)\s*\}\}).*' | ||
| if ($appFile -match $pattern) { | ||
| $secretName = $matches[2] | ||
| if (-not $secrets.ContainsKey($secretName)) { | ||
| throw "Setting: install$($list) references unknown secret '$secretName' in URL: $appFile" | ||
| } | ||
| $appFileUrl = $appFileUrl.Replace($matches[1],[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets."$secretName"))) | ||
| } | ||
|
|
||
| # Download the file (may return multiple .app files if it's a zip) | ||
| try { | ||
| Write-Host "Downloading from URL: $appFile" | ||
| $appFiles = Get-AppFilesFromUrl -Url $appFileUrl -DownloadPath $DestinationPath | ||
| } catch { | ||
| throw "Setting: install$($list) contains an inaccessible URL: $appFile. Error was: $($_.Exception.Message)" | ||
| } | ||
|
|
||
| return $appFiles | ||
| }) | ||
| } | ||
|
|
||
| return $install | ||
| } | ||
|
|
||
| Export-ModuleMember -Function Get-AppFilesFromUrl, Get-DependenciesFromInstallApps | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.