feat(packaging): add macOS bundle metadata, release packaging and application icon

This commit is contained in:
yyc12345 committed 2026-10-04 16:08:06 +08:00
1 parent 90a7531a27
commit 97f79db3f1
11 files changed
+160 -19

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
# Shell scripts run under bash on every CI runner, including Windows checkouts with autocrlf.
*.sh text eol=lf
+30 -17
View File
@@ -1,20 +1,25 @@
# Manual-only release build (PLAN §7.2): no push or pull_request trigger.
# Each RID job runs build -> test -> publish/pack -> upload; a failing step
# skips the rest of that job, so a RID whose tests fail produces no artifact.
# No GitHub Release is created.
name: Build
# Manual trigger only. There is no push/pull_request trigger on purpose:
# the project must not depend on push-triggered CI.
on:
workflow_dispatch:
# Least privilege: the workflow only reads the repository and uploads artifacts.
permissions:
contents: read
env:
DOTNET_NOLOGO: "true"
DOTNET_CLI_TELEMETRY_OPTOUT: "true"
jobs:
build:
name: ${{ matrix.rid }}
runs-on: ${{ matrix.os }}
strategy:
# One failing RID must not cancel the others.
# Every RID stands on its own: one failure does not cancel the others.
fail-fast: false
matrix:
include:
@@ -22,35 +27,43 @@ jobs:
os: windows-latest
- rid: linux-x64
os: ubuntu-latest
- rid: osx-x64
os: macos-15-intel
- rid: osx-arm64
os: macos-latest
os: macos-15
defaults:
run:
shell: bash
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup .NET
- name: Set up .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 10.0.x
- name: Restore
run: dotnet restore YKanBan.slnx
- name: Build
run: dotnet build YKanBan.slnx -c Release --no-restore
run: dotnet build YKanBan.slnx -c Release
# A failing test fails the job, so the publish and upload steps below are
# skipped and this RID produces no artifact.
- name: Test
run: dotnet test YKanBan.slnx -c Release --no-build --no-restore
run: dotnet test YKanBan.slnx -c Release --no-build
- name: Publish
run: dotnet publish YKanBan/YKanBan.csproj -c Release -r ${{ matrix.rid }} --self-contained true -o publish/${{ matrix.rid }}
run: >
dotnet publish YKanBan/YKanBan.csproj -c Release -r ${{ matrix.rid }}
--self-contained -o publish/${{ matrix.rid }}
- name: Pack
id: pack
run: |
version="$(dotnet msbuild YKanBan/YKanBan.csproj -getProperty:Version)"
bash packaging/package.sh ${{ matrix.rid }} publish/${{ matrix.rid }} dist "$version"
echo "name=YKanBan-$version-${{ matrix.rid }}" >> "$GITHUB_OUTPUT"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: YKanBan-${{ matrix.rid }}
path: publish/${{ matrix.rid }}
name: ${{ steps.pack.outputs.name }}
path: dist/*
if-no-files-found: error
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 yyc12345
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+10 -1
View File
@@ -4,11 +4,20 @@ A personal, local/offline kanban board. Cross-platform desktop app built with Av
See [USAGE.md](USAGE.md) for workspaces, backups, the search syntax and command-line usage.
## Build and test
## Building
Requires the .NET 10 SDK.
```
dotnet build YKanBan.slnx
dotnet test YKanBan.slnx
dotnet run --project YKanBan -- <path>
```
Packages are pinned in `YKanBan/YKanBan.csproj`.
Release archives for win-x64, linux-x64, osx-x64 and osx-arm64 are produced by the manually triggered workflow in `.github/workflows/build.yml`; `packaging/package.sh` packs one published RID.
## License
MIT — see [LICENSE](LICENSE).
Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

+1 -1
View File
@@ -6,7 +6,7 @@
mc:Ignorable="d" d:DesignWidth="1000" d:DesignHeight="640"
x:Class="YKanBan.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
Icon="/Assets/avalonia-logo.ico"
Icon="/Assets/ykanban.ico"
Title="{Binding Title}"
Width="1000" Height="640" MinWidth="720" MinHeight="480">
+1
View File
@@ -7,6 +7,7 @@
<Nullable>enable</Nullable>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ApplicationManifest>app.manifest</ApplicationManifest>
<ApplicationIcon>Assets\ykanban.ico</ApplicationIcon>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
</PropertyGroup>
+26
View File
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>YKanBan</string>
<key>CFBundleDisplayName</key>
<string>YKanBan</string>
<key>CFBundleIdentifier</key>
<string>cn.blumia.code.yyc12345.ykanban</string>
<key>CFBundleIconFile</key>
<string>ykanban.icns</string>
<key>CFBundleExecutable</key>
<string>YKanBan</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>@VERSION@</string>
<key>CFBundleVersion</key>
<string>@VERSION@</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>
Binary file not shown.
+69
View File
@@ -0,0 +1,69 @@
#!/usr/bin/env bash
# Packs one published RID into a release archive.
#
# packaging/package.sh <rid> <publish-dir> <output-dir> <version>
#
# win-x64 -> YKanBan-<version>-win-x64.zip (folder YKanBan-<version>-win-x64/)
# linux-x64 -> YKanBan-<version>-linux-x64.tar.gz (folder YKanBan-<version>-linux-x64/)
# osx-* -> YKanBan-<version>-<rid>.tar.gz (YKanBan.app bundle, ad-hoc signed when possible)
#
# tar.gz keeps the executable bit, which a plain zip artifact upload would lose.
set -euo pipefail
if [ "$#" -ne 4 ]; then
echo "usage: $0 <rid> <publish-dir> <output-dir> <version>" >&2
exit 2
fi
rid="$1"
publish_dir="$(cd "$2" && pwd)"
mkdir -p "$3"
output_dir="$(cd "$3" && pwd)"
version="$4"
script_dir="$(cd "$(dirname "$0")" && pwd)"
name="YKanBan-${version}-${rid}"
staging="$(mktemp -d)"
trap 'rm -rf "$staging"' EXIT
case "$rid" in
win-*)
cp -R "$publish_dir" "$staging/$name"
rm -f "$output_dir/$name.zip"
# 7-Zip ships on the Windows runners and writes '/' entry separators;
# Windows PowerShell 5.1's Compress-Archive writes '\', which breaks
# extraction outside Windows.
if ! command -v 7z > /dev/null 2>&1; then
echo "7z not found" >&2
exit 1
fi
(cd "$staging" && 7z a -tzip -bso0 -bsp0 "$output_dir/$name.zip" "$name")
;;
linux-*)
cp -R "$publish_dir" "$staging/$name"
chmod +x "$staging/$name/YKanBan"
tar -C "$staging" -czf "$output_dir/$name.tar.gz" "$name"
;;
osx-*)
app="$staging/YKanBan.app"
mkdir -p "$app/Contents/MacOS" "$app/Contents/Resources"
cp -R "$publish_dir/." "$app/Contents/MacOS/"
cp "$script_dir/macos/ykanban.icns" "$app/Contents/Resources/"
chmod +x "$app/Contents/MacOS/YKanBan"
sed "s/@VERSION@/${version}/g" "$script_dir/macos/Info.plist" > "$app/Contents/Info.plist"
if command -v codesign > /dev/null 2>&1; then
# Ad-hoc signature for the bundle. Not fatal: the SDK already ad-hoc
# signs the apphost, which is all arm64 needs to run, and --deep may
# trip over the non-Mach-O files in Contents/MacOS.
if ! codesign --force --deep --sign - "$app"; then
echo "warning: ad-hoc signing of YKanBan.app failed; packing it unsigned" >&2
fi
fi
tar -C "$staging" -czf "$output_dir/$name.tar.gz" YKanBan.app
;;
*)
echo "unsupported RID: $rid" >&2
exit 2
;;
esac
echo "packed $rid -> $output_dir"