Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 0 additions & 99 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,102 +107,3 @@ jobs:
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
172 changes: 172 additions & 0 deletions .github/workflows/native-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
name: Native Tests

# Native suites are slow (macOS runners, Gradle), so PRs only run the platform
# whose code they touch; the daily run catches breakage coming from src/.
on:
push:
branches:
- main
paths:
- 'platforms/**'
- 'dev/**'
- 'tests/fixtures/ssh/**'
- 'package.json'
- 'package-lock.json'
- '.github/workflows/native-tests.yml'
pull_request:
paths:
- 'platforms/**'
- 'dev/**'
- 'tests/fixtures/ssh/**'
- 'package.json'
- 'package-lock.json'
- '.github/workflows/native-tests.yml'
schedule:
- cron: "0 5 * * *"
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
changes:
name: Detect changed platforms
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
pull-requests: read
outputs:
android: ${{ steps.filter.outputs.android }}
ios: ${{ steps.filter.outputs.ios }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
if: github.event_name == 'push' || github.event_name == 'pull_request'
- name: Detect changed files
id: filter
if: github.event_name == 'push' || github.event_name == 'pull_request'
uses: dorny/paths-filter@v4
with:
filters: |
shared: &shared
- 'dev/config.js'
- 'dev/sync.js'
- 'dev/scripts/native.js'
- 'dev/scripts/build.sh'
- 'package.json'
- 'package-lock.json'
- '.github/workflows/native-tests.yml'
android:
- *shared
- 'platforms/android/**'
- 'dev/storage_manager.mjs'
- 'dev/scripts/android.js'
ios:
- *shared
- 'platforms/ios/**'
- 'dev/ios/**'
- 'dev/scripts/ios.js'
- 'dev/scripts/iosAds.js'
- 'tests/fixtures/ssh/**'

android:
name: Android (${{ matrix.variant }}, ${{ matrix.distribution }})
needs: changes
if: needs.changes.outputs.android == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
timeout-minutes: 30
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'
cache: gradle
- 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: $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager 'platforms;android-37.0' 'build-tools;36.0.0'
- name: Select package
run: npm pkg set androidPackageId=${{ matrix.package }}
- name: Native unit tests
run: npm run test:android -- ${{ matrix.distribution }}

ios:
name: iOS
needs: changes
if: needs.changes.outputs.ios == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
runs-on: macos-26
timeout-minutes: 30
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
5 changes: 4 additions & 1 deletion .github/workflows/nightly-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,11 @@ jobs:
run: |
npm ci --no-audit --no-fund

- name: Install Android SDK packages
run: $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager 'platforms;android-37.0' 'build-tools;36.0.0'

- name: Select paid package
run: npm pkg set name=com.foxdebug.acode
run: npm pkg set androidPackageId=com.foxdebug.acode

- name: Build normal APK
run: |
Expand Down
2 changes: 2 additions & 0 deletions _typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,5 @@ multline = "multline"
sav = "sav"
ist = "ist"
Hel = "Hel"
# Apple simulator device identifier
udid = "udid"
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ public void startsAndResumesWithoutReloadingTheEditor() throws Exception {
public void exposesEveryTransportKeyOnce() {
java.util.HashSet<String> keys = new java.util.HashSet<>();
for (ServiceName name : ServiceName.values()) {
assertSame(name, ServiceName.fromKey(name.getKey()));
assertTrue("duplicate key " + name.getKey(), keys.add(name.getKey()));
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/native/types/sftp.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ interface Sftp {
/**
* Executes command on ssh-server
* @param command
* @param onSucess
* @param onSuccess
* @param onFail
*/
exec(
command: String,
onSucess: (res: ExecResult) => void,
onSuccess: (res: ExecResult) => void,
onFail: (err: any) => void,
): void;
/** Connects using credentials held by the native profile store. */
Expand Down
Loading