Repository navigation
fix(ios): app paths and Alpine exec; feat(lsp): project-wide TypeScript worker with progress #26
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: | |
| branches: | |
| - main | |
| pull_request: | |
| branches: | |
| - '**' | |
| merge_group: | |
| jobs: | |
| spell-check: | |
| timeout-minutes: 5 | |
| name: Check spelling | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout Actions Repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Check spelling | |
| uses: crate-ci/typos@main | |
| with: | |
| config: ./_typos.toml | |
| quality: | |
| timeout-minutes: 5 | |
| name: Linting and formatting | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Setup Biome | |
| uses: biomejs/setup-biome@4c91541eaada48f67d7dbd7833600ce162b68f51 # v2.7.1 | |
| - name: Run Biome | |
| run: biome ci . | |
| unit-tests: | |
| name: Unit Tests (On PR Only) | |
| timeout-minutes: 10 | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - name: Checkout Repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| submodules: recursive | |
| - name: Use Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| cache: npm | |
| cache-dependency-path: '**/package-lock.json' | |
| - name: Install dependencies | |
| run: npm ci --no-audit --no-fund | |
| - name: Setup Java | |
| uses: actions/setup-java@v6 | |
| with: | |
| distribution: temurin | |
| java-version: '26' | |
| - name: Run unit tests | |
| run: npm run test | |
| - name: Check TypeScript | |
| run: npm run typecheck | |
| translation-check: | |
| name: Translation Check (On PR Only) | |
| timeout-minutes: 5 | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - name: Checkout Repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| submodules: recursive | |
| - name: Use Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| cache: npm | |
| cache-dependency-path: '**/package-lock.json' | |
| - name: Detect Changed Files | |
| uses: dorny/paths-filter@v4 | |
| id: file-changes | |
| with: | |
| list-files: shell | |
| filters: | | |
| translation: | |
| - 'src/lang/*.json' | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Translation Files Check (if changed) | |
| if: steps.file-changes.outputs.translation == 'true' | |
| run: | | |
| npm ci --no-audit --no-fund | |
| npm run lang check | |
| ios: | |
| name: Acode iOS | |
| runs-on: macos-26 | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| submodules: recursive | |
| - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: '24' | |
| cache: npm | |
| - name: Install dependencies | |
| run: npm ci --no-audit --no-fund | |
| - name: Install Alpine runtime build tools | |
| run: brew install meson ninja llvm lld | |
| - name: Prepare local iOS configuration | |
| run: cp platforms/ios/Config.xcconfig.example platforms/ios/Config.xcconfig | |
| - name: Select iPhone and iPad simulators with working StoreKit testing | |
| id: simulator | |
| run: | | |
| node <<'JS' | |
| const { execFileSync } = require('node:child_process'); | |
| const { appendFileSync } = require('node:fs'); | |
| const { devices } = JSON.parse(execFileSync('xcrun', ['simctl', 'list', 'devices', 'available', '--json'])); | |
| // iOS 26.3–26.5 fails SKTestSession configuration in command-line runs: | |
| // https://developer.apple.com/forums/thread/826971 | |
| const supported = ['iOS-18-6', 'iOS-26-2'].flatMap(version => | |
| devices[`com.apple.CoreSimulator.SimRuntime.${version}`] || []); | |
| for (const [family, output] of [['iPhone', 'id'], ['iPad', 'ipad']]) { | |
| const device = supported.find(device => device.isAvailable && | |
| device.deviceTypeIdentifier?.startsWith(`com.apple.CoreSimulator.SimDeviceType.${family}-`)); | |
| if (!device) throw new Error(`Install an iOS 18.6 or 26.2 ${family} simulator for integration tests`); | |
| appendFileSync(process.env.GITHUB_OUTPUT, `${output}=${device.udid}\n`); | |
| } | |
| JS | |
| - name: Build and run simulator tests with SSH and FTP fixtures | |
| run: | | |
| python3 -m venv .ios-build/ssh-fixture-venv | |
| .ios-build/ssh-fixture-venv/bin/pip install -r tests/fixtures/ssh/requirements.txt | |
| .ios-build/ssh-fixture-venv/bin/python tests/fixtures/ssh/server.py -- npm run test:ios -- --target=${{ steps.simulator.outputs.id }} | |
| - name: Run iPad startup and native UI checks | |
| run: | | |
| checks=() | |
| for test in AppBridgeTests SystemUITests KeyboardLayoutTests PlatformUITests HapticControlsTests DocumentsPickerTests ShareTests PreviewBrowserTests FilesBrowserTests BrowserBridgeTests; do | |
| checks+=("-only-testing:runnerTests/$test") | |
| done | |
| checks+=("-only-testing:runnerUITests/AppIconUITests") | |
| xcodebuild -project platforms/ios/runner.xcodeproj -scheme runner \ | |
| -configuration Debug -sdk iphonesimulator \ | |
| -destination 'platform=iOS Simulator,id=${{ steps.simulator.outputs.ipad }}' \ | |
| -derivedDataPath .ios-build -clonedSourcePackagesDirPath .ios-build/SourcePackages \ | |
| -parallel-testing-enabled NO -collect-test-diagnostics never \ | |
| "${checks[@]}" CODE_SIGNING_ALLOWED=YES CODE_SIGN_IDENTITY=- test-without-building | |
| android: | |
| name: Acode Android (${{ matrix.variant }}, ${{ matrix.distribution }}) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - variant: paid | |
| package: com.foxdebug.acode | |
| distribution: store | |
| - variant: free | |
| package: com.foxdebug.acodefree | |
| distribution: store | |
| - variant: paid | |
| package: com.foxdebug.acode | |
| distribution: fdroid | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| submodules: recursive | |
| - uses: actions/setup-java@v6 | |
| with: | |
| distribution: temurin | |
| java-version: '26' | |
| - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: '24' | |
| cache: npm | |
| - name: Install dependencies | |
| run: npm ci --no-audit --no-fund | |
| - name: Install Android SDK packages | |
| run: sdkmanager 'platforms;android-37' 'build-tools;36.0.0' | |
| - name: Select package | |
| run: npm pkg set name=${{ matrix.package }} | |
| - name: Build APK | |
| run: npm run build -- dev apk ${{ matrix.distribution }} | |
| - name: Native tests | |
| run: npm run test:android -- ${{ matrix.distribution }} | |
| - name: Validate minified release bundle | |
| if: matrix.distribution == 'store' | |
| run: npm run build -- prod bundle |