Skip to content

ci: 尝试 deb、pkg 构建 #4

ci: 尝试 deb、pkg 构建

ci: 尝试 deb、pkg 构建 #4

Workflow file for this run

name: Build & Publish
on:
push:
branches:
- master
- dev/v3
workflow_dispatch:
inputs:
release_tag:
description: "发布标签(例如 1.0.0.0)"
required: true
type: string
permissions:
contents: read
jobs:
build_desktop:
name: Build_Desktop_${{ matrix.os }}_${{ matrix.arch }}_${{ matrix.build_type }}
runs-on: ${{ matrix.os == 'linux' && 'ubuntu-24.04' || (matrix.os == 'macos' && 'macos-15' || 'windows-2022') }}
strategy:
fail-fast: false
matrix:
os: [windows, linux, macos]
arch: [x64, x86, arm64]
build_type: [full, selfContained]
exclude:
- os: linux
arch: x86
- os: macos
arch: x86
- os: linux
build_type: full
- os: macos
build_type: full
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.release_tag || github.ref }}
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: 10.0.x
- name: Restore
shell: pwsh
env:
RID: ${{ matrix.os == 'windows' && format('win-{0}', matrix.arch) || (matrix.os == 'linux' && format('linux-{0}', matrix.arch) || format('osx-{0}', matrix.arch)) }}
run: dotnet restore SecRandom.Desktop/SecRandom.Desktop.csproj -r $env:RID
- name: Publish Desktop
shell: pwsh
env:
RID: ${{ matrix.os == 'windows' && format('win-{0}', matrix.arch) || (matrix.os == 'linux' && format('linux-{0}', matrix.arch) || format('osx-{0}', matrix.arch)) }}
SELF_CONTAINED: ${{ matrix.build_type == 'selfContained' }}
MODE: ${{ matrix.build_type }}
run: |
$outDir = "bin/$env:RID-$env:MODE"
dotnet publish SecRandom.Desktop/SecRandom.Desktop.csproj `
-c Release `
-r $env:RID `
--self-contained $env:SELF_CONTAINED `
-p:PublishTrimmed=false `
-p:UseAppHost=true `
--no-restore `
-o $outDir
- name: Pack Zip
shell: pwsh
env:
RID: ${{ matrix.os == 'windows' && format('win-{0}', matrix.arch) || (matrix.os == 'linux' && format('linux-{0}', matrix.arch) || format('osx-{0}', matrix.arch)) }}
MODE: ${{ matrix.build_type }}
run: |
New-Item -ItemType Directory -Path dist -Force | Out-Null
$source = "bin/$env:RID-$env:MODE/*"
$target = "dist/SecRandom_desktop_$env:RID`_$env:MODE.zip"
Compress-Archive -Path $source -DestinationPath $target -Force
- name: Get Latest Tag
id: get_tag
if: ${{ github.event_name != 'workflow_dispatch' && matrix.os == 'windows' }}
shell: pwsh
run: |
$latestTag = git describe --tags --abbrev=0
echo "LATEST_TAG=$latestTag" >> $env:GITHUB_OUTPUT
echo "version_no_v=${version_no_v}" >> "$GITHUB_OUTPUT"
echo "Latest tag: $latestTag"
- name: Install Inno Setup Chinese Language
if: ${{ matrix.os == 'windows' }}
run: |
$langUrl = "https://raw.githubusercontent.com/kira-96/Inno-Setup-Chinese-Simplified-Translation/main/ChineseSimplified.isl"
$langPath = "C:\Program Files (x86)\Inno Setup 6\Languages\ChineseSimplified.isl"
$langDir = "C:\Program Files (x86)\Inno Setup 6\Languages"
if (!(Test-Path $langDir)) {
New-Item -ItemType Directory -Path $langDir -Force
}
Invoke-WebRequest -Uri $langUrl -OutFile $langPath
echo "Downloaded Chinese Language: $langPath"
- name: Build Setup
if: ${{ matrix.os == 'windows' }}
shell: pwsh
env:
VERSION: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.release_tag || steps.get_tag.outputs.LATEST_TAG }}
ARCH: ${{ matrix.arch }}
RID: ${{ matrix.os == 'windows' && format('win-{0}', matrix.arch) || (matrix.os == 'linux' && format('linux-{0}', matrix.arch) || format('osx-{0}', matrix.arch)) }}
MODE: ${{ matrix.build_type }}
run: |
$outDir = "bin/$env:RID-$env:MODE"
$issContent = Get-Content -Path "Setup.iss" -Raw
$updatedContent = $issContent -replace 'APP_VERSION', $env:VERSION
$updatedContent = $updatedContent -replace 'APP_OUTDIR', $outDir
Set-Content -Path "Setup.iss" -Value $updatedContent -NoNewline
New-Item -ItemType Directory -Path "SetupOutput" -Force | Out-Null
& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" Setup.iss `
/F"SecRandom_setup_$env:ARCH-$env:MODE" `
/O"SetupOutput"
- name: Build Linux deb
if: ${{ matrix.os == 'linux' }}
env:
RID: ${{ matrix.os == 'windows' && format('win-{0}', matrix.arch) || (matrix.os == 'linux' && format('linux-{0}', matrix.arch) || format('osx-{0}', matrix.arch)) }}
MODE: ${{ matrix.build_type }}
shell: bash
run: |
set -euo pipefail
version_no_v="${{ steps.get_tag.outputs.version_no_v }}"
mkdir -p dist
deb_arch="amd64"
case "${{ matrix.arch }}" in
x64) deb_arch="amd64" ;;
arm64) deb_arch="arm64" ;;
esac
pkgroot="$(pwd)/pkgroot"
rm -rf "$pkgroot"
mkdir -p "$pkgroot/DEBIAN"
mkdir -p "$pkgroot/usr/lib/secrandom"
mkdir -p "$pkgroot/usr/bin"
mkdir -p "$pkgroot/usr/share/applications"
mkdir -p "$pkgroot/usr/share/icons/hicolor/256x256/apps"
cp -a "bin/${RID}-${MODE}/." "$pkgroot/usr/lib/secrandom/"
chmod +x "$pkgroot/usr/lib/secrandom/SecRandom.Desktop" || true
cat > "$pkgroot/usr/bin/secrandom" << 'EOF'
#!/bin/sh
exec /usr/lib/secrandom/SecRandom.Desktop "$@"
EOF
chmod +x "$pkgroot/usr/bin/secrandom"
cat > "$pkgroot/usr/share/applications/secrandom.desktop" << 'EOF'
[Desktop Entry]
Type=Application
Name=SecRandom
Exec=secrandom
Icon=secrandom
Categories=Utility;
Terminal=false
EOF
if [ -f "resources/secrandom-icon-paper.png" ]; then
cp "resources/secrandom-icon-paper.png" "$pkgroot/usr/share/icons/hicolor/256x256/apps/secrandom.png"
fi
cat > "$pkgroot/DEBIAN/control" << EOF
Package: secrandom
Version: ${version_no_v}
Section: utils
Priority: optional
Architecture: ${deb_arch}
Maintainer: SECTL
Description: SecRandom
EOF
dpkg-deb --build "$pkgroot" "dist/SecRandom_deb_${ARCH}-${MODE}.deb"
- name: Build macOS pkg
if: ${{ matrix.os == 'macos' }}
env:
RID: ${{ matrix.os == 'windows' && format('win-{0}', matrix.arch) || (matrix.os == 'linux' && format('linux-{0}', matrix.arch) || format('osx-{0}', matrix.arch)) }}
MODE: ${{ matrix.build_type }}
shell: bash
run: |
set -euo pipefail
version_no_v="${{ steps.get_tag.outputs.version_no_v }}"
mkdir -p dist
work="$(pwd)/macpkg"
rm -rf "$work"
mkdir -p "$work/bundle/SecRandom.app/Contents/MacOS"
mkdir -p "$work/bundle/SecRandom.app/Contents/Resources"
cp -a "bin/${RID}-${MODE}/." "$work/bundle/SecRandom.app/Contents/MacOS/"
chmod +x "$work/bundle/SecRandom.app/Contents/MacOS/SecRandom.Desktop" || true
cat > "$work/bundle/SecRandom.app/Contents/Info.plist" << EOF
<?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>SecRandom</string>
<key>CFBundleDisplayName</key><string>SecRandom</string>
<key>CFBundleIdentifier</key><string>top.sectl.secrandom</string>
<key>CFBundleVersion</key><string>${version_no_v}</string>
<key>CFBundleShortVersionString</key><string>${version_no_v}</string>
<key>CFBundleExecutable</key><string>SecRandom.Desktop</string>
<key>CFBundlePackageType</key><string>APPL</string>
<key>LSMinimumSystemVersion</key><string>11.0</string>
<key>CFBundleIconFile</key><string>AppIcon</string>
</dict>
</plist>
EOF
icon_png="resources/secrandom-icon-paper.png"
if [ -f "$icon_png" ]; then
iconset="$work/AppIcon.iconset"
mkdir -p "$iconset"
for size in 16 32 64 128 256 512; do
sips -z "$size" "$size" "$icon_png" --out "$iconset/icon_${size}x${size}.png" >/dev/null
done
for size in 16 32 128 256 512; do
double=$((size*2))
sips -z "$double" "$double" "$icon_png" --out "$iconset/icon_${size}x${size}@2x.png" >/dev/null
done
iconutil -c icns "$iconset" -o "$work/bundle/SecRandom.app/Contents/Resources/AppIcon.icns"
fi
pkgroot="$work/pkgroot"
mkdir -p "$pkgroot/Applications"
cp -a "$work/bundle/SecRandom.app" "$pkgroot/Applications/"
pkgbuild \
--root "$pkgroot" \
--identifier "top.sectl.secrandom" \
--version "$version_no_v" \
--install-location "/" \
"dist/SecRandom_pkg_${ARCH}-${MODE}.pkg"
- name: Upload Desktop Artifact
uses: actions/upload-artifact@v7
with:
name: desktop_${{ matrix.os }}_${{ matrix.arch }}_${{ matrix.build_type }}
path: dist/*.zip
archive: false
- name: Upload Setup Artifact
if: ${{ matrix.os == 'windows' }}
uses: actions/upload-artifact@v7
with:
name: setup_${{ matrix.os }}_${{ matrix.arch }}_${{ matrix.build_type }}
path: SetupOutput/*.exe
archive: false
- name: Upload deb Artifact
if: ${{ matrix.os == 'linux' }}
uses: actions/upload-artifact@v7
with:
name: deb_${{ matrix.os }}_${{ matrix.arch }}_${{ matrix.build_type }}
path: dist/*.deb
archive: false
- name: Upload pkg Artifact
if: ${{ matrix.os == 'macos' }}
uses: actions/upload-artifact@v7
with:
name: pkg_${{ matrix.os }}_${{ matrix.arch }}_${{ matrix.build_type }}
path: dist/*.pkg
archive: false
publish:
name: Publish_Release
runs-on: windows-2022
needs: [build_desktop]
if: ${{ always() && success('build_desktop') && github.event_name == 'workflow_dispatch' && github.event.inputs.release_tag && github.event_name != 'pull_request' }}
permissions:
contents: write
concurrency:
group: publish-public
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ github.event.inputs.release_tag }}
- name: Download Artifacts
uses: actions/download-artifact@v8
with:
path: ./out_artifacts
- name: Combine Artifacts
shell: pwsh
run: |
New-Item -ItemType Directory -Path ./out -Force | Out-Null
Get-ChildItem ./out_artifacts -Recurse -File -Include *.zip,*.apk,*.exe | ForEach-Object {
Copy-Item $_.FullName ./out -Force
}
Write-Host "Combined files:"
Get-ChildItem ./out -File | Select-Object Name, Length
- name: Generate Release Note
env:
tagName: ${{ github.event.inputs.release_tag }}
repoName: ${{ github.repository }}
run: pwsh -ep bypass ./scripts/gen-release-note.ps1
- name: Upload APP to release
uses: ncipollo/release-action@v1
with:
artifacts: "./out/*.zip,./out/*.exe,./out/*.deb,./out/*.pkg"
draft: true
bodyFile: ./release-note.md
token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ github.event.inputs.release_tag }}