From 7cdf2ea1435614087351b68cc4c83678470af5dd Mon Sep 17 00:00:00 2001 From: Jungwon Sohn Date: Fri, 31 Jul 2026 15:26:04 +0900 Subject: [PATCH 1/6] ci(mobile): automate app store uploads (#185) --- .github/workflows/ios-app-store-connect.yml | 123 ++++++++++++++++++++ mobile/RELEASING.md | 23 ++++ 2 files changed, 146 insertions(+) create mode 100644 .github/workflows/ios-app-store-connect.yml diff --git a/.github/workflows/ios-app-store-connect.yml b/.github/workflows/ios-app-store-connect.yml new file mode 100644 index 0000000..5af3df2 --- /dev/null +++ b/.github/workflows/ios-app-store-connect.yml @@ -0,0 +1,123 @@ +name: iOS App Store Connect + +on: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: app-store-connect-production + cancel-in-progress: false + +jobs: + upload: + name: Build and upload iOS app + runs-on: macos-15 + environment: app-store-production + env: + APPLE_TEAM_ID: ${{ vars.APPLE_TEAM_ID }} + APP_STORE_PROFILE_NAME: ${{ vars.APP_STORE_PROFILE_NAME }} + ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }} + ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }} + ASC_PRIVATE_KEY: ${{ secrets.ASC_PRIVATE_KEY }} + APPLE_DISTRIBUTION_CERTIFICATE_BASE64: ${{ secrets.APPLE_DISTRIBUTION_CERTIFICATE_BASE64 }} + APPLE_DISTRIBUTION_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_DISTRIBUTION_CERTIFICATE_PASSWORD }} + APP_STORE_PROVISIONING_PROFILE_BASE64: ${{ secrets.APP_STORE_PROVISIONING_PROFILE_BASE64 }} + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: 22 + cache: npm + cache-dependency-path: mobile/package-lock.json + + - name: Install mobile dependencies + working-directory: mobile + run: npm ci + + - name: Generate the iOS project + working-directory: mobile + run: npx expo prebuild --platform ios --no-install + + - name: Install App Store signing assets + env: + KEYCHAIN_PASSWORD: ${{ github.run_id }}-${{ github.run_attempt }} + run: | + set -euo pipefail + test -n "$APPLE_TEAM_ID" + test -n "$APP_STORE_PROFILE_NAME" + test -n "$APPLE_DISTRIBUTION_CERTIFICATE_BASE64" + test -n "$APPLE_DISTRIBUTION_CERTIFICATE_PASSWORD" + test -n "$APP_STORE_PROVISIONING_PROFILE_BASE64" + + CERTIFICATE_PATH="$RUNNER_TEMP/distribution.p12" + PROFILE_PATH="$RUNNER_TEMP/profile.mobileprovision" + KEYCHAIN_PATH="$RUNNER_TEMP/app-store-signing.keychain-db" + + printf '%s' "$APPLE_DISTRIBUTION_CERTIFICATE_BASE64" | base64 -D > "$CERTIFICATE_PATH" + printf '%s' "$APP_STORE_PROVISIONING_PROFILE_BASE64" | base64 -D > "$PROFILE_PATH" + + security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" + security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + security import "$CERTIFICATE_PATH" -k "$KEYCHAIN_PATH" -P "$APPLE_DISTRIBUTION_CERTIFICATE_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + security list-keychain -d user -s "$KEYCHAIN_PATH" login.keychain-db + + mkdir -p "$HOME/Library/MobileDevice/Provisioning Profiles" + cp "$PROFILE_PATH" "$HOME/Library/MobileDevice/Provisioning Profiles/$(uuidgen).mobileprovision" + + - name: Install CocoaPods dependencies + working-directory: mobile/ios + run: pod install --repo-update + + - name: Archive the App Store build + working-directory: mobile + run: | + set -euo pipefail + xcodebuild \ + -workspace ios/OpenScene.xcworkspace \ + -scheme OpenScene \ + -configuration Release \ + -destination 'generic/platform=iOS' \ + -archivePath "$RUNNER_TEMP/OpenScene.xcarchive" \ + DEVELOPMENT_TEAM="$APPLE_TEAM_ID" \ + CODE_SIGN_STYLE=Manual \ + PROVISIONING_PROFILE_SPECIFIER="$APP_STORE_PROFILE_NAME" \ + CODE_SIGN_IDENTITY='Apple Distribution' \ + archive + + - name: Export the IPA + working-directory: mobile + run: | + set -euo pipefail + EXPORT_OPTIONS="$RUNNER_TEMP/ExportOptions.plist" + /usr/bin/plutil -create xml1 "$EXPORT_OPTIONS" + /usr/libexec/PlistBuddy -c 'Add :destination string export' "$EXPORT_OPTIONS" + /usr/libexec/PlistBuddy -c 'Add :method string app-store-connect' "$EXPORT_OPTIONS" + /usr/libexec/PlistBuddy -c "Add :teamID string $APPLE_TEAM_ID" "$EXPORT_OPTIONS" + /usr/libexec/PlistBuddy -c 'Add :signingStyle string manual' "$EXPORT_OPTIONS" + /usr/libexec/PlistBuddy -c 'Add :provisioningProfiles dict' "$EXPORT_OPTIONS" + /usr/libexec/PlistBuddy -c "Add :provisioningProfiles:com.sloki9637.openscene string $APP_STORE_PROFILE_NAME" "$EXPORT_OPTIONS" + xcodebuild \ + -exportArchive \ + -archivePath "$RUNNER_TEMP/OpenScene.xcarchive" \ + -exportOptionsPlist "$EXPORT_OPTIONS" \ + -exportPath "$RUNNER_TEMP/export" + + - name: Upload to App Store Connect + run: | + set -euo pipefail + test -n "$ASC_KEY_ID" + test -n "$ASC_ISSUER_ID" + test -n "$ASC_PRIVATE_KEY" + API_KEY_PATH="$RUNNER_TEMP/AuthKey_${ASC_KEY_ID}.p8" + umask 077 + printf '%s' "$ASC_PRIVATE_KEY" > "$API_KEY_PATH" + xcrun altool --upload-app \ + -f "$RUNNER_TEMP/export/OpenScene.ipa" \ + --api-key "$ASC_KEY_ID" \ + --api-issuer "$ASC_ISSUER_ID" \ + --p8-file-path "$API_KEY_PATH" diff --git a/mobile/RELEASING.md b/mobile/RELEASING.md index d7e3a56..921a717 100644 --- a/mobile/RELEASING.md +++ b/mobile/RELEASING.md @@ -58,6 +58,29 @@ OPENSCENE_KEY_PASSWORD=… build falls back to the debug key, so a local build still works for testing and only a real submission needs the keystore. +## App Store Connect automation + +The manually triggered **iOS App Store Connect** workflow builds an IPA and +uploads it to App Store Connect. It never submits an app for review: that +remains an explicit App Store Connect action after build processing and metadata +review. + +Create the `app-store-production` GitHub Environment, restrict it to the `dev` +branch, and require a reviewer before deploying. Store the following values as +environment configuration (not in the repository): + +- Variables: `APPLE_TEAM_ID` (`5H9F8F82WT`) and `APP_STORE_PROFILE_NAME` + (`macbook`). +- Secrets: `ASC_KEY_ID`, `ASC_ISSUER_ID`, `ASC_PRIVATE_KEY`, + `APPLE_DISTRIBUTION_CERTIFICATE_BASE64`, + `APPLE_DISTRIBUTION_CERTIFICATE_PASSWORD`, and + `APP_STORE_PROVISIONING_PROFILE_BASE64`. + +`ASC_PRIVATE_KEY` is the complete content of the downloaded App Store Connect +`.p8` file. The two `*_BASE64` secrets are base64-encoded copies of the signing +certificate `.p12` and the App Store provisioning profile respectively. Never +commit any of these files or their decoded values. + ### Build ```bash From 4d1f1b62100d4412a42f090b998c0532674b57a0 Mon Sep 17 00:00:00 2001 From: Jungwon Sohn Date: Fri, 31 Jul 2026 15:29:28 +0900 Subject: [PATCH 2/6] ci(mobile): automate google play uploads (#187) --- .github/workflows/android-google-play.yml | 93 +++++++++++++++++++++++ mobile/RELEASING.md | 21 +++++ 2 files changed, 114 insertions(+) create mode 100644 .github/workflows/android-google-play.yml diff --git a/.github/workflows/android-google-play.yml b/.github/workflows/android-google-play.yml new file mode 100644 index 0000000..ae5b95c --- /dev/null +++ b/.github/workflows/android-google-play.yml @@ -0,0 +1,93 @@ +name: Android Google Play + +on: + workflow_dispatch: + inputs: + track: + description: Google Play track to receive the release + type: choice + required: true + default: internal + options: + - internal + - production + release_status: + description: Publish state for the selected track + type: choice + required: true + default: draft + options: + - draft + - completed + +permissions: + contents: read + +concurrency: + group: google-play-production + cancel-in-progress: false + +jobs: + upload: + name: Build and upload Android app + runs-on: ubuntu-24.04 + environment: play-store-production + env: + ANDROID_PACKAGE_NAME: ${{ vars.ANDROID_PACKAGE_NAME }} + ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} + ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} + ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} + ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} + GOOGLE_PLAY_SERVICE_ACCOUNT_JSON: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }} + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: 22 + cache: npm + cache-dependency-path: mobile/package-lock.json + + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '17' + + - name: Install mobile dependencies + working-directory: mobile + run: npm ci + + - name: Generate the Android project + working-directory: mobile + run: npx expo prebuild --platform android --no-install + + - name: Install Android signing key + run: | + set -euo pipefail + test -n "$ANDROID_KEYSTORE_BASE64" + test -n "$ANDROID_KEYSTORE_PASSWORD" + test -n "$ANDROID_KEY_ALIAS" + test -n "$ANDROID_KEY_PASSWORD" + KEYSTORE_PATH="$RUNNER_TEMP/openscene-release.keystore" + printf '%s' "$ANDROID_KEYSTORE_BASE64" | base64 --decode > "$KEYSTORE_PATH" + echo "OPENSCENE_KEYSTORE_PATH=$KEYSTORE_PATH" >> "$GITHUB_ENV" + + - name: Build the signed Android App Bundle + working-directory: mobile/android + run: | + set -euo pipefail + ./gradlew bundleRelease \ + -POPENSCENE_STORE_FILE="$OPENSCENE_KEYSTORE_PATH" \ + -POPENSCENE_STORE_PASSWORD="$ANDROID_KEYSTORE_PASSWORD" \ + -POPENSCENE_KEY_ALIAS="$ANDROID_KEY_ALIAS" \ + -POPENSCENE_KEY_PASSWORD="$ANDROID_KEY_PASSWORD" + + - name: Upload to Google Play + uses: r0adkll/upload-google-play@v1.1.3 + with: + serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }} + packageName: ${{ vars.ANDROID_PACKAGE_NAME }} + releaseFiles: mobile/android/app/build/outputs/bundle/release/app-release.aab + tracks: ${{ inputs.track }} + status: ${{ inputs.release_status }} + changesNotSentForReview: true diff --git a/mobile/RELEASING.md b/mobile/RELEASING.md index 921a717..52d3845 100644 --- a/mobile/RELEASING.md +++ b/mobile/RELEASING.md @@ -81,6 +81,27 @@ environment configuration (not in the repository): certificate `.p12` and the App Store provisioning profile respectively. Never commit any of these files or their decoded values. +### Google Play automation + +The manually triggered **Android Google Play** workflow builds a signed Android +App Bundle (AAB) and uploads it to the explicitly selected Play track. It +defaults to an `internal` track `draft`; selecting `production` and `completed` +is a deliberate release decision made at dispatch time. + +Create the `play-store-production` GitHub Environment, restrict it to the +`dev` branch, and require a reviewer before deploying. Store the following +values as environment configuration (not in the repository): + +- Variable: `ANDROID_PACKAGE_NAME` (`com.sloki9637.openscene`). +- Secrets: `ANDROID_KEYSTORE_BASE64`, `ANDROID_KEYSTORE_PASSWORD`, + `ANDROID_KEY_ALIAS`, `ANDROID_KEY_PASSWORD`, and + `GOOGLE_PLAY_SERVICE_ACCOUNT_JSON`. + +`ANDROID_KEYSTORE_BASE64` is the base64-encoded release keystore. The Google +Play service account must have access to the OpenScene app in Play Console and +the Google Play Android Developer API must be enabled for its Google Cloud +project. Never commit the keystore, Gradle properties, or service-account JSON. + ### Build ```bash From fc9bb50c253cf2767aee9946b0f750a68804fbc8 Mon Sep 17 00:00:00 2001 From: Jungwon Sohn Date: Fri, 31 Jul 2026 15:43:44 +0900 Subject: [PATCH 3/6] fix(ci): use a Swift 6.2 capable iOS runner (#189) --- .github/workflows/ios-app-store-connect.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ios-app-store-connect.yml b/.github/workflows/ios-app-store-connect.yml index 5af3df2..2011796 100644 --- a/.github/workflows/ios-app-store-connect.yml +++ b/.github/workflows/ios-app-store-connect.yml @@ -13,7 +13,8 @@ concurrency: jobs: upload: name: Build and upload iOS app - runs-on: macos-15 + # Expo's Swift package dependencies require Swift tools 6.2 or newer. + runs-on: macos-26 environment: app-store-production env: APPLE_TEAM_ID: ${{ vars.APPLE_TEAM_ID }} From 3373337cee5aec15f8d5acb1e56db3e8c4c721ac Mon Sep 17 00:00:00 2001 From: Jungwon Sohn Date: Fri, 31 Jul 2026 16:03:58 +0900 Subject: [PATCH 4/6] fix(ci): target selected Google Play track (#191) --- .github/workflows/android-google-play.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/android-google-play.yml b/.github/workflows/android-google-play.yml index ae5b95c..5dc29c2 100644 --- a/.github/workflows/android-google-play.yml +++ b/.github/workflows/android-google-play.yml @@ -88,6 +88,5 @@ jobs: serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }} packageName: ${{ vars.ANDROID_PACKAGE_NAME }} releaseFiles: mobile/android/app/build/outputs/bundle/release/app-release.aab - tracks: ${{ inputs.track }} + track: ${{ inputs.track }} status: ${{ inputs.release_status }} - changesNotSentForReview: true From f26d5bc65771de3ccba0ca8b798c6aeb8b1eeb12 Mon Sep 17 00:00:00 2001 From: Jungwon Sohn Date: Fri, 31 Jul 2026 16:47:17 +0900 Subject: [PATCH 5/6] ci(mobile): distribute stores from main releases (#193) * ci(mobile): distribute stores from main releases * test(ci): cover main-only store distribution --- .github/workflows/android-google-play.yml | 16 +++---------- .github/workflows/ios-app-store-connect.yml | 2 +- .github/workflows/release.yml | 17 +++++++++++++- mobile/RELEASING.md | 25 +++++++++++---------- tests/releaseWorkflow.test.ts | 18 ++++++++++++--- 5 files changed, 48 insertions(+), 30 deletions(-) diff --git a/.github/workflows/android-google-play.yml b/.github/workflows/android-google-play.yml index 5dc29c2..c257776 100644 --- a/.github/workflows/android-google-play.yml +++ b/.github/workflows/android-google-play.yml @@ -1,24 +1,14 @@ name: Android Google Play on: - workflow_dispatch: + workflow_call: inputs: track: - description: Google Play track to receive the release - type: choice + type: string required: true - default: internal - options: - - internal - - production release_status: - description: Publish state for the selected track - type: choice + type: string required: true - default: draft - options: - - draft - - completed permissions: contents: read diff --git a/.github/workflows/ios-app-store-connect.yml b/.github/workflows/ios-app-store-connect.yml index 2011796..618462f 100644 --- a/.github/workflows/ios-app-store-connect.yml +++ b/.github/workflows/ios-app-store-connect.yml @@ -1,7 +1,7 @@ name: iOS App Store Connect on: - workflow_dispatch: + workflow_call: permissions: contents: read diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f455a85..0e39aa6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -136,9 +136,24 @@ jobs: dist/*.blockmap if-no-files-found: error - release: + app-store-connect: + needs: [check, build] + if: needs.check.outputs.already-released == 'false' + uses: ./.github/workflows/ios-app-store-connect.yml + secrets: inherit + + google-play: needs: [check, build] if: needs.check.outputs.already-released == 'false' + uses: ./.github/workflows/android-google-play.yml + with: + track: production + release_status: completed + secrets: inherit + + release: + needs: [check, build, app-store-connect, google-play] + if: needs.check.outputs.already-released == 'false' runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 diff --git a/mobile/RELEASING.md b/mobile/RELEASING.md index 52d3845..99b8374 100644 --- a/mobile/RELEASING.md +++ b/mobile/RELEASING.md @@ -58,14 +58,20 @@ OPENSCENE_KEY_PASSWORD=… build falls back to the debug key, so a local build still works for testing and only a real submission needs the keystore. -## App Store Connect automation +## Store distribution on main releases -The manually triggered **iOS App Store Connect** workflow builds an IPA and -uploads it to App Store Connect. It never submits an app for review: that -remains an explicit App Store Connect action after build processing and metadata -review. +The **release** workflow is the only store-distribution trigger. It runs when +an unreleased version is promoted to `main`, after the release verification and +desktop packaging jobs finish. It calls the iOS and Android distribution +workflows; they cannot be run manually. A push to `main` with an already tagged +version skips all release and store-distribution work. -Create the `app-store-production` GitHub Environment, restrict it to the `dev` +The iOS job builds an IPA and uploads it to App Store Connect. It never submits +an app for review: that remains an explicit App Store Connect action after build +processing and metadata review. The Android job uploads the signed AAB to the +Google Play **production** track with status `completed`. + +Create the `app-store-production` GitHub Environment, restrict it to the `main` branch, and require a reviewer before deploying. Store the following values as environment configuration (not in the repository): @@ -83,13 +89,8 @@ commit any of these files or their decoded values. ### Google Play automation -The manually triggered **Android Google Play** workflow builds a signed Android -App Bundle (AAB) and uploads it to the explicitly selected Play track. It -defaults to an `internal` track `draft`; selecting `production` and `completed` -is a deliberate release decision made at dispatch time. - Create the `play-store-production` GitHub Environment, restrict it to the -`dev` branch, and require a reviewer before deploying. Store the following +`main` branch, and require a reviewer before deploying. Store the following values as environment configuration (not in the repository): - Variable: `ANDROID_PACKAGE_NAME` (`com.sloki9637.openscene`). diff --git a/tests/releaseWorkflow.test.ts b/tests/releaseWorkflow.test.ts index 046d096..09df7c5 100644 --- a/tests/releaseWorkflow.test.ts +++ b/tests/releaseWorkflow.test.ts @@ -19,11 +19,11 @@ describe('release workflow', () => { // publish again, so every later step is gated on the tag being absent. expect(workflow).toContain('if git rev-parse -q --verify "refs/tags/${TAG}"'); expect(workflow).toContain("already-released=true"); - // Packaging and publishing are separate jobs, so each has to be gated too; - // a job without the guard would run on any push to main. + // Packaging, store distribution, and publishing are separate jobs, so each + // has to be gated too; a job without the guard would run on any push to main. expect(workflow).toContain("if: needs.check.outputs.already-released == 'false'"); const jobGates = workflow.match(/if: needs\.check\.outputs\.already-released == 'false'/g) ?? []; - expect(jobGates.length).toBe(2); + expect(jobGates.length).toBe(4); }); it('verifies the exact commit it packages', () => { @@ -81,10 +81,22 @@ describe('release workflow', () => { const uses = workflow.match(/uses: [^\n]+/g) ?? []; expect(uses.length).toBeGreaterThan(0); for (const use of uses) { + // Reusable workflows in this repository are versioned by the exact + // commit promoted to main, so they intentionally have a local path + // rather than an external action ref. + if (use.includes('uses: ./.github/workflows/')) continue; expect(use).toMatch(/@[0-9a-f]{40}/); } }); + it('distributes mobile stores only as part of a new main release', () => { + expect(workflow).toContain('uses: ./.github/workflows/ios-app-store-connect.yml'); + expect(workflow).toContain('uses: ./.github/workflows/android-google-play.yml'); + expect(workflow).toContain('track: production'); + expect(workflow).toContain('release_status: completed'); + expect(workflow).toContain('needs: [check, build, app-store-connect, google-play]'); + }); + it('keeps packaging able to run locally with the same inputs', () => { expect(packageJson.scripts.package).toBe('npm run build && electron-builder --publish never'); expect(packageJson.devDependencies['electron-builder']).toBeDefined(); From 7381bb8c7beccdda6c5b3271056c8ef5d3f696cf Mon Sep 17 00:00:00 2001 From: Jungwon Sohn Date: Fri, 31 Jul 2026 17:21:28 +0900 Subject: [PATCH 6/6] release: prepare 0.3.1 store build (#195) --- mobile/RELEASING.md | 2 +- mobile/app.json | 6 +++--- package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mobile/RELEASING.md b/mobile/RELEASING.md index 99b8374..0ce815a 100644 --- a/mobile/RELEASING.md +++ b/mobile/RELEASING.md @@ -10,7 +10,7 @@ survive `expo prebuild` belongs in a config plugin, as the release signing does. | --- | --- | | Display name | OpenScene | | iOS bundle id / Android applicationId | `com.sloki9637.openscene` | -| Version | `0.3.0` (`expo.version`) | +| Version | `0.3.1` (`expo.version`) | | iOS build number | `expo.ios.buildNumber` | | Android version code | `expo.android.versionCode` | diff --git a/mobile/app.json b/mobile/app.json index 6919f16..665ec0c 100644 --- a/mobile/app.json +++ b/mobile/app.json @@ -2,7 +2,7 @@ "expo": { "name": "OpenScene", "slug": "openscene", - "version": "0.3.0", + "version": "0.3.1", "orientation": "portrait", "icon": "./assets/icon.png", "scheme": "openscene", @@ -15,7 +15,7 @@ "ios": { "supportsTablet": true, "bundleIdentifier": "com.sloki9637.openscene", - "buildNumber": "1", + "buildNumber": "2", "infoPlist": { "NSPhotoLibraryUsageDescription": "OpenScene reads the videos you pick so you can put them on a timeline. It copies the ones you choose into the project and never scans your library on its own.", "NSPhotoLibraryAddUsageDescription": "OpenScene saves a finished export to your photo library when you ask it to.", @@ -31,7 +31,7 @@ }, "predictiveBackGestureEnabled": false, "package": "com.sloki9637.openscene", - "versionCode": 1, + "versionCode": 2, "blockedPermissions": [ "android.permission.RECORD_AUDIO", "android.permission.SYSTEM_ALERT_WINDOW", diff --git a/package-lock.json b/package-lock.json index 0ebf6d3..0e2c2ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "video-window-recorder", - "version": "0.2.0", + "version": "0.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "video-window-recorder", - "version": "0.2.0", + "version": "0.3.1", "dependencies": { "@langchain/anthropic": "^1.5.2", "@langchain/core": "^1.2.3", diff --git a/package.json b/package.json index eb291c3..2f0e808 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "video-window-recorder", "productName": "OpenScene", - "version": "0.3.0", + "version": "0.3.1", "description": "OpenScene secure Electron MVP for selected-window preview and local WebM recording.", "main": "./out/main/index.js", "type": "module",