Skip to content

macOS install: guided step-by-step installer + DMG quick guide + drag… #22

macOS install: guided step-by-step installer + DMG quick guide + drag…

macOS install: guided step-by-step installer + DMG quick guide + drag… #22

Workflow file for this run

name: Native Release
# Tag-triggered release pipeline for the native apps. Tag `vX.Y.Z` to build
# and attach artifacts to a GitHub Release.
#
# IMPORTANT: artifacts remain UNSIGNED until the signing/notarization secrets
# are wired in (see COMMERCIAL-CHECKLIST.md). This workflow is suitable for
# internal/preview validation; a paid stable release must add platform signing.
on:
push:
tags:
- 'v*'
permissions:
contents: write
jobs:
preflight:
name: Release preflight
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Verify tag and platform versions
run: bash scripts/check-release-version.sh "${GITHUB_REF_NAME}"
macos:
name: macOS (universal .dmg)
runs-on: macos-15
needs: preflight
steps:
- uses: actions/checkout@v4
- name: Swift version
run: swift --version
- name: Contract tests
working-directory: apps/macos
run: swift test
- name: Build + package (arm64 + x86_64)
working-directory: apps/macos
run: scripts/make-app.sh --universal /tmp/dist
- name: Verify bundle
run: |
test -x /tmp/dist/Taskly.app/Contents/MacOS/Taskly
/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' /tmp/dist/Taskly.app/Contents/Info.plist | grep -qx "$(cat VERSION)"
lipo -archs /tmp/dist/Taskly.app/Contents/MacOS/Taskly | grep -q arm64
lipo -archs /tmp/dist/Taskly.app/Contents/MacOS/Taskly | grep -q x86_64
- name: Create DMG
run: |
# Bundle the double-clickable installer beside the app.
mkdir -p /tmp/dist/pkg
mv /tmp/dist/Taskly.app /tmp/dist/pkg/Taskly.app
mv "/tmp/dist/安装 Taskly.command" "/tmp/dist/pkg/安装 Taskly.command"
hdiutil create -volname Taskly -srcfolder /tmp/dist/pkg \
-ov -format UDZO "Taskly-${{ github.ref_name }}-macos.dmg"
- uses: actions/upload-artifact@v4
with:
name: macos-dmg
path: Taskly-*.dmg
windows:
name: Windows (portable x64)
runs-on: windows-latest
needs: preflight
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Publish self-contained
run: >
dotnet publish apps/windows/Taskly/Taskly.csproj -c Release
-r win-x64 --self-contained true
-p:Platform=x64
-p:WindowsAppSDKSelfContained=true
-o publish/win-x64
- name: CLI release smoke
shell: bash
run: |
DB=$(mktemp -d)/tasks.db
B=publish/win-x64/Taskly.exe
"$B" mklist "release-smoke" --db "$DB" --json | grep -q '"id"'
ID=$("$B" add "release smoke" --due tomorrow --db "$DB" --quiet)
"$B" list --db "$DB" --json | grep -q 'release smoke'
"$B" done "$ID" --db "$DB" --json --quiet | grep -q '"completed": true'
- name: Zip
run: Compress-Archive -Path publish/win-x64/* -DestinationPath "Taskly-${{ github.ref_name }}-windows-x64.zip"
- name: Pack Velopack release (online updates)
shell: bash
run: |
dotnet tool install -g vpk --version 1.0.1
VER="${GITHUB_REF_NAME#v}"
vpk pack --packId Taskly --packVersion "$VER" \
--packDir publish/win-x64 --mainExe Taskly.exe --packTitle Taskly
mkdir -p vpk-dist
find Releases -type f \( -name "*.nupkg" -o -name "RELEASES" -o -name "*Setup.exe" \) \
-exec cp {} vpk-dist/ \;
ls -la vpk-dist
- uses: actions/upload-artifact@v4
with:
name: windows-zip
path: |
Taskly-*.zip
vpk-dist/*
linux:
name: Linux (tarball)
runs-on: ubuntu-latest
needs: preflight
steps:
- uses: actions/checkout@v4
- name: Install toolchain
run: |
sudo apt-get update
sudo apt-get install -y valac meson libgtk-4-dev libadwaita-1-dev \
libsqlite3-dev libnotify-dev pkg-config
- name: Build + test + install into staging dir
working-directory: apps/linux
run: |
meson setup build --buildtype=release --prefix=/usr
meson compile -C build
meson test -C build --verbose
DESTDIR="$(pwd)/staging" meson install -C build
- name: CLI release smoke
working-directory: apps/linux
run: |
DB=$(mktemp -d)/tasks.db
B=build/taskly
$B mklist "release-smoke" --db "$DB" --json | grep -q '"id"'
ID=$($B add "release smoke" --due tomorrow --db "$DB" --quiet)
$B list --db "$DB" --json | grep -q 'release smoke'
$B done "$ID" --db "$DB" --json --quiet | grep -q '"completed": true'
- name: Tarball
working-directory: apps/linux
run: |
tar -czf "../../Taskly-${{ github.ref_name }}-linux-x64.tar.gz" -C staging .
- uses: actions/upload-artifact@v4
with:
name: linux-tarball
path: Taskly-*.tar.gz
release:
name: Attach artifacts to GitHub Release
runs-on: ubuntu-latest
needs: [macos, windows, linux]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/download-artifact@v4
with:
merge-multiple: true
path: dist
- name: Create release and upload
env:
GH_TOKEN: ${{ github.token }}
run: |
# Flatten artifact subdirectories (vpk-dist) before uploading.
find dist -mindepth 2 -type f -exec mv {} dist/ \; 2>/dev/null || true
find dist -mindepth 1 -type d -empty -delete
PREV_TAG="$(git describe --tags --abbrev=0 "${{ github.ref_name }}^" 2>/dev/null || echo "")"
if gh release view "${{ github.ref_name }}" >/dev/null 2>&1; then
gh release upload "${{ github.ref_name }}" --clobber dist/*
elif [ -n "$PREV_TAG" ]; then
gh release create "${{ github.ref_name }}" dist/* \
--title "${{ github.ref_name }}" \
--generate-notes --notes-start-tag "$PREV_TAG"
else
# First release in the repository: no previous tag exists.
gh release create "${{ github.ref_name }}" dist/* \
--title "${{ github.ref_name }}" --generate-notes
fi