ci: build unsigned desktop artifacts without signing secrets (#1530)
This commit is contained in:
@@ -24,8 +24,10 @@ name: release
|
||||
# Each package (kandev + 5 @kdlbs/runtime-* packages) must have this workflow
|
||||
# configured as its trusted publisher on npmjs.com (Settings → Publishing access).
|
||||
#
|
||||
# Required secrets:
|
||||
# Required secrets for public releases:
|
||||
# HOMEBREW_TAP_DEPLOY_KEY — SSH private key for kdlbs/homebrew-kandev deploy key
|
||||
# Optional secrets for signed desktop artifacts. If these are incomplete, the
|
||||
# workflow still builds unsigned desktop artifacts and warns in release notes.
|
||||
# APPLE_CERTIFICATE / APPLE_CERTIFICATE_PASSWORD / KEYCHAIN_PASSWORD — macOS Developer ID signing
|
||||
# APPLE_ID / APPLE_PASSWORD / APPLE_TEAM_ID or APPLE_API_KEY / APPLE_API_ISSUER / APPLE_API_KEY_P8 — macOS notarization
|
||||
# WINDOWS_CERTIFICATE / WINDOWS_CERTIFICATE_PASSWORD — Windows installer signing
|
||||
@@ -46,10 +48,6 @@ on:
|
||||
description: "Dry run (no PR, tag, npm publish, or tap update)"
|
||||
type: boolean
|
||||
default: false
|
||||
allow_unsigned_desktop:
|
||||
description: "Allow unsigned macOS/Windows desktop artifacts; still publishes unless validation-only is checked"
|
||||
type: boolean
|
||||
default: false
|
||||
desktop_validation_only:
|
||||
description: "Build desktop artifacts only (no PR, tag, publish, npm, or tap update)"
|
||||
type: boolean
|
||||
@@ -279,10 +277,9 @@ jobs:
|
||||
NEXT: ${{ steps.compute.outputs.version }}
|
||||
TAG: ${{ steps.compute.outputs.tag }}
|
||||
REF: ${{ steps.compute.outputs.ref }}
|
||||
ALLOW_UNSIGNED_DESKTOP: ${{ inputs.allow_unsigned_desktop }}
|
||||
run: |
|
||||
echo "Desktop validation for $TAG / $NEXT."
|
||||
echo "Unsigned desktop artifacts allowed: $ALLOW_UNSIGNED_DESKTOP."
|
||||
echo "Desktop signing is automatic: complete signing inputs produce signed artifacts; otherwise artifacts are unsigned."
|
||||
echo "No release PR, tag, GitHub release, public container tags, npm publish, or Homebrew update will be created."
|
||||
echo "Build jobs will check out $REF."
|
||||
|
||||
@@ -536,7 +533,6 @@ jobs:
|
||||
- name: Configure macOS signing and notarization
|
||||
if: startsWith(matrix.platform, 'macos-')
|
||||
env:
|
||||
ALLOW_UNSIGNED_DESKTOP: ${{ inputs.allow_unsigned_desktop }}
|
||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
||||
@@ -550,37 +546,12 @@ jobs:
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
if [ "$ALLOW_UNSIGNED_DESKTOP" = "true" ]; then
|
||||
echo "::notice::Unsigned desktop artifacts requested; skipping macOS signing and notarization setup."
|
||||
if ! bash scripts/release/desktop-signing-ready.sh macos >/dev/null 2>&1; then
|
||||
echo "MACOS_SIGNING_ENABLED=false" >> "$GITHUB_ENV"
|
||||
echo "::notice::macOS signing/notarization inputs are incomplete; building unsigned desktop artifact."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
missing=()
|
||||
for key in APPLE_CERTIFICATE APPLE_CERTIFICATE_PASSWORD KEYCHAIN_PASSWORD; do
|
||||
if [ -z "${!key:-}" ]; then
|
||||
missing+=("$key")
|
||||
fi
|
||||
done
|
||||
|
||||
apple_id_notarization=0
|
||||
if [ -n "${APPLE_ID:-}" ] && [ -n "${APPLE_PASSWORD:-}" ] && [ -n "${APPLE_TEAM_ID:-}" ]; then
|
||||
apple_id_notarization=1
|
||||
fi
|
||||
|
||||
api_key_notarization=0
|
||||
if [ -n "${APPLE_API_KEY:-}" ] && [ -n "${APPLE_API_ISSUER:-}" ] && [ -n "${APPLE_API_KEY_P8:-}" ]; then
|
||||
api_key_notarization=1
|
||||
fi
|
||||
|
||||
if [ "$apple_id_notarization" -eq 0 ] && [ "$api_key_notarization" -eq 0 ]; then
|
||||
missing+=("APPLE_ID/APPLE_PASSWORD/APPLE_TEAM_ID or APPLE_API_KEY/APPLE_API_ISSUER/APPLE_API_KEY_P8")
|
||||
fi
|
||||
|
||||
if [ "${#missing[@]}" -gt 0 ]; then
|
||||
echo "::error::Public macOS desktop releases require signing and notarization inputs: ${missing[*]}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
certificate_path="$RUNNER_TEMP/kandev-developer-id.p12"
|
||||
python3 - <<'PY'
|
||||
import base64
|
||||
@@ -609,8 +580,9 @@ jobs:
|
||||
fi
|
||||
cert_id="$(echo "$cert_info" | awk -F'"' '{print $2}')"
|
||||
echo "APPLE_SIGNING_IDENTITY=$cert_id" >> "$GITHUB_ENV"
|
||||
echo "MACOS_SIGNING_ENABLED=true" >> "$GITHUB_ENV"
|
||||
|
||||
if [ "$api_key_notarization" -eq 1 ]; then
|
||||
if [ -n "${APPLE_API_KEY:-}" ] && [ -n "${APPLE_API_ISSUER:-}" ] && [ -n "${APPLE_API_KEY_P8:-}" ]; then
|
||||
private_keys_dir="$RUNNER_TEMP/private_keys"
|
||||
mkdir -p "$private_keys_dir"
|
||||
printf '%s\n' "$APPLE_API_KEY_P8" > "$private_keys_dir/AuthKey_${APPLE_API_KEY}.p8"
|
||||
@@ -618,7 +590,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Sign macOS desktop runtime binaries
|
||||
if: startsWith(matrix.platform, 'macos-') && !inputs.allow_unsigned_desktop
|
||||
if: startsWith(matrix.platform, 'macos-') && env.MACOS_SIGNING_ENABLED == 'true'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
runtime_bin="apps/desktop/src-tauri/resources/kandev/bin"
|
||||
@@ -632,8 +604,22 @@ jobs:
|
||||
codesign --verify --strict --verbose=2 "$path"
|
||||
done
|
||||
|
||||
- name: Detect Windows signing inputs
|
||||
if: matrix.platform == 'windows-x64'
|
||||
env:
|
||||
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
|
||||
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if bash scripts/release/desktop-signing-ready.sh windows >/dev/null 2>&1; then
|
||||
echo "WINDOWS_SIGNING_ENABLED=true" >> "$GITHUB_ENV"
|
||||
else
|
||||
echo "WINDOWS_SIGNING_ENABLED=false" >> "$GITHUB_ENV"
|
||||
echo "::notice::Windows signing inputs are incomplete; building unsigned desktop artifact."
|
||||
fi
|
||||
|
||||
- name: Sign Windows desktop runtime binaries
|
||||
if: matrix.platform == 'windows-x64' && !inputs.allow_unsigned_desktop
|
||||
if: matrix.platform == 'windows-x64' && env.WINDOWS_SIGNING_ENABLED == 'true'
|
||||
shell: pwsh
|
||||
env:
|
||||
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
|
||||
@@ -662,14 +648,13 @@ jobs:
|
||||
APPLE_PROVIDER_SHORT_NAME: ${{ secrets.APPLE_PROVIDER_SHORT_NAME }}
|
||||
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
|
||||
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
|
||||
ALLOW_UNSIGNED_DESKTOP: ${{ inputs.allow_unsigned_desktop }}
|
||||
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
|
||||
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
|
||||
WINDOWS_TIMESTAMP_URL: ${{ secrets.WINDOWS_TIMESTAMP_URL }}
|
||||
WINDOWS_SIGNTOOL_PATH: ${{ secrets.WINDOWS_SIGNTOOL_PATH }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [ "$ALLOW_UNSIGNED_DESKTOP" = "true" ]; then
|
||||
if [ "${MACOS_SIGNING_ENABLED:-false}" != "true" ]; then
|
||||
unset APPLE_CERTIFICATE
|
||||
unset APPLE_CERTIFICATE_PASSWORD
|
||||
unset APPLE_ID
|
||||
@@ -680,6 +665,8 @@ jobs:
|
||||
unset APPLE_API_ISSUER
|
||||
unset APPLE_API_KEY_PATH
|
||||
unset APPLE_SIGNING_IDENTITY
|
||||
fi
|
||||
if [ "${WINDOWS_SIGNING_ENABLED:-false}" != "true" ]; then
|
||||
unset WINDOWS_CERTIFICATE
|
||||
unset WINDOWS_CERTIFICATE_PASSWORD
|
||||
unset WINDOWS_TIMESTAMP_URL
|
||||
@@ -693,7 +680,7 @@ jobs:
|
||||
--bundles "${{ matrix.tauri_bundles }}"
|
||||
|
||||
- name: Sign Windows desktop artifacts
|
||||
if: matrix.platform == 'windows-x64' && !inputs.allow_unsigned_desktop
|
||||
if: matrix.platform == 'windows-x64' && env.WINDOWS_SIGNING_ENABLED == 'true'
|
||||
shell: pwsh
|
||||
env:
|
||||
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
|
||||
@@ -701,15 +688,6 @@ jobs:
|
||||
WINDOWS_TIMESTAMP_URL: ${{ secrets.WINDOWS_TIMESTAMP_URL }}
|
||||
WINDOWS_SIGNTOOL_PATH: ${{ secrets.WINDOWS_SIGNTOOL_PATH }}
|
||||
run: |
|
||||
$missing = @()
|
||||
if ([string]::IsNullOrWhiteSpace($env:WINDOWS_CERTIFICATE)) { $missing += "WINDOWS_CERTIFICATE" }
|
||||
if ([string]::IsNullOrWhiteSpace($env:WINDOWS_CERTIFICATE_PASSWORD)) { $missing += "WINDOWS_CERTIFICATE_PASSWORD" }
|
||||
|
||||
if ($missing.Count -gt 0) {
|
||||
Write-Error "Public Windows desktop releases require signing inputs: $($missing -join ', ')"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$certificatePath = Join-Path $env:RUNNER_TEMP "kandev-code-signing.pfx"
|
||||
[IO.File]::WriteAllBytes($certificatePath, [Convert]::FromBase64String($env:WINDOWS_CERTIFICATE))
|
||||
|
||||
@@ -1185,13 +1163,40 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Add unsigned desktop warning to release notes
|
||||
if: ${{ inputs.allow_unsigned_desktop }}
|
||||
env:
|
||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
|
||||
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
|
||||
APPLE_API_KEY_P8: ${{ secrets.APPLE_API_KEY_P8 }}
|
||||
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
|
||||
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
unsigned=()
|
||||
if ! bash scripts/release/desktop-signing-ready.sh macos >/dev/null 2>&1; then
|
||||
unsigned+=("macOS")
|
||||
fi
|
||||
if ! bash scripts/release/desktop-signing-ready.sh windows >/dev/null 2>&1; then
|
||||
unsigned+=("Windows")
|
||||
fi
|
||||
if [ "${#unsigned[@]}" -eq 0 ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
platforms="${unsigned[0]}"
|
||||
for ((i = 1; i < ${#unsigned[@]}; i++)); do
|
||||
platforms="$platforms, ${unsigned[$i]}"
|
||||
done
|
||||
tmp="$(mktemp)"
|
||||
{
|
||||
echo "> [!WARNING]"
|
||||
echo "> macOS and Windows desktop installers in this release are unsigned."
|
||||
echo "> $platforms desktop installers in this release are unsigned development builds."
|
||||
echo "> They may require manual OS security bypasses and are not trusted downloads."
|
||||
echo
|
||||
cat RELEASE_NOTES.md
|
||||
|
||||
Reference in New Issue
Block a user