Skip to content

Adds filter options for version, distribution, and test name in build tasks. #31

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
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 60 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,12 +297,12 @@ More information:
## Prerequisites

- [Docker](https://docs.docker.com/engine/install/)
- [Powershell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-linux)
- [Powershell 7.5+](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-linux)
- [Invoke-Build](https://github.com/nightroman/Invoke-Build#install-as-module)



## Build
## Building

To generate the source files and build each image from [`assets.json`](assets.json) configuration file, run:

Expand All @@ -316,12 +316,69 @@ You can then check all created images with:
docker image ls firebirdsql/firebird
```

### Filtering builds

> You can filter builds by **version** or **distribution**:

```bash
# Build only Firebird 5.x images
Invoke-Build Build -VersionFilter "5"

# Build only specific version
Invoke-Build Build -VersionFilter "5.0.2"

# Build only bookworm distribution images
Invoke-Build Build -DistributionFilter "bookworm"

# Combine filters
Invoke-Build Build -VersionFilter "4" -DistributionFilter "jammy"
```


## Tests

## Testing

To run the test suite for each image, use:

```bash
Invoke-Build Test
```

### Filtering tests

You can filter tests by **version**, **distribution**, or a specific **test name**:

```bash
# Test only Firebird 4.x images
Invoke-Build Test -VersionFilter "4"

# Test only bullseye distribution images
Invoke-Build Test -DistributionFilter "bullseye"

# Run specific test
Invoke-Build Test -TestFilter "FIREBIRD_USER_can_create_user"

# Combine filters
Invoke-Build Test -VersionFilter "5" -DistributionFilter "noble"
```



## Maintenance tasks

The build script includes additional tasks dedicated to maintaining this project.

```bash
# Update assets.json from GitHub releases
Invoke-Build Update-Assets

# Update README.md from assets.json
Invoke-Build Update-Readme

# Regenerate source files
Invoke-Build Prepare

# Clean up generated files
Invoke-Build Clean
```

154 changes: 101 additions & 53 deletions firebird-docker.build.ps1
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
param(
[string]$VersionFilter, # Filter by version (e.g. '3', '4.0', '5.0.2').
[string]$DistributionFilter, # Filter by image distribution (e.g. 'bookworm', 'bullseye', 'jammy').

[string]$TestFilter # Filter by test name (e.g., 'FIREBIRD_USER_can_create_user'). Used only in the 'Test' task.
)

#
# Globals
#
Expand All @@ -23,24 +30,11 @@ function Expand-Template([Parameter(ValueFromPipeline = $true)]$Template) {
$regex.Replace($Template, $evaluator)
}

function Copy-TemplateItem([string]$Path, [string]$Destination, [switch]$Force) {
function Copy-TemplateItem([string]$Path, [string]$Destination) {
if (Test-Path $Destination) {
# File already exists.

if ($Force) {
# With -Force: Overwrite.
$outputFile = Get-Item $Destination
$outputFile | Set-ItemProperty -Name IsReadOnly -Value $false
} else {
# Without -Force: Nothing to do.
return
}
}


if ( (-not $Force) -and (Test-Path $Destination) ) {
# File already exists. Ignore.
return
# File already exists: Remove readonly flag (if set).
$outputFile = Get-Item $Destination
$outputFile | Set-ItemProperty -Name IsReadOnly -Value $false
}

# Add header
Expand Down Expand Up @@ -229,30 +223,59 @@ task Update-Readme {
}
}

Copy-TemplateItem "./src/README.md.template" './README.md' -Force
Copy-TemplateItem "./src/README.md.template" './README.md'
}

# Synopsis: Invoke preprocessor to generate images sources from "assets.json".
task Prepare {
# Clear/create output folder
# Synopsis: Clean up the output folder.
task Clean {
Remove-Item -Path $outputFolder -Recurse -Force -ErrorAction SilentlyContinue
}

# Synopsis: Load the assets from "assets.json", optionally filtering it by command-line parameters.
task FilteredAssets {
$result = Get-Content -Raw -Path '.\assets.json' | ConvertFrom-Json

# Filter assets by command-line arguments
if ($VersionFilter) {
$result = $result | Where-Object { $_.version -like "$VersionFilter*" }
}

if ($DistributionFilter) {
$result = $result | Where-Object { $_.tags.$DistributionFilter -ne $null } |
# Remove tags that do not match the distribution filter
Select-Object -Property 'version','releases',@{Name = 'tags'; Expression = { [PSCustomObject]@{ "$DistributionFilter" = $_.tags.$DistributionFilter } } }
}

if (-not $result) {
Write-Error "No assets found matching the specified filters."
exit 1
}

$script:assets = $result
}

# Synopsis: Invoke preprocessor to generate the image source files (can be filtered using command-line options).
task Prepare FilteredAssets, {
# Create output folders if they do not exist
New-Item -ItemType Directory $outputFolder -Force > $null
New-Item -ItemType Directory (Join-Path $outputFolder 'logs') -Force > $null

# For each asset
$assets = Get-Content -Raw -Path '.\assets.json' | ConvertFrom-Json
$assets | ForEach-Object {
$asset = $_

$version = [version]$asset.version
$versionFolder = Join-Path $outputFolder $version
New-Item -ItemType Directory $versionFolder -Force > $null

# For each image
# For each tag
$asset.tags | Get-Member -MemberType NoteProperty | ForEach-Object {
$image = $_.Name
$distribution = $_.Name
$distributionFolder = Join-Path $versionFolder $distribution
New-Item -ItemType Directory $distributionFolder -Force > $null

$THasArchARM64 = ($asset.releases.arm64.url -ne $null -and $image -ne 'bullseye' -and $image -ne 'jammy' ?
# Set variables for the template
$THasArchARM64 = ($asset.releases.arm64.url -ne $null -and $distribution -ne 'bullseye' -and $distribution -ne 'jammy' ?
'$true' : '$false')

$TUrlArchAMD64 = $asset.releases.amd64.url
Expand All @@ -264,55 +287,80 @@ task Prepare {
$TMajor = $version.Major
$TImageVersion = $version

$TImageTags = $asset.tags.$image
$TImageTags = $asset.tags.$distribution
if ($TImageTags) {
# https://stackoverflow.com/a/73073678
$TImageTags = "'{0}'" -f ($TImageTags -join "', '")
}

$variantFolder = Join-Path $versionFolder $image
New-Item -ItemType Directory $variantFolder -Force > $null

Copy-TemplateItem "./src/Dockerfile.$image.template" "$variantFolder/Dockerfile"
Copy-Item './src/entrypoint.sh' $variantFolder
Copy-TemplateItem "./src/image.build.ps1.template" "$variantFolder/image.build.ps1"
Copy-Item './src/image.tests.ps1' $variantFolder
# Render templates into the distribution folder
Copy-TemplateItem "./src/Dockerfile.$distribution.template" "$distributionFolder/Dockerfile"
Copy-Item './src/entrypoint.sh' $distributionFolder
Copy-TemplateItem "./src/image.build.ps1.template" "$distributionFolder/image.build.ps1"
Copy-Item './src/image.tests.ps1' $distributionFolder
}
}
}

# Synopsis: Build all docker images.
# Synopsis: Build all docker images (can be filtered using command-line options).
task Build Prepare, {
$taskName = "Build"

$PSStyle.OutputRendering = 'PlainText'
$logFolder = Join-Path $outputFolder 'logs'
$builds = Get-ChildItem "$outputFolder/**/image.build.ps1" -Recurse | ForEach-Object {
$version = $_.Directory.Parent.Name
$variant = $_.Directory.Name
$taskName = "Build"
@{
File = $_.FullName
Task = $taskName
Log = (Join-Path $logFolder "$taskName-$version-$variant.log")

$builds = $assets | ForEach-Object {
$asset = $_

$version = [version]$asset.version
$versionFolder = Join-Path $outputFolder $version

$asset.tags | Get-Member -MemberType NoteProperty | ForEach-Object {
$distribution = $_.Name
$distributionFolder = Join-Path $versionFolder $distribution
@{
File = "$distributionFolder/image.build.ps1"
Task = $taskName
Log = "$logFolder/$taskName-$version-$distribution.log"

# Parameters passed to Invoke-Build
Verbose = $PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent
}
}
}

Build-Parallel $builds
}

# Synopsis: Run all tests.
task Test {
# Synopsis: Run all tests (can be filtered using command-line options).
task Test FilteredAssets, {
$taskName = "Test"

$PSStyle.OutputRendering = 'PlainText'
$logFolder = Join-Path $outputFolder 'logs'
$builds = Get-ChildItem "$outputFolder/**/image.build.ps1" -Recurse | ForEach-Object {
$version = $_.Directory.Parent.Name
$variant = $_.Directory.Name
$taskName = "Test"
@{
File = $_.FullName
Task = $taskName
Log = (Join-Path $logFolder "$taskName-$version-$variant.log")

$tests = $assets | ForEach-Object {
$asset = $_

$version = [version]$asset.version
$versionFolder = Join-Path $outputFolder $version

$asset.tags | Get-Member -MemberType NoteProperty | ForEach-Object {
$distribution = $_.Name
$distributionFolder = Join-Path $versionFolder $distribution
@{
File = "$distributionFolder/image.build.ps1"
Task = $taskName
Log = "$logFolder/$taskName-$version-$distribution.log"

# Parameters passed to Invoke-Build
Verbose = $PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent
TestFilter = $TestFilter
}
}
}
Build-Parallel $builds

Build-Parallel $tests
}

# Synopsis: Publish all images.
Expand Down
62 changes: 59 additions & 3 deletions src/README.md.template
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,12 @@ More information:
## Prerequisites

- [Docker](https://docs.docker.com/engine/install/)
- [Powershell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-linux)
- [Powershell 7.5+](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-linux)
- [Invoke-Build](https://github.com/nightroman/Invoke-Build#install-as-module)



## Build
## Building

To generate the source files and build each image from [`assets.json`](assets.json) configuration file, run:

Expand All @@ -262,12 +262,68 @@ You can then check all created images with:
docker image ls firebirdsql/firebird
```

### Filtering builds

> You can filter builds by **version** or **distribution**:

```bash
# Build only Firebird 5.x images
Invoke-Build Build -VersionFilter "5"

# Build only specific version
Invoke-Build Build -VersionFilter "5.0.2"

# Build only bookworm distribution images
Invoke-Build Build -DistributionFilter "bookworm"

# Combine filters
Invoke-Build Build -VersionFilter "4" -DistributionFilter "jammy"
```


## Tests

## Testing

To run the test suite for each image, use:

```bash
Invoke-Build Test
```

### Filtering tests

You can filter tests by **version**, **distribution**, or a specific **test name**:

```bash
# Test only Firebird 4.x images
Invoke-Build Test -VersionFilter "4"

# Test only bullseye distribution images
Invoke-Build Test -DistributionFilter "bullseye"

# Run specific test
Invoke-Build Test -TestFilter "FIREBIRD_USER_can_create_user"

# Combine filters
Invoke-Build Test -VersionFilter "5" -DistributionFilter "noble"
```



## Maintenance tasks

The build script includes additional tasks dedicated to maintaining this project.

```bash
# Update assets.json from GitHub releases
Invoke-Build Update-Assets

# Update README.md from assets.json
Invoke-Build Update-Readme

# Regenerate source files
Invoke-Build Prepare

# Clean up generated files
Invoke-Build Clean
```
Loading