@livx.cc/appwrap 0.20.3 → 0.20.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livx.cc/appwrap",
3
- "version": "0.20.3",
3
+ "version": "0.20.4",
4
4
  "description": "Wrap any PWA into a native app with native capabilities (appwrap runtime + @livx.cc/native-kit).",
5
5
  "license": "MIT",
6
6
  "author": "Elya Livshitz",
@@ -156,7 +156,14 @@ export const MODULES: ModuleManifest[] = [
156
156
  // string + the healthkit entitlement, both module-owned. No background execution — HealthKit
157
157
  // already has the steps the OS recorded while the app was killed.
158
158
  ios: {
159
- permissions: [{ key: 'NSHealthShareUsageDescription', domain: 'health', defaultUsage: 'Read your step count from the Health app.' }],
159
+ // App Store validation REQUIRES both Share AND Update purpose strings whenever the HealthKit
160
+ // entitlement is present — even for a read-only app (else upload fails 409 "Missing purpose
161
+ // string … NSHealthUpdateUsageDescription"). Device debug builds don't validate this; only the
162
+ // App Store upload does.
163
+ permissions: [
164
+ { key: 'NSHealthShareUsageDescription', domain: 'health', defaultUsage: 'Read your step count from the Health app.' },
165
+ { key: 'NSHealthUpdateUsageDescription', domain: 'health', defaultUsage: 'Read your step count from the Health app.' },
166
+ ],
160
167
  entitlements: { 'com.apple.developer.healthkit': true },
161
168
  },
162
169
  // Android primary = Health Connect (system store, Wear-inclusive, survives kill — matches iOS).
package/src/cli.ts CHANGED
@@ -28,8 +28,19 @@ function deriveBuild(version: string): number {
28
28
  return maj * 10000 + min * 100 + patch;
29
29
  }
30
30
 
31
- /** Resolved monotonic build number: explicit `buildNumber` (e.g. CI run #) wins, else derived. */
31
+ /**
32
+ * Resolved monotonic build number (iOS CFBundleVersion / Android versionCode).
33
+ * Precedence: `APPWRAP_BUILD_NUMBER` env (CI run #) > explicit `cfg.buildNumber` > derived from version.
34
+ * The env override means CI gets a monotonic, collision-free build number for free — no per-app config
35
+ * plumbing — which is the whole point: the derived default is CONSTANT per version, so repeat uploads
36
+ * of the same marketing version would 409 ("build already exists") without it.
37
+ */
32
38
  function buildNumberOf(cfg: AppwrapConfig): number {
39
+ const env = process.env.APPWRAP_BUILD_NUMBER;
40
+ if (env != null && env !== '') {
41
+ const n = parseInt(env, 10);
42
+ if (!Number.isNaN(n)) return n;
43
+ }
33
44
  if (cfg.buildNumber != null) {
34
45
  const n = parseInt(String(cfg.buildNumber), 10);
35
46
  if (!Number.isNaN(n)) return n;
@@ -9,9 +9,15 @@
9
9
  # exist on Play with one prior manual upload before supply works)
10
10
  name: Release Android
11
11
  on:
12
+ workflow_dispatch:
12
13
  push:
13
14
  tags: ['v*']
14
15
 
16
+ # Monotonic store build number (Android versionCode). appwrap CLI reads APPWRAP_BUILD_NUMBER over the
17
+ # constant derived default — Play rejects a versionCode it has already seen. run_number is increasing.
18
+ env:
19
+ APPWRAP_BUILD_NUMBER: ${{ github.run_number + 100 }}
20
+
15
21
  jobs:
16
22
  play:
17
23
  runs-on: ubuntu-latest
@@ -14,6 +14,12 @@ on:
14
14
  push:
15
15
  tags: ['v*']
16
16
 
17
+ # Monotonic store build number (CFBundleVersion). The appwrap CLI reads APPWRAP_BUILD_NUMBER and it wins
18
+ # over the (constant-per-version) derived default — without this, repeat uploads of the same marketing
19
+ # version 409 ("build already exists"). run_number is strictly increasing; +100 clears low derived values.
20
+ env:
21
+ APPWRAP_BUILD_NUMBER: ${{ github.run_number + 100 }}
22
+
17
23
  jobs:
18
24
  testflight:
19
25
  runs-on: macos-15