diff --git a/.github/workflows/native-e2e.yml b/.github/workflows/native-e2e.yml new file mode 100644 index 00000000..49f9ed5a --- /dev/null +++ b/.github/workflows/native-e2e.yml @@ -0,0 +1,104 @@ +name: Native Simulator Tests + +on: + push: + branches: + - ci/native-e2e + workflow_dispatch: + schedule: + - cron: '0 18 * * 0' # Weekly, Monday 03:00 JST + +permissions: + contents: read + +concurrency: + group: native-e2e-${{ github.ref }} + cancel-in-progress: false + +jobs: + suite: + timeout-minutes: 75 + # xcode-27 preview label; Xcode 27 beta is the default toolchain on that + # image, so no DEVELOPER_DIR override is needed. + runs-on: xcode-27 + strategy: + fail-fast: false + matrix: + include: + - suite: ui-shell + script: scripts/verify-native-ui-shell.sh + kana: '' + - suite: search + script: scripts/verify-native-search.sh + scenario: search + kana: kana + - suite: edge + script: scripts/verify-native-search.sh + scenario: edge + kana: '' + steps: + - uses: actions/checkout@v5 + - uses: actions/setup-node@v5 + with: + node-version: 24 + + - id: meta + run: | + xcodebuild -version + echo "xcode_version=$(xcodebuild -version | head -n 1 | tr ' ' '-')" >> "$GITHUB_OUTPUT" + echo "image_version=${ImageVersion:-unknown}" >> "$GITHUB_OUTPUT" + + - uses: actions/cache@v5 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + + - name: Restore incremental build products + uses: actions/cache@v5 + with: + path: ${{ runner.temp }}/native-${{ matrix.suite }} + key: native-${{ matrix.suite }}-${{ steps.meta.outputs.xcode_version }}-${{ hashFiles('**/package-lock.json', 'ios/**', 'demo/ios/**', 'demo/native-*-fixture/**', 'src/**') }} + restore-keys: | + native-${{ matrix.suite }}-${{ steps.meta.outputs.xcode_version }}- + + - name: Install XcodeGen + run: brew list xcodegen >/dev/null 2>&1 || brew install xcodegen + + - run: npm ci + - run: npm ci + working-directory: './demo' + + - name: Fetch shared simulator setup script + run: | + sha=$(jq -r '.packages["node_modules/@rdlabo/ionic-theme-utils"].resolved' package-lock.json | sed 's/.*#//') + curl -fsSL "https://raw.githubusercontent.com/rdlabo-dev/ionic-theme-utils/$sha/scripts/ci-simulator.sh" -o "$RUNNER_TEMP/ci-simulator.sh" + + - name: Create and boot simulator + run: sh "$RUNNER_TEMP/ci-simulator.sh" "iPhone 17" "iOS 27.0" ${{ matrix.kana }} + + - name: Run ${{ matrix.suite }} suite + run: sh ${{ matrix.script }} "$SIM_UDID" ${{ matrix.scenario }} + env: + VERIFY_ARTIFACTS_DIR: ${{ runner.temp }}/native-${{ matrix.suite }} + + - name: Upload screenshots and logs + uses: actions/upload-artifact@v5 + if: always() + with: + name: native-${{ matrix.suite }}-screenshots + path: | + ${{ runner.temp }}/native-${{ matrix.suite }}/screenshots + ${{ runner.temp }}/native-${{ matrix.suite }}/*.log + if-no-files-found: warn + retention-days: 7 + + - name: Upload result bundle on failure + uses: actions/upload-artifact@v5 + if: failure() + with: + name: native-${{ matrix.suite }}-xcresult + path: ${{ runner.temp }}/native-${{ matrix.suite }}/tests.xcresult + if-no-files-found: warn + retention-days: 7 diff --git a/package-lock.json b/package-lock.json index 1c5e8879..8e9c2fa3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.0", "license": "MIT", "dependencies": { - "@rdlabo/ionic-theme-utils": "git+ssh://git@github.com/rdlabo-dev/ionic-theme-utils.git#66eb2fccca10646ebfccdfb3b6c2f3b4c9b00bf6" + "@rdlabo/ionic-theme-utils": "git+ssh://git@github.com/rdlabo-dev/ionic-theme-utils.git#ec42938042c0fb65ef6f3c312c4240d820a2cf6f" }, "devDependencies": { "@capacitor/core": "^8.5.2", @@ -2255,7 +2255,7 @@ }, "node_modules/@rdlabo/ionic-theme-utils": { "version": "0.1.0", - "resolved": "git+ssh://git@github.com/rdlabo-dev/ionic-theme-utils.git#66eb2fccca10646ebfccdfb3b6c2f3b4c9b00bf6", + "resolved": "git+ssh://git@github.com/rdlabo-dev/ionic-theme-utils.git#ec42938042c0fb65ef6f3c312c4240d820a2cf6f", "integrity": "sha512-0/aRkysY012ByvBJFaKBNiU5BFeR7uHCxuQ/BBprq1eHjOgS2AoyZwcBqhqP3SZDDDhnGKLK/SfLQYRySeFAng==", "license": "MIT", "peerDependencies": { diff --git a/package.json b/package.json index ef3343d1..1c41ebf3 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ }, "homepage": "https://docs.rdlabo.dev/projects/ionic-theme-ios27", "dependencies": { - "@rdlabo/ionic-theme-utils": "git+ssh://git@github.com/rdlabo-dev/ionic-theme-utils.git#66eb2fccca10646ebfccdfb3b6c2f3b4c9b00bf6" + "@rdlabo/ionic-theme-utils": "git+ssh://git@github.com/rdlabo-dev/ionic-theme-utils.git#ec42938042c0fb65ef6f3c312c4240d820a2cf6f" }, "devDependencies": { "@capacitor/core": "^8.5.2", diff --git a/scripts/verify-native-search.sh b/scripts/verify-native-search.sh index 5292b7d2..a7bd4c97 100644 --- a/scripts/verify-native-search.sh +++ b/scripts/verify-native-search.sh @@ -10,7 +10,12 @@ case "$scenario" in esac repo=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) fixture="$repo/demo/native-$scenario-fixture" -artifacts=$(mktemp -d "/tmp/ionic-native-$scenario-verification.XXXXXX") +if [ "${VERIFY_ARTIFACTS_DIR:-}" ]; then + artifacts=$VERIFY_ARTIFACTS_DIR + mkdir -p "$artifacts" +else + artifacts=$(mktemp -d "/tmp/ionic-native-$scenario-verification.XXXXXX") +fi printf 'Native %s verification artifacts: %s\n' "$scenario" "$artifacts" cd "$repo" npm run build @@ -28,7 +33,14 @@ const file = process.argv[2]; writeFileSync(file, readFileSync(file, 'utf8').replace('', ``)); JS cd "$artifacts/consumer" -npm install --ignore-scripts "$artifacts/$archive" @capacitor/core@8.5.2 @capacitor/ios@8.5.2 @capacitor/cli@8.5.2 @capacitor/keyboard@8.0.5 @ionic/core@8.8.19 +# --ignore-scripts would skip the git dependency's prepare script, leaving +# @rdlabo/ionic-theme-utils without its dist build. +npm install "$artifacts/$archive" @capacitor/core@8.5.2 @capacitor/ios@8.5.2 @capacitor/cli@8.5.2 @capacitor/keyboard@8.0.5 @ionic/core@8.8.19 +# Some npm versions skip `prepare` for transitive git dependencies; build the +# utils dist explicitly when it was not produced. +if [ ! -f node_modules/@rdlabo/ionic-theme-utils/dist/index.js ]; then + (cd node_modules/@rdlabo/ionic-theme-utils && npm install --no-save --no-audit --no-fund typescript && npm run build) +fi npx cap add ios --packagemanager SPM xcodebuild -project ios/App/App.xcodeproj -scheme App -configuration Debug \ -sdk iphonesimulator -destination "platform=iOS Simulator,id=$simulator" \ diff --git a/scripts/verify-native-ui-shell.sh b/scripts/verify-native-ui-shell.sh index b3f0d231..9ed7c2ed 100644 --- a/scripts/verify-native-ui-shell.sh +++ b/scripts/verify-native-ui-shell.sh @@ -6,7 +6,12 @@ set -eu simulator=${1:?Usage: sh scripts/verify-native-ui-shell.sh SIMULATOR_UDID} repo=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) -artifacts=$(mktemp -d /tmp/ionic-native-ui-shell-verification.XXXXXX) +if [ "${VERIFY_ARTIFACTS_DIR:-}" ]; then + artifacts=$VERIFY_ARTIFACTS_DIR + mkdir -p "$artifacts" +else + artifacts=$(mktemp -d /tmp/ionic-native-ui-shell-verification.XXXXXX) +fi printf 'Native UI Shell verification artifacts: %s\n' "$artifacts" cd "$repo" @@ -26,7 +31,14 @@ mkdir -p "$artifacts/consumer/www" cp "$repo/demo/native-package-fixture/app.js" "$repo/demo/native-package-fixture/capacitor.config.json" "$artifacts/consumer/" cp "$repo/demo/native-package-fixture/index.html" "$artifacts/consumer/www/" cd "$artifacts/consumer" -npm install --ignore-scripts "$artifacts/$archive" @capacitor/core@8.5.2 @capacitor/ios@8.5.2 @capacitor/cli@8.5.2 @ionic/core@8.8.19 +# --ignore-scripts would skip the git dependency's prepare script, leaving +# @rdlabo/ionic-theme-utils without its dist build. +npm install "$artifacts/$archive" @capacitor/core@8.5.2 @capacitor/ios@8.5.2 @capacitor/cli@8.5.2 @ionic/core@8.8.19 +# Some npm versions skip `prepare` for transitive git dependencies; build the +# utils dist explicitly when it was not produced. +if [ ! -f node_modules/@rdlabo/ionic-theme-utils/dist/index.js ]; then + (cd node_modules/@rdlabo/ionic-theme-utils && npm install --no-save --no-audit --no-fund typescript && npm run build) +fi "$repo/demo/node_modules/.bin/esbuild" app.js --bundle --format=esm --outdir=www npx cap add ios --packagemanager SPM xcodebuild -project ios/App/App.xcodeproj -scheme App -configuration Debug \