-
Notifications
You must be signed in to change notification settings - Fork 42
/
Invoke-GitHubReleaseFetcher.ps1
204 lines (160 loc) · 9.13 KB
/
Invoke-GitHubReleaseFetcher.ps1
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
####################################
# Invoke-GitHubReleaseFetcher.ps1 #
####################################
# Version: 1.2.0
# Last Modified: 26/10/2022
# Author: Jack Tracey
# Source: https://github.com/jtracey93/PublicScripts/blob/master/GitHub/PowerShell/Invoke-GitHubReleaseFetcher.ps1
<#
.SYNOPSIS
Checks for the releases of a GitHub repository and downloads the latest release or all releases and pulls it into a specified directory, one for each version.
.DESCRIPTION
Checks for the releases of a GitHub repository and downloads the latest release or all releases and pulls it into a specified directory, one for each version.
.EXAMPLE
# Sync only latest release to PWD and keep only "version.json" file and "infra-as-code" directory (recursively)
$keepThese = @("version.json", "infra-as-code")
./Invoke-GitHubReleaseFetcher.ps1 -githubRepoUrl "https://github.com/Azure/ALZ-Bicep" -directoryAndFilesToKeep $keepThese
# Sync only all releases to PWD and keep only "version.json" file and "infra-as-code" directory (recursively)
$keepThese = @("version.json", "infra-as-code")
./Invoke-GitHubReleaseFetcher.ps1 -githubRepoUrl "https://github.com/Azure/ALZ-Bicep" -syncAllReleases:$true -directoryAndFilesToKeep $keepThese
.NOTES
# Release notes 25/10/2021 - V1.0.0:
- Initial release.
# Release notes 26/10/2021 - V1.1.0:
- Add support to move all extracted contents to release directories if $directoryAndFilesToKeep is not specified or is a empty array (which is the default).
# Release notes 30/10/2021 - V1.2.0:
- Add missing if condition to stop all files being added regardless of what is passed into `directoryAndFilesToKeep`.
#>
# Check for pre-reqs
#Requires -PSEdition Core
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingWriteHost", "", Justification = "Required for colour outputs")]
[CmdletBinding()]
param (
#Added this back into parameters as error occurs if multiple tenants are found when using Get-AzTenant
[Parameter(Mandatory = $true, Position = 1, HelpMessage = "Please the provide the full URL of the GitHub repository you wish to check for the latest release.")]
[string]
$githubRepoUrl,
[Parameter(Mandatory = $false, Position = 2, HelpMessage = "Sync all releases from the specified GitHub repository. Defaults to false.")]
[bool]
$syncAllReleases = $false,
[Parameter(Mandatory = $false, Position = 3, HelpMessage = "The directory to download the releases to. Defaults to the current directory.")]
[string]
$directoryForReleases = "$PWD/releases",
[Parameter(Mandatory = $false, Position = 4, HelpMessage = "An array of strings contianing the paths to the directories or files that you wish to keep when downloading and extracting from the releases.")]
[array]
$directoryAndFilesToKeep = @()
)
# Start timer
$StopWatch = New-Object -TypeName System.Diagnostics.Stopwatch
$StopWatch.Start()
# Split Repo URL into parts
$repoOrgPlusRepo = $githubRepoUrl.Split("/")[-2..-1] -join "/"
# Get releases on repo
$repoReleasesUrl = "https://api.github.com/repos/$repoOrgPlusRepo/releases"
$allRepoReleases = Invoke-RestMethod $repoReleasesUrl
Write-Host ""
Write-Host "=====> Checking for releases on GitHub Repo: $repoOrgPlusRepo" -ForegroundColor Cyan
Write-Host ""
Write-Host "=====> All available releases on GitHub Repo: $repoOrgPlusRepo" -ForegroundColor Cyan
$allRepoReleases | Select-Object name, tag_name, published_at, prerelease, draft, html_url | Format-Table -AutoSize
# Get latest release on repo
$latestRepoRelease = $allRepoReleases | Where-Object { $_.prerelease -eq $false } | Where-Object { $_.draft -eq $false } | Sort-Object -Descending published_at | Select-Object -First 1
Write-Host ""
Write-Host "=====> Latest available release on GitHub Repo: $repoOrgPlusRepo" -ForegroundColor Cyan
$latestRepoRelease | Select-Object name, tag_name, published_at, prerelease, draft, html_url | Format-Table -AutoSize
# Check if directory exists
Write-Host ""
Write-Host "=====> Checking if directory for releases exists: $directoryForReleases" -ForegroundColor Cyan
if (!(Test-Path $directoryForReleases)) {
Write-Host ""
Write-Host "Directory does not exist for releases, will now create: $directoryForReleases" -ForegroundColor Yellow
New-Item -ItemType Directory -Path $directoryForReleases
}
# Pull all releases into directories
if ($syncAllReleases -eq $true) {
Write-Host ""
Write-Host "=====> Syncing all releases of $repoOrgPlusRepo into $directoryForReleases" -ForegroundColor Cyan
foreach ($release in $allRepoReleases) {
$releaseDirectory = "$directoryForReleases/$($release.tag_name)"
Write-Host ""
Write-Host "===> Checking if directory for release version exists: $releaseDirectory" -ForegroundColor Cyan
if (!(Test-Path $releaseDirectory)) {
Write-Host ""
Write-Host "Directory does not exist for release $($release.tag_name), will now create: $releaseDirectory" -ForegroundColor Yellow
New-Item -ItemType Directory -Path $releaseDirectory
}
Write-Host ""
Write-Host "===> Checking if any content exists inside of $releaseDirectory" -ForegroundColor Cyan
$contentInReleaseDirectory = Get-ChildItem -Path $releaseDirectory -Recurse -ErrorAction SilentlyContinue
if ($null -eq $contentInReleaseDirectory) {
Write-Host ""
Write-Host "===> Pulling and extracting release $($release.tag_name) into $releaseDirectory" -ForegroundColor Cyan
New-Item -ItemType Directory -Path "$releaseDirectory/tmp"
Invoke-WebRequest -Uri "https://github.com/$repoOrgPlusRepo/archive/refs/tags/$($release.tag_name).zip" -OutFile "$releaseDirectory/tmp/$($release.tag_name).zip"
Expand-Archive -Path "$releaseDirectory/tmp/$($release.tag_name).zip" -DestinationPath "$releaseDirectory/tmp/extracted"
$extractedSubFolder = Get-ChildItem -Path "$releaseDirectory/tmp/extracted" -Directory
if ($null -ne $directoryAndFilesToKeep) {
foreach ($path in $directoryAndFilesToKeep) {
Write-Host ""
Write-Host "===> Moving $path into $releaseDirectory." -ForegroundColor Cyan
Move-Item -Path "$($extractedSubFolder.FullName)/$($path)" -Destination "$releaseDirectory" -ErrorAction SilentlyContinue
}
}
if ($null -eq $directoryAndFilesToKeep) {
Write-Host ""
Write-Host "===> Moving all extracted contents into $releaseDirectory." -ForegroundColor Cyan
Move-Item -Path "$($extractedSubFolder.FullName)/*" -Destination "$releaseDirectory" -ErrorAction SilentlyContinue
}
Remove-Item -Path "$releaseDirectory/tmp" -Force -Recurse
}
else {
Write-Host ""
Write-Host "===> Content already exists in $releaseDirectory. Skipping" -ForegroundColor Yellow
}
}
}
if ($syncAllReleases -eq $false) {
Write-Host ""
Write-Host "=====> Syncing latest release $($latestRepoRelease.tag_name) only of $repoOrgPlusRepo into $directoryForReleases" -ForegroundColor Cyan
$releaseDirectory = "$directoryForReleases/$($latestRepoRelease.tag_name)"
Write-Host ""
Write-Host "===> Checking if directory for release version exists: $releaseDirectory" -ForegroundColor Cyan
if (!(Test-Path $releaseDirectory)) {
Write-Host ""
Write-Host "Directory does not exist for release $($latestRepoRelease.tag_name), will now create: $releaseDirectory" -ForegroundColor Yellow
New-Item -ItemType Directory -Path $releaseDirectory
}
Write-Host ""
Write-Host "===> Checking if any content exists inside of $releaseDirectory" -ForegroundColor Cyan
$contentInReleaseDirectory = Get-ChildItem -Path $releaseDirectory -Recurse -ErrorAction SilentlyContinue
if ($null -eq $contentInReleaseDirectory) {
Write-Host ""
Write-Host "===> Pulling and extracting release $($latestRepoRelease.tag_name) into $releaseDirectory" -ForegroundColor Cyan
New-Item -ItemType Directory -Path "$releaseDirectory/tmp"
Invoke-WebRequest -Uri "https://github.com/$repoOrgPlusRepo/archive/refs/tags/$($latestRepoRelease.tag_name).zip" -OutFile "$releaseDirectory/tmp/$($latestRepoRelease.tag_name).zip"
Expand-Archive -Path "$releaseDirectory/tmp/$($latestRepoRelease.tag_name).zip" -DestinationPath "$releaseDirectory/tmp/extracted"
$extractedSubFolder = Get-ChildItem -Path "$releaseDirectory/tmp/extracted" -Directory
if ($null -ne $directoryAndFilesToKeep) {
foreach ($path in $directoryAndFilesToKeep) {
Write-Host ""
Write-Host "===> Moving $path into $releaseDirectory." -ForegroundColor Cyan
Move-Item -Path "$($extractedSubFolder.FullName)/$($path)" -Destination "$releaseDirectory" -ErrorAction SilentlyContinue
}
}
if ($null -eq $directoryAndFilesToKeep) {
Write-Host ""
Write-Host "===> Moving all extracted contents into $releaseDirectory." -ForegroundColor Cyan
Move-Item -Path "$($extractedSubFolder.FullName)/*" -Destination "$releaseDirectory" -ErrorAction SilentlyContinue
}
Remove-Item -Path "$releaseDirectory/tmp" -Force -Recurse
}
else {
Write-Host ""
Write-Host "===> Content already exists in $releaseDirectory. Skipping" -ForegroundColor Yellow
}
}
# Stop timer
$StopWatch.Stop()
# Display timer output as table
Write-Host "Time taken to complete task:" -ForegroundColor Yellow
$StopWatch.Elapsed | Format-Table