Skip to content

Fix DMG background: use setup-python for reliable Pillow install #20

Fix DMG background: use setup-python for reliable Pillow install

Fix DMG background: use setup-python for reliable Pillow install #20

Workflow file for this run

name: Release Build
on:
push:
tags:
- 'v*'
workflow_dispatch:
permissions:
contents: write
jobs:
# ============================================================
# macOS: .app bundle + .dmg (arm64 + x64)
# ============================================================
build-macos:
name: macOS ${{ matrix.arch }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- arch: arm64
runner: macos-14
rid: osx-arm64
- arch: x64
runner: macos-15
rid: osx-x64
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Get version
shell: bash
run: |
VERSION=${GITHUB_REF#refs/tags/v}
[[ "$VERSION" == refs/* ]] && VERSION=0.0.0-dev
echo "VERSION=$VERSION" >> $GITHUB_ENV
- name: Publish (self-contained)
run: dotnet publish src/Taskly/Taskly.csproj -c Release -r ${{ matrix.rid }} --self-contained true -p:PublishSingleFile=true -p:Version=${{ env.VERSION }} -o publish
- name: Assemble .app bundle
shell: bash
run: |
mkdir -p "Taskly.app/Contents/MacOS"
mkdir -p "Taskly.app/Contents/Resources"
cp -R publish/* "Taskly.app/Contents/MacOS/"
# 写 Info.plist(用实际版本号替换占位)
sed 's/0\.3\.0/${{ env.VERSION }}/' packaging/macos/Info.plist > "Taskly.app/Contents/Info.plist"
chmod +x "Taskly.app/Contents/MacOS/Taskly"
# appdmg writes the .DS_Store binary directly (no Finder/AppleScript),
# producing a decorated DMG (background + /Applications link) in headless CI.
- name: Setup Node for appdmg
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Setup Python for background generation
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install appdmg
run: npm install -g appdmg
- name: Generate DMG background
run: |
python3 -m pip install pillow
python3 packaging/macos/dmg/make_background.py packaging/macos/dmg
- name: Create .dmg (decorated, with retry)
shell: bash
run: |
chmod +x packaging/macos/create-dmg.sh
packaging/macos/create-dmg.sh \
"packaging/macos/dmg/spec.json" \
"taskly-${{ env.VERSION }}-macos-${{ matrix.arch }}.dmg"
- uses: actions/upload-artifact@v4
with:
name: taskly-macos-${{ matrix.arch }}
path: '*.dmg'
# ============================================================
# Windows: Setup.exe (Velopack)
# ============================================================
build-windows:
name: Windows x64
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Get version
shell: bash
run: |
VERSION=${GITHUB_REF#refs/tags/v}
[[ "$VERSION" == refs/* ]] && VERSION=0.0.0-dev
echo "VERSION=$VERSION" >> $GITHUB_ENV
- name: Publish (self-contained)
run: dotnet publish src/Taskly/Taskly.csproj -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -p:Version=${{ env.VERSION }} -o publish
- name: Install Velopack
run: dotnet tool install -g vpk
- name: Create Setup.exe
shell: pwsh
run: |
$env:PATH = "$env:USERPROFILE\.dotnet\tools;$env:PATH"
# 诊断:确认 publish 目录内容
Write-Host "=== publish 目录 ==="
Get-ChildItem publish/*.exe | Format-Table Name, Length
# 运行 vpk(出错了能看到完整输出)
vpk pack -u Taskly -v ${{ env.VERSION }} -p publish -e Taskly.exe -o build --verbose
Write-Host "=== build 产物 ==="
Get-ChildItem build/*.exe | Format-Table Name, Length
- uses: actions/upload-artifact@v4
with:
name: taskly-windows-x64
path: 'build/*.exe'
# ============================================================
# Linux: .AppImage + .deb
# ============================================================
build-linux:
name: Linux x64
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Get version
shell: bash
run: |
VERSION=${GITHUB_REF#refs/tags/v}
[[ "$VERSION" == refs/* ]] && VERSION=0.0.0-dev
echo "VERSION=$VERSION" >> $GITHUB_ENV
- name: Publish (self-contained)
run: dotnet publish src/Taskly/Taskly.csproj -c Release -r linux-x64 --self-contained true -p:PublishSingleFile=true -p:Version=${{ env.VERSION }} -o publish
# --- AppImage ---
- name: Install FUSE for AppImage
run: sudo apt-get update && sudo apt-get install -y libfuse2
- name: Build AppImage
shell: bash
run: |
# 组装 AppDir(appimagetool 要求 .desktop 在根目录)
mkdir -p AppDir/usr/bin
cp -R publish/* AppDir/usr/bin/
chmod +x AppDir/usr/bin/Taskly
# .desktop 必须在 AppDir 根目录
cp packaging/linux/taskly.desktop AppDir/taskly.desktop
# 图标(appimagetool 要求 Icon=taskly 对应 taskly.png 存在)
cp packaging/linux/taskly.png AppDir/taskly.png
cp packaging/linux/AppRun AppDir/AppRun
chmod +x AppDir/AppRun
# 下载 appimagetool
wget -q "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" -O appimagetool
chmod +x appimagetool
# 生成 AppImage(CI 环境用 APPIMAGE_EXTRACT_AND_RUN 绕过 FUSE)
ARCH=x86_64 APPIMAGE_EXTRACT_AND_RUN=1 ./appimagetool AppDir "taskly-${{ env.VERSION }}-linux-x64.AppImage"
ls -la *.AppImage
# --- .deb ---
- name: Build .deb
shell: bash
run: |
VERSION=${{ env.VERSION }}
STAGING="deb-staging"
mkdir -p "$STAGING/usr/bin"
mkdir -p "$STAGING/usr/lib/taskly"
mkdir -p "$STAGING/usr/share/applications"
mkdir -p "$STAGING/DEBIAN"
# 可执行文件 + 运行时(self-contained)
cp -R publish/* "$STAGING/usr/lib/taskly/"
chmod +x "$STAGING/usr/lib/taskly/Taskly"
# 启动脚本(转发到 self-contained 可执行文件)
cat > "$STAGING/usr/bin/taskly" << 'EOF'
#!/bin/sh
exec /usr/lib/taskly/Taskly "$@"
EOF
chmod +x "$STAGING/usr/bin/taskly"
# .desktop 文件(Exec 指向启动脚本)
sed 's|Exec=Taskly|Exec=/usr/bin/taskly|' packaging/linux/taskly.desktop > "$STAGING/usr/share/applications/taskly.desktop"
# control 文件(用实际版本号)
sed "s/Version: 0.3.0/Version: $VERSION/" packaging/linux/control > "$STAGING/DEBIAN/control"
# 构建 .deb
dpkg-deb --root-owner-group --build "$STAGING" "taskly-${{ env.VERSION }}-linux-x64.deb"
ls -la *.deb
- uses: actions/upload-artifact@v4
with:
name: taskly-linux-x64
path: |
*.AppImage
*.deb
# ============================================================
# Release: 收集所有产物,创建 GitHub Release
# ============================================================
release:
name: Create Release
needs: [build-macos, build-windows, build-linux]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps:
- uses: actions/checkout@v4
- name: Get version
shell: bash
run: |
VERSION=${GITHUB_REF#refs/tags/v}
echo "VERSION=$VERSION" >> $GITHUB_ENV
- uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: List artifacts
shell: bash
run: find artifacts -type f
- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: |
artifacts/*.dmg
artifacts/*.exe
artifacts/*.AppImage
artifacts/*.deb
name: Release v${{ env.VERSION }}
body: |
## Downloads
### macOS
- `taskly-${{ env.VERSION }}-macos-arm64.dmg` (Apple Silicon)
- `taskly-${{ env.VERSION }}-macos-x64.dmg` (Intel)
### Windows
- `taskly-${{ env.VERSION }}-windows-x64.exe` (Setup installer)
### Linux
- `taskly-${{ env.VERSION }}-linux-x64.AppImage` (zero-install)
- `taskly-${{ env.VERSION }}-linux-x64.deb` (Debian/Ubuntu)
---
*Release notes are automatically generated.*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}