Skip to content

Fix catalog signer cleanup trap #19

Fix catalog signer cleanup trap

Fix catalog signer cleanup trap #19

Workflow file for this run

name: Continuous integration
on:
workflow_call:
push:
branches:
- dev
pull_request:
branches:
- dev
workflow_dispatch:
# Read access is the workflow default. Only the release job receives write access.
permissions:
contents: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
quality:
name: Python tests and source quality
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- name: Check out source
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.13"
cache: pip
cache-dependency-path: |
auto_tests/requirements.txt
auto_tests/requirements-dev.txt
- name: Install test dependencies
working-directory: auto_tests
run: python -m pip install --requirement requirements-dev.txt
- name: Lint Python
working-directory: auto_tests
run: python -m ruff check app tests ../assets/live/*.py ../iso-tools/*.py
- name: Check Python formatting
working-directory: auto_tests
run: python -m ruff format --check app tests ../assets/live/*.py ../iso-tools/*.py
- name: Run Python test suite with coverage
working-directory: auto_tests
run: python -m pytest --cov=app --cov-report=term-missing --cov-fail-under=70
- name: Validate shell script syntax
shell: bash
run: |
set -Eeuo pipefail
while IFS= read -r -d '' script; do
bash -n "$script"
done < <(git ls-files -z '*.sh')
- name: Run ShellCheck
shell: bash
run: |
set -Eeuo pipefail
git ls-files -z '*.sh' | xargs -0 --no-run-if-empty shellcheck -x -S warning
- name: Validate versioned JSON contracts
shell: bash
run: |
set -Eeuo pipefail
python -m json.tool schemas/installation-plan.schema.json >/dev/null
python -m json.tool schemas/installation-state.schema.json >/dev/null
wpf:
name: Build WPF (.NET Framework 4.8)
runs-on: windows-2022
timeout-minutes: 30
steps:
- name: Check out source
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Add Visual Studio MSBuild to PATH
uses: microsoft/setup-msbuild@30375c66a4eea26614e0d39710365f22f8b0af57 # v3
with:
vs-version: "[17.0,18.0)"
- name: Verify .NET Framework 4.8 build tools
shell: pwsh
run: |
$referenceAssemblies = Join-Path ${env:ProgramFiles(x86)} `
'Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8'
if (-not (Test-Path -LiteralPath $referenceAssemblies -PathType Container)) {
throw ".NET Framework 4.8 targeting pack is missing: $referenceAssemblies"
}
msbuild -version
- name: Validate PowerShell syntax
shell: pwsh
run: |
$failures = [System.Collections.Generic.List[string]]::new()
Get-ChildItem -Path Scripts, auto_tests/app/scripts, PowerShell.Tests -Recurse -File |
Where-Object { $_.Extension -in '.ps1', '.psm1' } |
ForEach-Object {
$tokens = $null
$errors = $null
[void][System.Management.Automation.Language.Parser]::ParseFile(
$_.FullName,
[ref]$tokens,
[ref]$errors
)
foreach ($errorRecord in $errors) {
$failures.Add("$($_.FullName): $($errorRecord.Message)")
}
}
if ($failures.Count -gt 0) {
throw ($failures -join [Environment]::NewLine)
}
- name: Analyze PowerShell
shell: pwsh
run: |
Install-Module -Name PSScriptAnalyzer -RequiredVersion 1.25.0 `
-Scope CurrentUser -Force -Repository PSGallery
$findings = @(
Invoke-ScriptAnalyzer `
-Path Scripts `
-Recurse `
-Settings PSScriptAnalyzerSettings.psd1 `
-Severity Error, Warning
Invoke-ScriptAnalyzer `
-Path auto_tests/app/scripts `
-Recurse `
-Settings PSScriptAnalyzerSettings.psd1 `
-Severity Error, Warning
Invoke-ScriptAnalyzer `
-Path PowerShell.Tests `
-Recurse `
-Settings PSScriptAnalyzerSettings.psd1 `
-Severity Error, Warning
)
$findings | Format-Table -AutoSize
if ($findings.Count -gt 0) {
throw "PSScriptAnalyzer reported $($findings.Count) finding(s)."
}
- name: Run PowerShell contract tests
shell: pwsh
run: |
Install-Module -Name Pester -RequiredVersion 6.0.1 `
-Scope CurrentUser -Force -Repository PSGallery
$configuration = New-PesterConfiguration
$configuration.Run.Path = 'PowerShell.Tests'
$configuration.Run.Exit = $true
$configuration.Output.Verbosity = 'Normal'
Invoke-Pester -Configuration $configuration
- name: Build Libertix.exe
shell: pwsh
run: >-
msbuild Libertix.sln
/restore
/m
/warnaserror
/p:Configuration=Release
'/p:Platform=Any CPU'
/verbosity:minimal
- name: Run C# contract tests
shell: pwsh
run: >-
dotnet test Libertix.Tests\Libertix.Tests.csproj
--configuration Release
--no-build
--no-restore
--verbosity minimal
- name: Verify WPF output
shell: pwsh
run: |
$executable = 'bin\Release\Libertix.exe'
if (-not (Test-Path -LiteralPath $executable -PathType Leaf)) {
throw "Expected WPF executable was not produced: $executable"
}
$hash = Get-FileHash -Algorithm SHA256 -LiteralPath $executable
"Libertix.exe SHA-256: $($hash.Hash.ToLowerInvariant())" |
Tee-Object -FilePath $env:GITHUB_STEP_SUMMARY -Append
- name: Upload WPF build
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: Libertix-wpf-${{ github.sha }}
path: bin/Release/**
if-no-files-found: error
retention-days: 14
compression-level: 9
iso:
name: Build and verify BIOS and UEFI mini-ISO
needs:
- quality
- wpf
# The ISO builder requires a privileged Docker container. Do not execute
# untrusted pull-request code with that privilege.
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/dev'
runs-on: ubuntu-24.04
timeout-minutes: 150
steps:
- name: Check out source
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Verify Docker and disk capacity
shell: bash
run: |
set -Eeuo pipefail
docker version
available_bytes="$(df -B1 --output=avail "$GITHUB_WORKSPACE" | tail -n 1 | tr -d ' ')"
required_bytes="$((12 * 1024 * 1024 * 1024))"
printf 'Available workspace capacity: %s bytes\n' "$available_bytes"
if (( available_bytes < required_bytes )); then
printf 'At least %s bytes are required for both full ISO builds.\n' \
"$required_bytes" >&2
exit 1
fi
- name: Build and verify both mini-ISO images
shell: bash
run: ./iso-tools/build-isos-docker.sh all
- name: Record ISO checksums
shell: bash
run: |
set -Eeuo pipefail
test -s libertix-installer-bios.iso
test -s libertix-installer-uefi.iso
sha256sum \
libertix-installer-bios.iso \
libertix-installer-uefi.iso \
| tee libertix-isos.sha256
cat libertix-isos.sha256 >> "$GITHUB_STEP_SUMMARY"
- name: Upload verified mini-ISO images
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: Libertix-mini-isos-${{ github.sha }}
path: |
libertix-installer-bios.iso
libertix-installer-uefi.iso
libertix-isos.sha256
if-no-files-found: error
retention-days: 7
compression-level: 0
release:
name: Publish dev alpha prerelease
needs:
- quality
- wpf
- iso
if: >-
github.ref == 'refs/heads/dev' &&
(github.event_name == 'push' || github.event_name == 'workflow_dispatch')
runs-on: ubuntu-24.04
timeout-minutes: 15
permissions:
contents: write
steps:
- name: Download WPF build
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: Libertix-wpf-${{ github.sha }}
path: release-input/wpf
- name: Download verified mini-ISO images
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: Libertix-mini-isos-${{ github.sha }}
path: release-input/iso
- name: Prepare release assets
shell: bash
run: |
set -Eeuo pipefail
test -d release-input/wpf
test -s release-input/iso/libertix-installer-bios.iso
test -s release-input/iso/libertix-installer-uefi.iso
mkdir -p release-assets
(
cd release-input/wpf
zip -9 -q -r "$GITHUB_WORKSPACE/release-assets/Libertix-wpf.zip" .
)
cp -- \
release-input/iso/libertix-installer-bios.iso \
release-input/iso/libertix-installer-uefi.iso \
release-assets/
test -s release-assets/Libertix-wpf.zip
- name: Publish alpha prerelease
shell: bash
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
run: |
set -Eeuo pipefail
tag="${GITHUB_SHA:0:7}"
title="Alpha $tag"
commit_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/commit/$GITHUB_SHA"
notes="Automated Libertix alpha build for commit [$tag]($commit_url)."
assets=(
release-assets/Libertix-wpf.zip
release-assets/libertix-installer-bios.iso
release-assets/libertix-installer-uefi.iso
)
if gh release view "$tag" >/dev/null 2>&1; then
gh release edit "$tag" \
--target "$GITHUB_SHA" \
--title "$title" \
--notes "$notes" \
--prerelease
gh release upload "$tag" "${assets[@]}" --clobber
else
gh release create "$tag" "${assets[@]}" \
--target "$GITHUB_SHA" \
--title "$title" \
--notes "$notes" \
--prerelease
fi
- name: Keep the three newest dev alpha prereleases
shell: bash
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
run: |
set -Eeuo pipefail
mapfile -t stale_tags < <(
gh release list \
--limit 100 \
--json tagName,isPrerelease,createdAt \
--jq '[.[] | select(.isPrerelease == true and (.tagName | test("^[0-9a-f]{7}$")))] | sort_by(.createdAt) | reverse | .[3:][] | .tagName'
)
for stale_tag in "${stale_tags[@]}"; do
gh release delete "$stale_tag" --cleanup-tag --yes
done