diff --git a/.github/workflows/accessibility-tests.yml b/.github/workflows/accessibility-tests.yml index 273f6186e..fef1c8f1a 100644 --- a/.github/workflows/accessibility-tests.yml +++ b/.github/workflows/accessibility-tests.yml @@ -11,6 +11,11 @@ permissions: {} jobs: tests: name: Tests + # HealthChat: skip in this fork. It runs nightly Mon-Fri and fails at checkout, because + # permissions: {} leaves a metadata-only token that cannot read an INTERNAL repo. Gated rather + # than deleted so the file keeps rebasing cleanly. Run locally with + # `swift run tools ci accessibility-tests`. + if: github.repository == 'element-hq/element-x-ios' runs-on: macos-26 timeout-minutes: 150 diff --git a/.github/workflows/compound-ios.yml b/.github/workflows/compound-ios.yml index e940dcf3e..7e8d19bd9 100644 --- a/.github/workflows/compound-ios.yml +++ b/.github/workflows/compound-ios.yml @@ -20,6 +20,11 @@ permissions: {} jobs: tests: + # HealthChat: skip in this fork. It only triggers on changes under compound-ios/, which this fork + # has never edited, so it would only ever fire on an upstream sync and go red at checkout — + # permissions: {} leaves a metadata-only token that cannot read an INTERNAL repo. Gated rather + # than deleted so the file keeps rebasing cleanly. + if: github.repository == 'element-hq/element-x-ios' runs-on: macos-26 timeout-minutes: 15 diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 9c06b1455..ac563cc90 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -11,6 +11,13 @@ permissions: {} jobs: integration_tests: name: Integration Tests + # HealthChat: skip in this fork. It runs nightly Mon-Fri and fails at checkout, and it is the one + # job that still calls out to Element's Codecov — its upload guard is true on schedule events, so + # it POSTs slug/branch/SHA every night with continue-on-error hiding the failure. Fixing it would + # need a real healthchat.ch test account and three new secrets, and would still not work: + # HealthChatAppSettingsHook sets allowOtherAccountProviders: false, hiding the change-server UI + # these tests drive. Gated rather than deleted so the file keeps rebasing cleanly. + if: github.repository == 'element-hq/element-x-ios' runs-on: macos-26 timeout-minutes: 45 diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml index 4af202200..76fcac3a7 100644 --- a/.github/workflows/ui-tests.yml +++ b/.github/workflows/ui-tests.yml @@ -15,6 +15,12 @@ permissions: {} jobs: tests: name: Tests + # HealthChat: skip in this fork. It runs nightly Mon-Fri and fails at checkout, because + # permissions: {} leaves a metadata-only token that cannot read an INTERNAL repo. Fixing the + # permission would not help: the rebrand changed the start screen without re-recording any + # UITests snapshot, so it would fail on content instead. Gated rather than deleted so the file + # keeps rebasing cleanly. Run locally with `swift run tools ci ui-tests`. + if: github.repository == 'element-hq/element-x-ios' runs-on: macos-26 timeout-minutes: 90 strategy: diff --git a/.github/workflows/unit-tests-enterprise.yml b/.github/workflows/unit-tests-enterprise.yml index 27117fb7a..5b3afd24c 100644 --- a/.github/workflows/unit-tests-enterprise.yml +++ b/.github/workflows/unit-tests-enterprise.yml @@ -17,7 +17,14 @@ jobs: timeout-minutes: 45 # Skip in forks - if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }} + # HealthChat: this job can never pass in this fork — it needs + # secrets.ELEMENT_BOT_TOKEN (Element's bot, absent here) and recursively + # checks out the private element-hq/element-ios-enterprise submodule, which + # Novaloop cannot obtain. The guard below only asks whether the PR comes + # FROM a fork, not whether this repo IS one, so it does not skip us. Gate on + # the upstream repo as post-release.yml does. Gated rather than deleted so + # the file keeps rebasing cleanly against upstream. + if: ${{ github.repository == 'element-hq/element-x-ios' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) }} concurrency: # Only allow a single run of this workflow on each branch, automatically cancelling older runs. diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index f72fb550f..85f4ab9f3 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -13,21 +13,63 @@ permissions: {} jobs: tests: name: Tests - runs-on: macos-26 + # HealthChat: GitHub-hosted macos-26 could not finish this job inside + # timeout-minutes: 60 (two attempts: 51m42s, then killed at 60m44s), and macOS + # minutes bill at 10x. novaloop-mac-studio-001 is the org's Mac Studio, already + # used by the release pipeline; its labels are [self-hosted, macOS, ARM64]. + runs-on: [self-hosted, macOS] + # Upstream's 60 is kept: with previews skipped (see Run tests) the build plus unit tests measured + # ~16 min here. A run approaching this budget is a signal, not normal — the earlier 60m timeouts + # were preview tests, not the build. timeout-minutes: 60 + permissions: + contents: read # HealthChat: this fork is INTERNAL, so a metadata-only token 404s on checkout (and on git lfs pull). Upstream is public, hence permissions: {} there. + concurrency: # Only allow a single run of this workflow on each branch, automatically cancelling older runs. group: ${{ format('unit-tests-{0}', github.ref) }} cancel-in-progress: true steps: + # HealthChat: upstream passes persist-credentials: false here, which the + # composite forwards to actions/checkout — stripping the auth header before + # its separate "Git LFS Pull" step runs. Upstream can afford that because + # its repo is public and git lfs pull works anonymously; this fork is + # INTERNAL, so the LFS batch endpoint would 404. Keep the composite's own + # default (true) so the pull is authenticated with GITHUB_TOKEN. - uses: nschloe/action-cached-lfs-checkout@385a8ecc719e50b8c71af6ab01a624b486b7c3bc # v1.2.5 - with: - persist-credentials: false - - name: Setup environment - run: source ci_scripts/ci_common.sh && setup_github_actions_environment + # HealthChat: verify only — never provision. Upstream's + # setup_github_actions_environment cannot run on this runner: it calls + # `sudo xcode-select -s /Applications/Xcode_26.5.0.app`, but the runner has no + # passwordless sudo and no such path (only /Applications/Xcode.app exists), and + # it calls `brew update && brew install ...` — novaloop-mac-studio-001 is the + # shared release machine, so a per-run `brew update` could upgrade xcodegen + # underneath the release pipeline. These tools are installed once by hand; CI + # only asserts they are present and fails loudly, naming the fix, if not. + - name: Verify environment + run: | + set -eu + missing="" + formulae="" + for tool in xcodegen swiftlint swiftformat xcbeautify xcresultparser pkl git-lfs; do + if ! command -v "$tool" >/dev/null 2>&1; then + missing="$missing $tool" + case "$tool" in + # Not in homebrew-core; only this tap ships it. + xcresultparser) formulae="$formulae a7ex/homebrew-formulae/xcresultparser" ;; + *) formulae="$formulae $tool" ;; + esac + fi + done + if [ -n "$missing" ]; then + echo "::error::Missing on self-hosted runner:${missing}. Install by hand on novaloop-mac-studio-001, then re-run: brew install${formulae}" + exit 1 + fi + # The Xcode version is no longer pinned anywhere, so this is the only record + # of which Xcode built a given run. + xcodebuild -version - name: Restore compilation cache uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 @@ -37,7 +79,12 @@ jobs: restore-keys: compilation-cache-unit-tests- - name: Run tests - run: swift run -q tools ci unit-tests + # HealthChat: previews are skipped. PreviewTests renders a snapshot for every preview in the + # app and was the entire reason this job could not fit in an hour — it never once finished, + # on either runner. Unit tests alone take ~16 min here. Upstream skips them the same way in + # unit-tests-enterprise.yml. Cost: preview snapshot regressions are not caught in CI, so + # re-record and check them locally when changing UI. + run: swift run -q tools ci unit-tests --skip-previews - name: Save compilation cache # Only develop populates the cache, all of the other runs simply read from it. @@ -59,7 +106,11 @@ jobs: - name: Upload coverage to Codecov # Skip if not successful and in forks - if: ${{ success() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) }} + # HealthChat: the existing guard only asks whether the PR comes FROM a + # fork, not whether this repo IS one, so it is true here and the step + # runs without a CODECOV_TOKEN — which fails the job via + # fail_ci_if_error. Gate on the upstream repo as post-release.yml does. + if: ${{ success() && github.repository == 'element-hq/element-x-ios' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) }} uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: report_type: coverage @@ -71,7 +122,9 @@ jobs: - name: Upload test results to Codecov # Skip if cancelled and in forks - if: ${{ !cancelled() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) }} + # HealthChat: gated on the upstream repo for the same reason as the + # coverage step above — no CODECOV_TOKEN exists in this fork. + if: ${{ !cancelled() && github.repository == 'element-hq/element-x-ios' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) }} uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 continue-on-error: true with: diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 229e04998..33bdb1d8f 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -14,6 +14,8 @@ jobs: runs-on: ubuntu-latest permissions: security-events: write # Required for upload-sarif (used by zizmor-action) to upload SARIF files. + contents: read # HealthChat: this fork is INTERNAL, so a metadata-only token 404s on checkout. Upstream is public, hence permissions: {} there. + actions: read # HealthChat: upload-sarif additionally needs this on private/internal repos; public upstream does not. steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1