ytptube/.github/workflows/native-build.yml

225 lines
6.8 KiB
YAML

name: native-build
on:
workflow_dispatch:
inputs:
tag:
required: true
description: "Ref to build from (e.g. v1.0.0)"
useWorkflowSpec:
type: boolean
default: false
description: "Use app.spec from workflow branch instead of tag"
push:
tags:
- "v*"
jobs:
build:
if: ${{ vars.REGISTRY == '' }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
arch: amd64
- os: ubuntu-latest
arch: arm64
- os: macos-latest
arch: arm64
- os: windows-latest
arch: amd64
- os: windows-latest
arch: arm64
permissions:
packages: write
contents: write
env:
PYTHON_VERSION: "3.13"
BUN_VERSION: latest
NODE_VERSION: 20
TAG_NAME: ${{ github.event.inputs.tag || github.ref_name }}
steps:
- name: Checkout source repo
uses: actions/checkout@v4
with:
ref: ${{ env.TAG_NAME }}
- name: Overwrite app.spec from workflow branch
if: ${{ github.event.inputs.useWorkflowSpec == 'true' }}
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
sparse-checkout: |
app.spec
sparse-checkout-cone-mode: false
path: temp-spec
- name: Replace app.spec with version from workflow branch
if: ${{ github.event.inputs.useWorkflowSpec == 'true' }}
shell: bash
run: cp temp-spec/app.spec ./app.spec
- name: Update app/library/version.py
shell: bash
run: |
VERSION="${TAG_NAME}"
SHA=$(git rev-parse HEAD)
DATE=$(date -u +"%Y%m%d")
BRANCH=$(git branch --show-current)
if [ -z "${BRANCH}" ]; then
BRANCH="${TAG_NAME}"
fi
BRANCH=$(echo "${BRANCH}" | sed 's#/#-#g')
echo "APP_VERSION=${VERSION}" >> "$GITHUB_ENV"
echo "APP_SHA=${SHA}" >> "$GITHUB_ENV"
echo "APP_DATE=${DATE}" >> "$GITHUB_ENV"
echo "APP_BRANCH=${BRANCH}" >> "$GITHUB_ENV"
sed -i.bak \
-e "s/^APP_VERSION = \".*\"/APP_VERSION = \"${VERSION}\"/" \
-e "s/^APP_COMMIT_SHA = \".*\"/APP_COMMIT_SHA = \"${SHA}\"/" \
-e "s/^APP_BUILD_DATE = \".*\"/APP_BUILD_DATE = \"${DATE}\"/" \
-e "s/^APP_BRANCH = \".*\"/APP_BRANCH = \"${BRANCH}\"/" \
app/library/version.py
rm -f app/library/version.py.bak
echo "Updated version info:"
cat app/library/version.py
- name: Cache Python venv
id: cache-python
uses: actions/cache@v4
with:
path: .venv
key: uv-${{ runner.os }}-${{ matrix.arch }}-${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock') }}
restore-keys: |
uv-${{ runner.os }}-${{ matrix.arch }}-${{ env.PYTHON_VERSION }}-
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
architecture: "x64"
- name: Install Python dependencies
shell: bash
run: |
pip install uv
if [ ! -d .venv ]; then
uv venv --system-site-packages --relocatable
fi
uv sync --link-mode=copy --active --extra installer
- name: Cache bun installation
id: cache-bun
uses: actions/cache@v4
with:
path: ~/.bun/install/cache
key: ${{ runner.os }}-${{ matrix.arch }}-bun-${{ hashFiles('**/bun.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.arch }}-bun-
- name: Install bun
uses: oven-sh/setup-bun@v2
with:
bun-version: ${{ env.BUN_VERSION }}
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Build frontend
working-directory: ui
shell: bash
run: |
bun install --production --prefer-offline --frozen-lockfile
bun run generate
- name: Clean build outputs (Unix)
if: runner.os != 'Windows'
shell: bash
run: rm -rf build dist release || true
- name: Clean build outputs (Windows)
if: runner.os == 'Windows'
shell: powershell
run: |
if (Test-Path build) { Remove-Item -Recurse -Force build }
if (Test-Path dist) { Remove-Item -Recurse -Force dist }
if (Test-Path release) { Remove-Item -Recurse -Force release }
- name: Build native binary (Windows)
if: matrix.os == 'windows-latest'
shell: powershell
run: |
.\.venv\Scripts\activate
uv run pyinstaller ./app.spec
- name: Build native binary (Linux/macOS)
if: matrix.os != 'windows-latest'
shell: bash
run: |
. .venv/bin/activate
uv run pyinstaller ./app.spec
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: app-${{ runner.os }}-${{ matrix.arch }}-${{ env.TAG_NAME }}
path: dist/YTPTube/**
- name: Package artifact (Unix)
if: startsWith(env.TAG_NAME, 'v') && runner.os != 'Windows'
shell: bash
run: |
mkdir -p release
PKG_DIR="YTPTube-${{ env.TAG_NAME }}"
ZIP_NAME="ytptube-${{ runner.os }}-${{ matrix.arch }}-${{ env.TAG_NAME }}.zip"
if [ ! -f "dist/YTPTube/YTPTube" ]; then
echo "Missing dist/YTPTube/YTPTube"
find dist -maxdepth 3 -type f | head -n 200
exit 1
fi
rm -rf "dist/${PKG_DIR}"
mv "dist/YTPTube" "dist/${PKG_DIR}"
zip -yr "release/${ZIP_NAME}" "dist/${PKG_DIR}"
- name: Package artifact (Windows)
if: startsWith(env.TAG_NAME, 'v') && runner.os == 'Windows'
shell: powershell
run: |
$pkgDir = "YTPTube-${{ env.TAG_NAME }}"
$zipName = "ytptube-${{ runner.os }}-${{ matrix.arch }}-${{ env.TAG_NAME }}.zip"
New-Item -ItemType Directory -Force -Path release | Out-Null
if (!(Test-Path "dist\YTPTube\YTPTube.exe")) {
Write-Host "Missing dist\YTPTube\YTPTube.exe"
Get-ChildItem -Recurse dist | Select-Object -First 200 | Format-Table -AutoSize
exit 1
}
if (Test-Path "dist\$pkgDir") { Remove-Item -Recurse -Force "dist\$pkgDir" }
Move-Item "dist\YTPTube" "dist\$pkgDir"
Compress-Archive -Path "dist\$pkgDir" -DestinationPath "release\$zipName" -Force
- name: Upload to GitHub Release
if: startsWith(env.TAG_NAME, 'v')
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ env.TAG_NAME }}
files: release/*.zip