Files
obdash/.gitea/workflows/release.yml
T
justin 0b0ecc96e7 Fix #12: pin CI actions to SHAs, container to digest, bound deps
Supply-chain hardening for the release pipeline:
- actions/checkout and softprops/action-gh-release pinned from floating major
  tags to commit SHAs (v4.2.2 / v2.2.1) — a moved tag can no longer inject code
  into the job that holds the release token.
- Linux/arm64 build container pinned by manifest-list digest
  (nikolaik/python-nodejs:python3.12-nodejs20@sha256:9ff0859…).
- requirements-gui.txt gains upper bounds so a breaking major (e.g. numpy 3,
  PySide6 7) can't silently change a release binary; current versions still
  satisfy, so no build change.

Deferred (noted on the issue): hash-verifying the Windows get-pip.py / embed-zip
download — low value + fragile (get-pip.py isn't hash-stable) and that fallback
path is dormant now that the runner has Python installed system-wide.

Closes #12

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016yT89n4zR4qbrySoSiEyZs
2026-07-01 19:42:51 -04:00

127 lines
5.9 KiB
YAML

name: Build binaries
# Build OBDash GUI binaries on each self-hosted runner. On a version tag
# (v*), publish a Gitea Release with every platform's binary attached.
# Manual runs (workflow_dispatch) build-only (no release) to verify compilation.
on:
push:
tags: ["v*"]
workflow_dispatch: {}
jobs:
windows:
runs-on: windows-latest # self-hosted Windows runner (no Python preinstalled)
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Build OBDash.exe (PyInstaller)
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
# Use a pre-installed Python if the runner has one; otherwise set up a
# self-contained embeddable Python (no MSI, no admin, no registry).
$py = "python"
if (-not (Get-Command python -ErrorAction SilentlyContinue)) {
$dir = "$env:LOCALAPPDATA\obdash-python"
if (-not (Test-Path "$dir\python.exe")) {
Write-Host "Setting up embeddable Python 3.12 at $dir ..."
$zip = "$env:TEMP\pyembed.zip"
Invoke-WebRequest "https://www.python.org/ftp/python/3.12.7/python-3.12.7-embed-amd64.zip" -OutFile $zip
if (Test-Path $dir) { Remove-Item -Recurse -Force $dir }
Expand-Archive $zip -DestinationPath $dir -Force
# enable site-packages so pip-installed packages import
$pth = Get-ChildItem "$dir\python*._pth" | Select-Object -First 1
(Get-Content $pth) -replace '^#\s*import site','import site' | Set-Content $pth
Invoke-WebRequest "https://bootstrap.pypa.io/get-pip.py" -OutFile "$dir\get-pip.py"
& "$dir\python.exe" "$dir\get-pip.py" --no-warn-script-location
}
$py = "$dir\python.exe"
$env:Path = "$dir;$dir\Scripts;$env:Path"
}
& $py --version
& $py -m pip install --no-cache-dir --upgrade pip
& $py -m pip install --no-cache-dir -r requirements-gui.txt pyinstaller
& $py -m PyInstaller --noconfirm --onefile --windowed --name OBDash --add-data "profiles;profiles" run_gui.py
Copy-Item dist/OBDash.exe OBDash-windows.exe
(Get-FileHash OBDash-windows.exe -Algorithm SHA256).Hash.ToLower() + " OBDash-windows.exe" | Out-File -Encoding ascii OBDash-windows.exe.sha256
- name: Publish to release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
with:
files: |
OBDash-windows.exe
OBDash-windows.exe.sha256
env:
GITHUB_TOKEN: ${{ secrets.GITEA_TOKEN }}
macos:
runs-on: self-hosted-mac
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Build OBDash.app (PyInstaller)
shell: bash
run: |
python3 -m venv .build-venv
. .build-venv/bin/activate
pip install --upgrade pip
pip install -r requirements-gui.txt pyinstaller
pyinstaller --noconfirm --windowed --name OBDash --add-data "profiles:profiles" run_gui.py
ditto -c -k --keepParent dist/OBDash.app OBDash-macos.zip
shasum -a 256 OBDash-macos.zip > OBDash-macos.zip.sha256
- name: Publish to release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
with:
files: |
OBDash-macos.zip
OBDash-macos.zip.sha256
env:
GITHUB_TOKEN: ${{ secrets.GITEA_TOKEN }}
linux-amd64:
runs-on: docker # Linux x86_64 runner
container: nikolaik/python-nodejs:python3.12-nodejs20@sha256:9ff0859871d1b3c382a39aa23d998929edaaefb31e6b3cb67f30d2f8c832db73 # has python+pip AND node (for checkout)
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Build OBDash (PyInstaller)
shell: bash
run: |
apt-get update && apt-get install -y patchelf libgl1 libegl1 libxkbcommon0
pip install --upgrade pip
pip install -r requirements-gui.txt pyinstaller
pyinstaller --noconfirm --onefile --name OBDash --add-data "profiles:profiles" run_gui.py
cp dist/OBDash OBDash-linux-x86_64
sha256sum OBDash-linux-x86_64 > OBDash-linux-x86_64.sha256
- name: Publish to release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
with:
files: |
OBDash-linux-x86_64
OBDash-linux-x86_64.sha256
env:
GITHUB_TOKEN: ${{ secrets.GITEA_TOKEN }}
linux-arm64:
runs-on: arm64 # Raspberry Pi (aarch64) runner
container: nikolaik/python-nodejs:python3.12-nodejs20@sha256:9ff0859871d1b3c382a39aa23d998929edaaefb31e6b3cb67f30d2f8c832db73 # multi-arch: pulls arm64
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Build OBDash (PyInstaller)
shell: bash
run: |
apt-get update && apt-get install -y patchelf libgl1 libegl1 libxkbcommon0
pip install --upgrade pip
pip install -r requirements-gui.txt pyinstaller
pyinstaller --noconfirm --onefile --name OBDash --add-data "profiles:profiles" run_gui.py
cp dist/OBDash OBDash-linux-aarch64
sha256sum OBDash-linux-aarch64 > OBDash-linux-aarch64.sha256
- name: Publish to release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
with:
files: |
OBDash-linux-aarch64
OBDash-linux-aarch64.sha256
env:
GITHUB_TOKEN: ${{ secrets.GITEA_TOKEN }}