Skip to content

feat(ios): collapse the whole composer to one line when the keyboard … #177

feat(ios): collapse the whole composer to one line when the keyboard …

feat(ios): collapse the whole composer to one line when the keyboard … #177

Workflow file for this run

name: CI
on:
push:
pull_request:
workflow_dispatch:
inputs:
windows_release_tag:
description: "Tag to attach an UNSIGNED Windows installer to (e.g. v1.1.0). Blank = skip."
required: false
default: ""
linux_release_tag:
description: "Tag to attach an UNSIGNED Linux AppImage/deb to (e.g. v1.5.0). Blank = skip."
required: false
default: ""
jobs:
test:
name: Test (${{ matrix.name }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- name: Linux
os: ubuntu-latest
- name: macOS Apple Silicon
os: macos-15
- name: macOS Intel
os: macos-15-intel
- name: Windows
os: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run ci
# The native macOS bridge daemon gates Screen Watch / creative-app /
# editor actions, so its Swift unit tests must pass before changes land.
# The bridge is macOS-only and needs the Xcode Swift toolchain
# (preinstalled on GitHub macOS runners), so this step is gated to the
# macOS legs of the matrix and skipped on Linux/Windows. `swift test`
# exits non-zero on failure, which fails this job.
- name: Swift bridge tests (macOS only)
if: runner.os == 'macOS'
run: |
swift --version
npm run test:swift:bridge
notarized-macos-release:
name: Notarized macOS Release
runs-on: macos-15
if: startsWith(github.ref, 'refs/tags/v') && vars.ENABLE_MACOS_NOTARIZED_RELEASE == 'true'
env:
CSC_LINK: ${{ secrets.MACOS_CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.MACOS_CSC_KEY_PASSWORD }}
CSC_NAME: ${{ secrets.MACOS_CSC_NAME }}
APPLE_KEYCHAIN_PROFILE: ${{ secrets.APPLE_KEYCHAIN_PROFILE }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run security:deps
- run: npm run build:mac:notarized
- name: Verify notarized macOS artifacts
run: |
set -euo pipefail
test -d "dist/mac-universal/TaskWraith.app"
codesign --verify --deep --strict --verbose=2 "dist/mac-universal/TaskWraith.app"
spctl --assess --type execute --verbose=4 "dist/mac-universal/TaskWraith.app"
xcrun stapler validate "dist/mac-universal/TaskWraith.app"
for artifact in dist/*.dmg; do
test -f "$artifact"
xcrun stapler validate "$artifact"
done
signed-windows-release:
name: Signed Windows Release
runs-on: windows-latest
if: startsWith(github.ref, 'refs/tags/v') && vars.ENABLE_WINDOWS_SIGNED_RELEASE == 'true'
env:
CSC_LINK: ${{ secrets.WINDOWS_CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.WINDOWS_CSC_KEY_PASSWORD }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run security:deps
- run: npm run build:win:signed
- name: Verify signed Windows artifacts
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$installers = Get-ChildItem -Path dist -Filter "TaskWraith-*-win-*-setup.exe"
if ($installers.Count -lt 2) {
throw "Expected signed x64 and arm64 Windows installers in dist/."
}
foreach ($installer in $installers) {
$signature = Get-AuthenticodeSignature -FilePath $installer.FullName
if ($signature.Status -ne "Valid") {
throw "Invalid Authenticode signature for $($installer.Name): $($signature.Status)"
}
}
$version = (Get-Content package.json | ConvertFrom-Json).version
$feedPrefix = if ($version -match "-") { "beta" } else { "latest" }
foreach ($arch in @("x64", "arm64")) {
$feed = "dist/$feedPrefix-win-$arch.yml"
if (!(Test-Path $feed)) {
throw "Missing $feed"
}
}
unsigned-windows-build:
name: Unsigned Windows Build (testing)
runs-on: windows-latest
if: github.event_name == 'workflow_dispatch' && inputs.windows_release_tag != ''
permissions:
contents: write
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
# `build:win:nopublish` shares build:win's recipe (compile + electron-builder
# + packaged-app smoke + update-feed write/validate) but forces
# `--publish never`: electron-builder's implicit CI publish would otherwise
# try to attach to the `windows_release_tag` release and refuse any release
# created >2h ago. The packaged-app launch smoke now skips the arm64 binary
# on this x64 runner (it can't be executed natively) instead of crashing
# with "spawn UNKNOWN", so it is safe to run here. Assets are attached by the
# gh step below (gh release upload --clobber works on an existing release).
- run: npm run build:win:nopublish
- name: Upload unsigned Windows installers to the release
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$tag = "${{ inputs.windows_release_tag }}"
$assets = @(
Get-ChildItem -Path dist -Filter "TaskWraith-*-win-*-setup.exe"
Get-ChildItem -Path dist -Filter "TaskWraith-*-win-*-setup.exe.blockmap"
Get-ChildItem -Path dist -Filter "latest-win-*.yml"
) | ForEach-Object { $_.FullName }
if ($assets.Count -lt 2) {
throw "Expected Windows installers in dist/, found $($assets.Count)."
}
Write-Host "Uploading $($assets.Count) asset(s) to release $tag"
gh release upload $tag @assets --clobber
unsigned-linux-build:
name: Unsigned Linux Build (testing)
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' && inputs.linux_release_tag != ''
permissions:
contents: write
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
# AppImage + deb only — snap needs snapcraft (absent on the default
# runner). `--publish never` stops electron-builder's implicit CI publish
# from trying to attach to a release created >2h ago; the gh step below
# attaches the assets (gh release upload --clobber on an existing release).
- run: npm run build:linux:nopublish
- name: Upload unsigned Linux artifacts to the release
run: |
set -euo pipefail
tag="${{ inputs.linux_release_tag }}"
shopt -s nullglob
assets=(dist/*.AppImage dist/*.deb dist/latest-linux*.yml)
if [ ${#assets[@]} -lt 1 ]; then
echo "Expected Linux artifacts in dist/, found none."
exit 1
fi
echo "Uploading ${#assets[@]} asset(s) to release $tag"
gh release upload "$tag" "${assets[@]}" --clobber