Skip to content

v0.7.0: Reminders-style theme redesign (replace Anthropic warm palette) #42

v0.7.0: Reminders-style theme redesign (replace Anthropic warm palette)

v0.7.0: Reminders-style theme redesign (replace Anthropic warm palette) #42

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"
# Ad-hoc 签名(无 Apple Developer 账号):让 macOS Gatekeeper 显示
# "无法验证开发者"而非误导性的"已损坏"。用户右键打开即可运行。
- name: Ad-hoc code sign
shell: bash
run: |
# 签名所有 Mach-O 二进制(self-contained 发布包含 .NET 运行时)
find "Taskly.app/Contents/MacOS" -type f -exec sh -c '
file "$1" | grep -q "Mach-O" && codesign --force --sign - "$1" 2>/dev/null || true
' _ {} \;
# 整体签名 .app bundle
codesign --force --deep --sign - "Taskly.app"
# 验证
codesign --verify --verbose=2 "Taskly.app" 2>&1 || true
# 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 app icon
run: |
python3 -m pip install pillow
python3 packaging/macos/make_icon.py /tmp/taskly-icon-build
cp /tmp/taskly-icon-build/icon.icns "Taskly.app/Contents/Resources/icon.icns"
- 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(--icon 让 Setup.exe 和安装后的快捷方式显示 Taskly 图标)
vpk pack -u Taskly -v ${{ env.VERSION }} -p publish -e Taskly.exe -o build --icon src/Taskly/taskly.ico --verbose
- name: Rename to match platform naming convention
shell: pwsh
run: |
# Velopack 输出 Taskly-{version}-win-x64-Setup.exe 或类似名称,
# 统一改为 taskly-{version}-windows-x64.exe 与其他平台一致。
$src = Get-ChildItem build/*-Setup.exe | Select-Object -First 1
if (-not $src) { $src = Get-ChildItem build/*.exe | Select-Object -First 1 }
if ($src) {
$dst = "taskly-${{ env.VERSION }}-windows-x64.exe"
Copy-Item $src.FullName $dst
Write-Host "Renamed: $($src.Name) -> $dst"
}
- uses: actions/upload-artifact@v4
with:
name: taskly-windows-x64
path: 'taskly-*-windows-x64.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@/$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)
> **首次打开提示**:Taskly 尚未经过 Apple 公证。安装后若提示"无法打开"或"已损坏",
> 请在终端执行:`xattr -cr /Applications/Taskly.app`
> 然后即可正常打开。
>
> **First launch**: Taskly is not yet notarized by Apple. If macOS says the app
> is "damaged" or "can't be opened", run this in Terminal:
> `xattr -cr /Applications/Taskly.app`
### 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 }}