feat(packaging): add macOS bundle metadata, release packaging and application icon
This commit is contained in:
1 parent
90a7531a27
commit
97f79db3f1
11 files changed
+160
-19
No files matched your search
@@ -0,0 +1,2 @@
|
||||
# Shell scripts run under bash on every CI runner, including Windows checkouts with autocrlf.
|
||||
*.sh text eol=lf
|
||||
+30
-17
@@ -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
|
||||
@@ -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.
|
||||
@@ -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 |
@@ -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">
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<ApplicationIcon>Assets\ykanban.ico</ApplicationIcon>
|
||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -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.
Executable
+69
@@ -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"
|
||||
Reference in new issue
Block a user