|
| 1 | +# Copyright (c) Microsoft Corporation. |
| 2 | +# Licensed under the MIT License. |
| 3 | +<# |
| 4 | + .SYNOPSIS |
| 5 | + Install the latest build of DSC from a GitHub Actions run |
| 6 | + .DESCRIPTION |
| 7 | + This script installs a build of DSC from the artifact generated by a GitHub Actions run. The |
| 8 | + artifact is retrieved as a `.zip` file containing a `.tar` archive with the required files. |
| 9 | + The script retrieves the artifacts, extracts the contents, and then installs them to the `dsc` |
| 10 | + folder in `LOCALAPPDATA`. |
| 11 | + You can override the installation directory with the `-InstallPath` parameter. |
| 12 | + By default, the script installs the artifact from the latest successful build on the `main` |
| 13 | + branch in the `PowerShell/DSC` repository. You can select a different branch with the `-Branch` |
| 14 | + parameter, a different repository with the `-Repo` parameter, and a specific run with the |
| 15 | + `-RunId` parameter. |
| 16 | + By default, the script removes the downloaded artifact archive and intermediary files and |
| 17 | + folders. Use the `-NoClean` parameter to skip this cleanup step if needed. |
| 18 | + This script requires the `gh` CLI and `tar` executable. If either tool isn't installed and |
| 19 | + available, the script throws an error. |
| 20 | + .PARAMETER InstallPath |
| 21 | + Defines the folder to install DSC to. Defaults to the `dsc` folder in `LOCALAPPDATA`. Define |
| 22 | + this value as the full path to an alternate location. The script will create the directory |
| 23 | + path if it doesn't already exist. |
| 24 | + .PARAMETER Branch |
| 25 | + Defines which branch to retrieve the build artifact from. Defaults to `main`. |
| 26 | + .PARAMETER Repo |
| 27 | + Defines the repository to retrieve the build artifact from. Defaults to `PowerShell/DSC`. |
| 28 | + Define this value with the user or organization followed by a forward slash and then the |
| 29 | + repository name, like `SomeUserName/DSC`. |
| 30 | + .PARAMETER RunId |
| 31 | + Defines a specific GitHub Action run to retrieve the build artifact from. When this parameter |
| 32 | + isn't specified, the script retrieves the build artifact from the latest successful build |
| 33 | + agains the specified branch and repository. |
| 34 | + .PARAMETER NoClean |
| 35 | + By default, the script deletes the downloaded artifact and intermediary files and folders after |
| 36 | + installing DSC to the specified path. Use this parameter to prevent the script from removing |
| 37 | + these files and folders if needed. |
| 38 | +#> |
| 39 | +[cmdletbinding()] |
| 40 | +param( |
| 41 | + [string] |
| 42 | + $InstallPath = [System.IO.Path]::combine($env:LOCALAPPDATA, "dsc"), |
| 43 | + |
| 44 | + [string] |
| 45 | + $Branch = 'main', |
| 46 | + |
| 47 | + [ValidatePattern('^\w+\/\w+$')] |
| 48 | + [string] |
| 49 | + $Repo = 'PowerShell/DSC', |
| 50 | + |
| 51 | + [string] |
| 52 | + $RunId, |
| 53 | + |
| 54 | + [switch] |
| 55 | + $NoClean |
| 56 | +) |
| 57 | +begin { |
| 58 | + [string[]]$missing = @() |
| 59 | + if (-not (Get-Command 'gh' -ErrorAction SilentlyContinue)) { |
| 60 | + $missing += 'gh' |
| 61 | + } |
| 62 | + if (-not (Get-Command 'tar' -ErrorAction SilentlyContinue)) { |
| 63 | + $missing += 'tar' |
| 64 | + } |
| 65 | + if ($missing.Count -gt 0) { |
| 66 | + throw (@( |
| 67 | + "This script requires the 'gh' CLI and 'tar' executable." |
| 68 | + 'Please install the missing tools before invoking the script again:' |
| 69 | + "'$($missing -join "', '")'" |
| 70 | + ) -join ' ') |
| 71 | + } |
| 72 | + if ([string]::IsNullOrEmpty($RunId)) { |
| 73 | + $latestRunParameters = @( |
| 74 | + '-R', $Repo |
| 75 | + '--branch', $Branch |
| 76 | + '--workflow', 'rust' |
| 77 | + '--status', 'success' |
| 78 | + '-L', 1 |
| 79 | + '--json', 'databaseId' |
| 80 | + '-q', '.[0].databaseId' |
| 81 | + ) |
| 82 | + $RunId = & gh run list @latestRunParameters |
| 83 | + if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrEmpty($RunId)) { |
| 84 | + throw "Unable to find a successful build to install from" |
| 85 | + } |
| 86 | + } |
| 87 | + $tmpDir = [System.IO.Path]::combine( |
| 88 | + [System.IO.Path]::GetTempPath(), |
| 89 | + [System.IO.Path]::GetRandomFileName() |
| 90 | + ) |
| 91 | + $installationFiles = Join-Path -Path $tmpDir -ChildPath 'bin' -AdditionalChildPath 'debug' |
| 92 | + $dscExe = Join-Path $InstallPath "dsc.exe" |
| 93 | +} |
| 94 | +process { |
| 95 | + $ErrorActionPreference = 'Stop' |
| 96 | + #region Download the artifact |
| 97 | + $downloadArtifactParams = @( |
| 98 | + '-R', $Repo |
| 99 | + $RunId |
| 100 | + '-n', "$platform-bin" |
| 101 | + "--dir", $tmpDir |
| 102 | + ) |
| 103 | + gh run download @downloadArtifactParams |
| 104 | + if ($LASTEXITCODE -ne 0) { |
| 105 | + throw "Unable to download artifact" |
| 106 | + } |
| 107 | + #endregion Download the artifact |
| 108 | + #region Expand the tar file |
| 109 | + $tar = Get-ChildItem -Path $tmpDir | Select-Object -First 1 |
| 110 | + if ($null -eq $tar) { |
| 111 | + throw "Failed to find downloaded artifact" |
| 112 | + } |
| 113 | + tar -xf $tar.FullName -C $tmpDir |
| 114 | + if ($LASTEXITCODE -ne 0) { |
| 115 | + throw "Unable to extract the tar file from the artifact" |
| 116 | + } |
| 117 | + #endregion Expand the tar file |
| 118 | + #region Move extracted files to the install directory |
| 119 | + # Create the install directory if it doesn't exist |
| 120 | + if (-not (Test-Path -Path $InstallPath -PathType Container)) { |
| 121 | + $null = New-Item -ItemType Directory -Force -Path $InstallPath |
| 122 | + } |
| 123 | + Move-Item -Path "$installationFiles/*" -Destination $InstallPath -Force -ErrorAction Ignore |
| 124 | + #endregion Copy extracted files to the install directory |
| 125 | + #region Retrieve and display version information |
| 126 | + $versionStdout = & $dscExe --version; if(!$?) { throw } |
| 127 | + $version = $versionStdout -replace 'dsc ', '' |
| 128 | + Write-Information "Installed DSC CLI $version from https://github.com/$Repo/actions/runs/$RunId to $InstallPath" |
| 129 | + #endregion Retrieve and display version information |
| 130 | + Write-Information "Make sure to add $InstallPath to your PATH environment variable to use the 'dsc' command." |
| 131 | +} |
| 132 | +clean { |
| 133 | + if (-not $NoClean) { |
| 134 | + Remove-Item $tmpDir -Recurse |
| 135 | + } |
| 136 | +} |
0 commit comments