1+ param (
2+ [string ]$VersionFilter , # Filter by version (e.g. '3', '4.0', '5.0.2').
3+ [string ]$DistributionFilter , # Filter by image distribution (e.g. 'bookworm', 'bullseye', 'jammy').
4+
5+ [string ]$TestFilter # Filter by test name (e.g., 'FIREBIRD_USER_can_create_user'). Used only in the 'Test' task.
6+ )
7+
18#
29# Globals
310#
@@ -23,24 +30,11 @@ function Expand-Template([Parameter(ValueFromPipeline = $true)]$Template) {
2330 $regex.Replace ($Template , $evaluator )
2431}
2532
26- function Copy-TemplateItem ([string ]$Path , [string ]$Destination , [ switch ] $Force ) {
33+ function Copy-TemplateItem ([string ]$Path , [string ]$Destination ) {
2734 if (Test-Path $Destination ) {
28- # File already exists.
29-
30- if ($Force ) {
31- # With -Force: Overwrite.
32- $outputFile = Get-Item $Destination
33- $outputFile | Set-ItemProperty - Name IsReadOnly - Value $false
34- } else {
35- # Without -Force: Nothing to do.
36- return
37- }
38- }
39-
40-
41- if ( (-not $Force ) -and (Test-Path $Destination ) ) {
42- # File already exists. Ignore.
43- return
35+ # File already exists: Remove readonly flag (if set).
36+ $outputFile = Get-Item $Destination
37+ $outputFile | Set-ItemProperty - Name IsReadOnly - Value $false
4438 }
4539
4640 # Add header
@@ -229,30 +223,59 @@ task Update-Readme {
229223 }
230224 }
231225
232- Copy-TemplateItem " ./src/README.md.template" ' ./README.md' - Force
226+ Copy-TemplateItem " ./src/README.md.template" ' ./README.md'
233227}
234228
235- # Synopsis: Invoke preprocessor to generate images sources from "assets.json".
236- task Prepare {
237- # Clear/create output folder
229+ # Synopsis: Clean up the output folder.
230+ task Clean {
238231 Remove-Item - Path $outputFolder - Recurse - Force - ErrorAction SilentlyContinue
232+ }
233+
234+ # Synopsis: Load the assets from "assets.json", optionally filtering it by command-line parameters.
235+ task FilteredAssets {
236+ $result = Get-Content - Raw - Path ' .\assets.json' | ConvertFrom-Json
237+
238+ # Filter assets by command-line arguments
239+ if ($VersionFilter ) {
240+ $result = $result | Where-Object { $_.version -like " $VersionFilter *" }
241+ }
242+
243+ if ($DistributionFilter ) {
244+ $result = $result | Where-Object { $_.tags .$DistributionFilter -ne $null } |
245+ # Remove tags that do not match the distribution filter
246+ Select-Object - Property ' version' , ' releases' , @ {Name = ' tags' ; Expression = { [PSCustomObject ]@ { " $DistributionFilter " = $_.tags .$DistributionFilter } } }
247+ }
248+
249+ if (-not $result ) {
250+ Write-Error " No assets found matching the specified filters."
251+ exit 1
252+ }
253+
254+ $script :assets = $result
255+ }
256+
257+ # Synopsis: Invoke preprocessor to generate the image source files (can be filtered using command-line options).
258+ task Prepare FilteredAssets, {
259+ # Create output folders if they do not exist
239260 New-Item - ItemType Directory $outputFolder - Force > $null
240261 New-Item - ItemType Directory (Join-Path $outputFolder ' logs' ) - Force > $null
241262
242263 # For each asset
243- $assets = Get-Content - Raw - Path ' .\assets.json' | ConvertFrom-Json
244264 $assets | ForEach-Object {
245265 $asset = $_
246266
247267 $version = [version ]$asset.version
248268 $versionFolder = Join-Path $outputFolder $version
249269 New-Item - ItemType Directory $versionFolder - Force > $null
250270
251- # For each image
271+ # For each tag
252272 $asset.tags | Get-Member - MemberType NoteProperty | ForEach-Object {
253- $image = $_.Name
273+ $distribution = $_.Name
274+ $distributionFolder = Join-Path $versionFolder $distribution
275+ New-Item - ItemType Directory $distributionFolder - Force > $null
254276
255- $THasArchARM64 = ($asset.releases.arm64.url -ne $null -and $image -ne ' bullseye' -and $image -ne ' jammy' ?
277+ # Set variables for the template
278+ $THasArchARM64 = ($asset.releases.arm64.url -ne $null -and $distribution -ne ' bullseye' -and $distribution -ne ' jammy' ?
256279 ' $true' : ' $false' )
257280
258281 $TUrlArchAMD64 = $asset.releases.amd64.url
@@ -264,55 +287,80 @@ task Prepare {
264287 $TMajor = $version.Major
265288 $TImageVersion = $version
266289
267- $TImageTags = $asset.tags .$image
290+ $TImageTags = $asset.tags .$distribution
268291 if ($TImageTags ) {
269292 # https://stackoverflow.com/a/73073678
270293 $TImageTags = " '{0}'" -f ($TImageTags -join " ', '" )
271294 }
272295
273- $variantFolder = Join-Path $versionFolder $image
274- New-Item - ItemType Directory $variantFolder - Force > $null
275-
276- Copy-TemplateItem " ./src/Dockerfile.$image .template" " $variantFolder /Dockerfile"
277- Copy-Item ' ./src/entrypoint.sh' $variantFolder
278- Copy-TemplateItem " ./src/image.build.ps1.template" " $variantFolder /image.build.ps1"
279- Copy-Item ' ./src/image.tests.ps1' $variantFolder
296+ # Render templates into the distribution folder
297+ Copy-TemplateItem " ./src/Dockerfile.$distribution .template" " $distributionFolder /Dockerfile"
298+ Copy-Item ' ./src/entrypoint.sh' $distributionFolder
299+ Copy-TemplateItem " ./src/image.build.ps1.template" " $distributionFolder /image.build.ps1"
300+ Copy-Item ' ./src/image.tests.ps1' $distributionFolder
280301 }
281302 }
282303}
283304
284- # Synopsis: Build all docker images.
305+ # Synopsis: Build all docker images (can be filtered using command-line options) .
285306task Build Prepare, {
307+ $taskName = " Build"
308+
286309 $PSStyle.OutputRendering = ' PlainText'
287310 $logFolder = Join-Path $outputFolder ' logs'
288- $builds = Get-ChildItem " $outputFolder /**/image.build.ps1" - Recurse | ForEach-Object {
289- $version = $_.Directory.Parent.Name
290- $variant = $_.Directory.Name
291- $taskName = " Build"
292- @ {
293- File = $_.FullName
294- Task = $taskName
295- Log = (Join-Path $logFolder " $taskName -$version -$variant .log" )
311+
312+ $builds = $assets | ForEach-Object {
313+ $asset = $_
314+
315+ $version = [version ]$asset.version
316+ $versionFolder = Join-Path $outputFolder $version
317+
318+ $asset.tags | Get-Member - MemberType NoteProperty | ForEach-Object {
319+ $distribution = $_.Name
320+ $distributionFolder = Join-Path $versionFolder $distribution
321+ @ {
322+ File = " $distributionFolder /image.build.ps1"
323+ Task = $taskName
324+ Log = " $logFolder /$taskName -$version -$distribution .log"
325+
326+ # Parameters passed to Invoke-Build
327+ Verbose = $PSCmdlet.MyInvocation.BoundParameters [" Verbose" ].IsPresent
328+ }
296329 }
297330 }
331+
298332 Build-Parallel $builds
299333}
300334
301- # Synopsis: Run all tests.
302- task Test {
335+ # Synopsis: Run all tests (can be filtered using command-line options).
336+ task Test FilteredAssets, {
337+ $taskName = " Test"
338+
303339 $PSStyle.OutputRendering = ' PlainText'
304340 $logFolder = Join-Path $outputFolder ' logs'
305- $builds = Get-ChildItem " $outputFolder /**/image.build.ps1" - Recurse | ForEach-Object {
306- $version = $_.Directory.Parent.Name
307- $variant = $_.Directory.Name
308- $taskName = " Test"
309- @ {
310- File = $_.FullName
311- Task = $taskName
312- Log = (Join-Path $logFolder " $taskName -$version -$variant .log" )
341+
342+ $tests = $assets | ForEach-Object {
343+ $asset = $_
344+
345+ $version = [version ]$asset.version
346+ $versionFolder = Join-Path $outputFolder $version
347+
348+ $asset.tags | Get-Member - MemberType NoteProperty | ForEach-Object {
349+ $distribution = $_.Name
350+ $distributionFolder = Join-Path $versionFolder $distribution
351+ @ {
352+ File = " $distributionFolder /image.build.ps1"
353+ Task = $taskName
354+ Log = " $logFolder /$taskName -$version -$distribution .log"
355+
356+ # Parameters passed to Invoke-Build
357+ Verbose = $PSCmdlet.MyInvocation.BoundParameters [" Verbose" ].IsPresent
358+ TestFilter = $TestFilter
359+ }
313360 }
314361 }
315- Build-Parallel $builds
362+
363+ Build-Parallel $tests
316364}
317365
318366# Synopsis: Publish all images.
0 commit comments