Skip to content
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c9090b5
Phase 0: Foundation
fdcastel Apr 7, 2026
378b7f6
Phase 1: Dockerfile & Entrypoint rewrite
fdcastel Apr 7, 2026
e540e72
Phase 2: Build System rewrite
fdcastel Apr 7, 2026
99c85a6
Phase 3: Tagging System
fdcastel Apr 7, 2026
2d5c601
Phase 4: CI/CD Workflows
fdcastel Apr 7, 2026
fb59b60
Phase 5: Snapshot / Pre-release Images
fdcastel Apr 7, 2026
a9e1c88
Phase 6: New tests
fdcastel Apr 7, 2026
adf319a
Phase 7: Documentation & Housekeeping
fdcastel Apr 7, 2026
258f2da
Fix Wait-Port/Test-Port parameter bugs and remove redundant Start-Sleep
fdcastel Apr 7, 2026
ea84133
Incorporate user edits to AGENTS.md and Dockerfile.template
fdcastel Apr 7, 2026
0cc84fc
Phase 4: Add ARM64 native runners and split publish workflow
fdcastel Apr 7, 2026
8fde8f7
Phase 5: Add snapshot and architecture sections to README
fdcastel Apr 7, 2026
dbaac41
Phase 6: Add _FILE variant tests, tag correctness test, mutual exclus…
fdcastel Apr 7, 2026
563e0a8
Phase 7: Add CONTRIBUTING.md
fdcastel Apr 7, 2026
1bb5c8a
Update GitHub Actions workflows to use actions/checkout@v5 and remove…
fdcastel Apr 7, 2026
bb9c604
Add fork publishing to GitHub Container Registry (ghcr.io)
fdcastel Apr 7, 2026
42efd40
Fix publish-fork staging packages; move dev notes to CONTRIBUTING.md
fdcastel Apr 7, 2026
b0597b6
Fix staging packages in multi-arch publish; update docker/login-actio…
fdcastel Apr 7, 2026
f06b5f4
Fix image tests to pass against Firebird 6 snapshots
fdcastel Apr 7, 2026
87b6c02
Add Test-Published task for testing images from a registry
fdcastel Apr 7, 2026
3bf7a7a
Upgrade actions/checkout from v5 to v6 in CI workflows
fdcastel Apr 7, 2026
35cd03d
Address review: uniform CI matrix, fix README alignment, clarify tag …
fdcastel Apr 7, 2026
3fbd9a1
Fix Test task: skip arm64-unsupported versions on arm64 runners
fdcastel Apr 7, 2026
b411e34
Add documentation for ARM64 build process in GitHub Actions
fdcastel Apr 10, 2026
4a24602
ci: build only latest-per-major on fork pushes
fdcastel Apr 10, 2026
d20c31c
docs: update comment for staging packages in publish-fork workflow
fdcastel Apr 10, 2026
0bd74f9
Switch to digest-based multi-arch assembly (no staging tags)
fdcastel Apr 11, 2026
b61de02
ci: auto-commit generated Dockerfiles and update README after publish
fdcastel Apr 11, 2026
c1b7ec6
chore: update generated Dockerfiles and README [skip ci]
github-actions[bot] Apr 11, 2026
f04f86d
fix: use Contains instead of ContainsKey on OrderedDictionary
fdcastel Apr 20, 2026
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
14 changes: 0 additions & 14 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1 @@
# These are supported funding model platforms

github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
thanks_dev: # Replace with a single thanks.dev username
custom: https://firebirdsql.org/en/donate/
58 changes: 39 additions & 19 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,66 @@ on:
pull_request:
branches: ['**']

workflow_dispatch: # Allows manual dispatch
workflow_dispatch:
inputs:
version-filter:
description: 'Version filter (e.g. 5, 4.0, 5.0.3). Empty = all.'
required: false
type: string
distro-filter:
description: 'Distro filter (e.g. bookworm). Empty = all.'
required: false
type: string

# Prevents overlapping runs of this workflow on the same branch.
# If multiple commits are pushed in quick succession, only the most recent run will complete.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build-and-test:
if: ${{ !(github.repository == 'FirebirdSQL/firebird-docker' && github.ref == 'refs/heads/master') }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
arch: [amd64, arm64]
include:
- arch: amd64
runner: ubuntu-latest
- arch: arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 10

- name: Set up QEMU
uses: docker/setup-qemu-action@v3
uses: actions/checkout@v6

- name: Install tools
shell: pwsh
run: |
Install-Module InvokeBuild -Force
Install-Module PSFirebird -MinimumVersion '1.0.0' -Force

- name: Build
shell: pwsh
run: |
Invoke-Build
$params = @{}
if ('${{ inputs.version-filter }}') { $params['VersionFilter'] = '${{ inputs.version-filter }}' }
if ('${{ inputs.distro-filter }}') { $params['DistributionFilter'] = '${{ inputs.distro-filter }}' }
Invoke-Build Build @params

- name: Test
shell: pwsh
run: |
Invoke-Build Test

- name: Upload logs
uses: actions/upload-artifact@v4
if: always()
with:
name: ci-logs-${{ github.run_id }}
path: generated/logs
retention-days: 7 # Short log retention for CI runs
$params = @{}
if ('${{ inputs.version-filter }}') { $params['VersionFilter'] = '${{ inputs.version-filter }}' }
if ('${{ inputs.distro-filter }}') { $params['DistributionFilter'] = '${{ inputs.distro-filter }}' }
Invoke-Build Test @params

- name: Run tag unit tests
# Verifies Get-ImageTags produces correct Docker tags (pure logic, no Docker required).
# Tag logic is arch-independent — run once on amd64 to avoid duplication.
if: matrix.arch == 'amd64'
Comment thread
fdcastel marked this conversation as resolved.
shell: pwsh
run: |
Install-Module Pester -Force -SkipPublisherCheck
Invoke-Pester src/tags.tests.ps1 -Output Detailed -CI
235 changes: 235 additions & 0 deletions .github/workflows/publish-fork.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
name: publish-fork

# Build, test and publish Docker images to GitHub Container Registry (ghcr.io).
# - Triggers: Manual dispatch only (workflow_dispatch)
# - Runs on: Any fork (uses built-in GITHUB_TOKEN — no extra secrets required)
#
# Images are published to ghcr.io/<owner>/firebird
# Default scope: latest Firebird version + bookworm (fast, ~2 minutes)
# Default result: ONE package — ghcr.io/<owner>/firebird — with all expected tags.
#
# With include-arm64=true: publishes ghcr.io/<owner>/firebird as a multi-arch image
# (plus temporary staging packages firebird-amd64 / firebird-arm64 needed for manifest creation).
#
# Usage:
# Go to Actions → publish-fork → Run workflow
# Pull with: docker pull ghcr.io/<your-username>/firebird:<tag>

on:
workflow_dispatch:
inputs:
version-filter:
description: 'Version filter (e.g. 5, 5.0.3). Empty = latest only.'
required: false
type: string
distro-filter:
description: 'Distro filter (e.g. bookworm, jammy). Empty = default distro (bookworm).'
required: false
type: string
include-arm64:
description: 'Also build ARM64 images (takes ~2x longer; produces extra staging packages).'
required: false
type: boolean
default: false
include-snapshots:
description: 'Also build and publish snapshot images (6-snapshot, 5-snapshot).'
required: false
type: boolean
default: false

# Only one run at a time per fork.
concurrency:
group: ${{ github.workflow }}-${{ github.repository }}
cancel-in-progress: true

env:
REGISTRY: ghcr.io/${{ github.repository_owner }}
IMAGE_NAME: firebird

jobs:
determine-scope:
runs-on: ubuntu-latest
outputs:
version-filter: ${{ steps.scope.outputs.version-filter }}
distro-filter: ${{ steps.scope.outputs.distro-filter }}
matrix: ${{ steps.scope.outputs.matrix }}
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Determine build scope
id: scope
shell: pwsh
run: |
$assets = Get-Content -Raw ./assets.json | ConvertFrom-Json

# Use input or default to latest version + default distro
$vf = '${{ inputs.version-filter }}'
$df = '${{ inputs.distro-filter }}'
if (-not $vf) { $vf = $assets.versions[0].version }
if (-not $df) { $df = $assets.config.defaultDistro }

"version-filter=$vf" >> $env:GITHUB_OUTPUT
"distro-filter=$df" >> $env:GITHUB_OUTPUT

# Build arch matrix based on input
$includeArm64 = '${{ inputs.include-arm64 }}' -eq 'true'
$matrix = if ($includeArm64) {
'{"arch":["amd64","arm64"],"include":[{"arch":"amd64","runner":"ubuntu-latest"},{"arch":"arm64","runner":"ubuntu-24.04-arm"}]}'
} else {
'{"arch":["amd64"],"include":[{"arch":"amd64","runner":"ubuntu-latest"}]}'
}
"matrix=$matrix" >> $env:GITHUB_OUTPUT

build-and-push:
needs: determine-scope
permissions:
packages: write
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.determine-scope.outputs.matrix) }}
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Install tools
shell: pwsh
run: |
Install-Module InvokeBuild -Force
Install-Module PSFirebird -MinimumVersion '1.0.0' -Force

- name: Build
shell: pwsh
run: |
Invoke-Build Build `
-VersionFilter '${{ needs.determine-scope.outputs.version-filter }}' `
-DistributionFilter '${{ needs.determine-scope.outputs.distro-filter }}' `
-Registry '${{ env.REGISTRY }}'

- name: Test
shell: pwsh
run: |
Invoke-Build Test `
-VersionFilter '${{ needs.determine-scope.outputs.version-filter }}' `
-DistributionFilter '${{ needs.determine-scope.outputs.distro-filter }}' `
-Registry '${{ env.REGISTRY }}'

- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

# amd64-only: push as the final image name — produces exactly ONE package.
- name: Push (amd64 only — final name, no staging)
if: ${{ !inputs.include-arm64 }}
shell: pwsh
run: |
Invoke-Build Publish-Direct `
-VersionFilter '${{ needs.determine-scope.outputs.version-filter }}' `
-DistributionFilter '${{ needs.determine-scope.outputs.distro-filter }}' `
-Registry '${{ env.REGISTRY }}'

# multi-arch: push with -amd64/-arm64 staging suffixes for later manifest creation.
- name: Push (staging for multi-arch manifest)
if: ${{ inputs.include-arm64 }}
shell: pwsh
run: |
Invoke-Build Publish-Arch `
-VersionFilter '${{ needs.determine-scope.outputs.version-filter }}' `
-DistributionFilter '${{ needs.determine-scope.outputs.distro-filter }}' `
-Registry '${{ env.REGISTRY }}'

- name: Build and push snapshot images
if: ${{ inputs.include-snapshots && matrix.arch == 'amd64' }}
shell: pwsh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
foreach ($branch in @('master', 'v5.0-release')) {
Invoke-Build Build-Snapshot -Branch $branch -Registry '${{ env.REGISTRY }}'
$tag = if ($branch -eq 'master') { '6-snapshot' } else { '5-snapshot' }
docker push "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:$tag"
}

# Summary only for the amd64-only case (multi-arch summary is in create-manifests).
- name: Summary
if: ${{ !inputs.include-arm64 && matrix.arch == 'amd64' }}
shell: pwsh
run: |
$vf = '${{ needs.determine-scope.outputs.version-filter }}'
$df = '${{ needs.determine-scope.outputs.distro-filter }}'
$registry = '${{ env.REGISTRY }}'
$imageName = '${{ env.IMAGE_NAME }}'

$assets = Get-Content -Raw ./assets.json | ConvertFrom-Json
$filtered = $assets.versions | Where-Object { $_.version -like "$vf*" }
$tags = $filtered | ForEach-Object { $_.tags.$df } | Select-Object -First 5

@"
## Published to GitHub Container Registry

**Registry:** ``$registry/$imageName``

### Pull commands
``````
$(($tags | ForEach-Object { "docker pull $registry/${imageName}:$_" }) -join "`n")
``````
"@ >> $env:GITHUB_STEP_SUMMARY

# Only runs when include-arm64=true. Creates multi-arch OCI manifests from staging images.
create-manifests:
if: ${{ inputs.include-arm64 }}
needs: [determine-scope, build-and-push]
permissions:
packages: write
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Install tools
shell: pwsh
run: |
Install-Module InvokeBuild -Force
Install-Module PSFirebird -MinimumVersion '1.0.0' -Force

- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Create and push multi-arch manifests
shell: pwsh
run: |
Invoke-Build Publish-Manifests `
-VersionFilter '${{ needs.determine-scope.outputs.version-filter }}' `
-DistributionFilter '${{ needs.determine-scope.outputs.distro-filter }}' `
-Registry '${{ env.REGISTRY }}'

- name: Summary
shell: pwsh
run: |
$vf = '${{ needs.determine-scope.outputs.version-filter }}'
$df = '${{ needs.determine-scope.outputs.distro-filter }}'
$registry = '${{ env.REGISTRY }}'
$imageName = '${{ env.IMAGE_NAME }}'

$assets = Get-Content -Raw ./assets.json | ConvertFrom-Json
$filtered = $assets.versions | Where-Object { $_.version -like "$vf*" }
$tags = $filtered | ForEach-Object { $_.tags.$df } | Select-Object -First 5

@"
## Published to GitHub Container Registry (multi-arch)

**Registry:** ``$registry/$imageName``

### Pull commands
``````
$(($tags | ForEach-Object { "docker pull $registry/${imageName}:$_" }) -join "`n")
``````
"@ >> $env:GITHUB_STEP_SUMMARY
Loading