fix(ios): focus-collapse composer + whole-round ensemble summary #178
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |