Skip to content

fix(mobile): show Check for updates in Settings #30

fix(mobile): show Check for updates in Settings

fix(mobile): show Check for updates in Settings #30

Workflow file for this run

name: Fork CI
# The commands of ci.yml on GitHub-hosted runners. ci.yml uses upstream's
# Blacksmith runners, which this fork does not have, so the fork disables it.
# Limit: this file copies the ci.yml commands by hand. When upstream changes
# them, update this file. A failure on main calls the repair agent. See docs/fork/operations.md "Fork CI".
#
# The heavy jobs run only when the push or pull request changes code. The changes job
# compares a push with the last green run, so a cancelled or failed run never hides a
# change. It compares a pull request with its base.
on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:
inputs:
notify_agent:
description: Call the agent webhook if this run fails. The agent sets false on its own retries.
type: boolean
default: true
permissions:
contents: read
# A newer push to the same branch or pull request cancels the older run. A manual run waits instead.
concurrency:
group: fork-ci-${{ github.ref }}
cancel-in-progress: ${{ github.event_name != 'workflow_dispatch' }}
jobs:
changes:
name: Changes
runs-on: ubuntu-24.04
timeout-minutes: 5
permissions:
actions: read
contents: read
outputs:
code: ${{ steps.classify.outputs.code }}
files: ${{ steps.classify.outputs.files }}
machine_map: ${{ steps.classify.outputs.machine_map }}
steps:
- name: Classify the changed files
id: classify
env:
GH_TOKEN: ${{ github.token }}
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail
code() { echo "code=true" >>"$GITHUB_OUTPUT"; echo "$1: the heavy jobs run."; exit 0; }
head="$GITHUB_SHA"
case "$GITHUB_EVENT_NAME" in
push)
base="$(gh run list --repo "$GITHUB_REPOSITORY" --workflow fork-ci.yml --branch "$GITHUB_REF_NAME" \
--event push --status success --limit 1 --json headSha --jq '.[0].headSha // empty')"
[[ -n "$base" ]] || code "No green run to compare with"
;;
pull_request)
base="$PR_BASE_SHA"
head="$PR_HEAD_SHA"
;;
*) code "Manual run" ;;
esac
# The compare API lists at most 300 files. A longer list counts as code.
files="$(gh api "repos/$GITHUB_REPOSITORY/compare/$base...$head" --jq '.files[].filename')" ||
code "The compare with $base failed"
(($(wc -l <<<"$files") < 300)) || code "300 or more changed files"
while IFS= read -r file; do
[[ -n "$file" ]] || continue
case "$file" in
docs/* | *.md) ;;
apps/machine-map/*) echo "machine_map=true" >>"$GITHUB_OUTPUT" ;;
*) code "$file changed since $base" ;;
esac
done <<<"$files"
echo "code=false" >>"$GITHUB_OUTPUT"
{ echo "files<<EOF"; echo "$files"; echo "EOF"; } >>"$GITHUB_OUTPUT"
echo "Only docs, markdown or apps/machine-map changed since $base: only lint and the machine map job run."
# The heavy jobs also cover apps/machine-map. This job checks it alone when nothing else changed.
machine_map:
name: Machine map
needs: changes
if: needs.changes.outputs.code == 'false' && needs.changes.outputs.machine_map == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false
- uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: |
- args: ["--filter", "@t3tools/machine-map...", "--filter", "@t3tools/monorepo"]
- run: vp run --filter @t3tools/machine-map typecheck
- run: vp run --filter @t3tools/machine-map test
lint:
name: Lint
needs: changes
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false
- uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: true
- if: needs.changes.outputs.code == 'true'
run: vp run --filter @t3tools/desktop ensure:electron
- if: needs.changes.outputs.code == 'true'
run: vp run knip:check
- if: needs.changes.outputs.code == 'true'
run: vp check
- name: Check the changed files
if: needs.changes.outputs.code != 'true'
env:
FILES: ${{ needs.changes.outputs.files }}
run: |
existing=()
scripts=()
while IFS= read -r file; do
[[ -f "$file" ]] || continue
existing+=("$file")
case "$file" in *.ts | *.tsx | *.js | *.jsx | *.mjs | *.cjs) scripts+=("$file") ;; esac
done <<<"$FILES"
# vp check fails when no file is lintable, so markdown gets only the format check.
if ((${#existing[@]} > 0)); then vp fmt --check "${existing[@]}"; fi
if ((${#scripts[@]} > 0)); then vp check "${scripts[@]}"; fi
# On both paths, because a code change can rename a file that a doc links to.
- name: Check the links of the fork docs
run: node scripts/fork-check-doc-links.ts
typecheck:
name: Typecheck
needs: changes
if: needs.changes.outputs.code == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false
- uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: true
- run: vp run --filter @t3tools/desktop ensure:electron
- run: vpr typecheck
build:
name: Build
needs: changes
if: needs.changes.outputs.code == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false
- run: sudo apt-get update && sudo apt-get install -y libsecret-1-dev pkg-config
- uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: true
- run: vp run --filter @t3tools/desktop ensure:electron
- run: vp run build:desktop
- run: node apps/desktop/scripts/verify-preload-bundle.mjs
test:
name: Test ${{ matrix.group }}
needs: changes
if: needs.changes.outputs.code == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 30
# Two runners: on one runner, the slowest packages wait for each other.
strategy:
fail-fast: false
matrix:
include:
- group: apps
filters: --filter @t3tools/mobile --filter @t3tools/desktop --filter @t3tools/oxlint-plugin-t3code
- group: packages
filters: >-
--filter '!t3' --filter '!@t3tools/monorepo' --filter '!@t3tools/web'
--filter '!@t3tools/mobile' --filter '!@t3tools/desktop' --filter '!@t3tools/oxlint-plugin-t3code'
steps:
- uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false
- run: sudo apt-get update && sudo apt-get install -y --no-install-recommends build-essential libsecret-1-dev pkg-config
- uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: true
- run: vp run --filter @t3tools/desktop ensure:electron
- if: matrix.group == 'packages'
run: python3 -B .github/scripts/stage-preview-bundle.test.py
- if: matrix.group == 'packages'
run: node --test .github/scripts/check-nightly-release.test.cjs
- run: vp run --parallel --concurrency-limit 4 ${{ matrix.filters }} test
test_web:
name: Test Web
needs: changes
if: needs.changes.outputs.code == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false
- uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: true
# The browser project runs React tests in headless Chromium.
- run: node apps/web/node_modules/playwright/cli.js install --with-deps --only-shell chromium
- run: vp run --filter @t3tools/web test
test_server:
name: Test Server ${{ matrix.shard }}
needs: changes
if: needs.changes.outputs.code == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4, 5, 6, 7, 8]
steps:
- uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false
- uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: true
- run: node apps/server/node_modules/playwright-core/cli.js install --with-deps --only-shell chromium
- run: vp run --filter t3 test --shard ${{ matrix.shard }}/${{ strategy.job-total }}
rust:
name: Rust
needs: changes
if: needs.changes.outputs.code == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: Check formatting and test
run: |
for crate in resource-monitor kde-snap-shot hyprland-snap-shot; do
cargo fmt --manifest-path "native/$crate/Cargo.toml" -- --check
cargo test --locked --manifest-path "native/$crate/Cargo.toml"
done
# The one check that branch protection requires. A skipped job counts as passed,
# so the docs-only path passes too. A cancelled job counts as failed.
result:
name: Fork CI result
needs: [changes, lint, machine_map, typecheck, build, test, test_web, test_server, rust]
if: always()
runs-on: ubuntu-24.04
timeout-minutes: 5
steps:
- name: Check the job results
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
env:
NEEDS_JSON: ${{ toJSON(needs) }}
run: |
jq -r 'to_entries[] | "\(.key): \(.value.result)"' <<<"$NEEDS_JSON"
exit 1
# Starts the repair agent, like Fork Sync and Fork Release. Without it, a red
# main goes unnoticed. Off until the T3_AGENT_WEBHOOK_URL secret is set.
# A pull request never calls it: its author sees the failed check.
notify_agent:
name: Notify repair agent
needs: [changes, lint, machine_map, typecheck, build, test, test_web, test_server, rust]
if: failure() && github.event_name != 'pull_request' && github.event.inputs.notify_agent != 'false'
runs-on: ubuntu-24.04
timeout-minutes: 20
permissions:
actions: read
steps:
- uses: actions/checkout@v6
with:
sparse-checkout: scripts/fork-notify-agent.sh
sparse-checkout-cone-mode: false
- name: Call agent webhook
env:
GH_TOKEN: ${{ github.token }}
WEBHOOK_URL: ${{ secrets.T3_AGENT_WEBHOOK_URL }}
CF_ACCESS_CLIENT_ID: ${{ secrets.CF_ACCESS_CLIENT_ID }}
CF_ACCESS_CLIENT_SECRET: ${{ secrets.CF_ACCESS_CLIENT_SECRET }}
NEEDS_JSON: ${{ toJSON(needs) }}
run: scripts/fork-notify-agent.sh