play build: signing passwords only through the child environment, never argv
This commit is contained in:
parent
7960063e0e
commit
e4ebbb825d
5 changed files with 13 additions and 12 deletions
|
|
@ -6,7 +6,7 @@
|
|||
- `storebound apps ignore|unignore [--store apple|play]`: hide dormant apps, or one store side of an app, from watch, reads and the desktop (MCP apps_ignore / apps_unignore).
|
||||
- Reviews: a store read that fails is an error, not an empty "no new reviews" list; the Reviews tab notes Apple API lag and Play's 7-day window (pitfall 106).
|
||||
- Desktop: live store thumbnails load right away, also in a hidden window.
|
||||
- `play build` passes the upload key (ANDROID_KEYSTORE, ...) to Gradle as `-Pandroid.injected.signing.*` too (passwords masked in the printed command), so a build file that signs only from a local keystore.properties no longer gives an unsigned AAB in CI (pitfall 107).
|
||||
- `play build` passes the upload key (ANDROID_KEYSTORE, ...) to Gradle as injected signing properties (store file and alias as `-P` arguments, the passwords only through `ORG_GRADLE_PROJECT_*` environment variables, never on argv), so a build file that signs only from a local keystore.properties no longer gives an unsigned AAB in CI (pitfall 107).
|
||||
- `play build`, `play upload` and `play release` of a local AAB verify it is signed (META-INF entries, `jarsigner -verify` when a JDK exists) and fail with the fix before any upload.
|
||||
- `apple build --version` and `apple upload` refuse an IPA whose CFBundleShortVersionString is not the intended / editable App Store version; `--allow-version-mismatch` overrides (pitfall 108).
|
||||
- Play release notes that name iOS, iPhone or the App Store are caught by `storebound check` and `play build`, not only at release time (pitfall 109).
|
||||
|
|
|
|||
|
|
@ -70,11 +70,10 @@ export function gradleArgs(t: GradleTarget, o: { versionCode?: number; versionNa
|
|||
|
||||
/** The upload key as Gradle project properties (-Pandroid.injected.signing.*). A project whose build file signs only
|
||||
* from a local keystore.properties (absent in CI) gives an unsigned AAB otherwise (Play: 403 "All uploaded bundles
|
||||
* must be signed"). The passwords are on this argv: print it only through maskArgs. */
|
||||
* must be signed"). Only the file and alias go on argv; the passwords travel through signingEnv (ORG_GRADLE_PROJECT_*), never argv. */
|
||||
export function signingArgs(s: AndroidSigning | null): string[] {
|
||||
if (!s) return [];
|
||||
return [`-Pandroid.injected.signing.store.file=${s.storeFile}`, `-Pandroid.injected.signing.store.password=${s.storePassword}`,
|
||||
`-Pandroid.injected.signing.key.alias=${s.keyAlias}`, `-Pandroid.injected.signing.key.password=${s.keyPassword}`];
|
||||
return [`-Pandroid.injected.signing.store.file=${s.storeFile}`, `-Pandroid.injected.signing.key.alias=${s.keyAlias}`];
|
||||
}
|
||||
|
||||
/** An argv for logs and plans: the signing passwords are replaced by ***. Pure. */
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
// unless --version-code is given, runs `gradlew :app:bundleRelease` (Flutter: flutter build appbundle) and copies the
|
||||
// AAB to <out>/<package>-<versionCode>.aab, checked by reading its manifest. Signing: the upload key from env or
|
||||
// .storebound/credentials.json (ANDROID_KEYSTORE, ANDROID_KEYSTORE_PASSWORD, ANDROID_KEY_ALIAS, ANDROID_KEY_PASSWORD)
|
||||
// goes to Gradle as injected signing properties (-Pandroid.injected.signing.* and the ORG_GRADLE_PROJECT_ environment; the
|
||||
// passwords are masked in every printed command); without it the
|
||||
// goes to Gradle as injected signing properties (store file and alias as -P arguments, the passwords only through
|
||||
// ORG_GRADLE_PROJECT_* in the child environment, never argv); without it the
|
||||
// project's own signingConfig signs. Local only: Play is only read (version codes).
|
||||
// Before Gradle runs, the app module's build file must read -PversionCode / -PversionName in defaultConfig (a literal
|
||||
// or an env var keeps the AAB at that value; android.injected.version.* does not override it for bundleRelease): a
|
||||
|
|
|
|||
|
|
@ -1290,9 +1290,8 @@ that fails without the fix (see CONTRIBUTING.md).
|
|||
upload key in `ANDROID_KEYSTORE` / `ANDROID_KEYSTORE_PASSWORD` / `ANDROID_KEY_ALIAS` / `ANDROID_KEY_PASSWORD` reached
|
||||
Gradle only through `ORG_GRADLE_PROJECT_*`, which that build file does not use; the AAB came out unsigned and the
|
||||
refusal came only at upload.
|
||||
- **Do:** set the four variables (env or `.storebound/credentials.json`); `play build` now also passes them as
|
||||
`-Pandroid.injected.signing.store.file|store.password|key.alias|key.password`. The printed command and the plan show
|
||||
the passwords as `***`.
|
||||
- **Do:** set the four variables (env or `.storebound/credentials.json`); `play build` now also passes `-Pandroid.injected.signing.store.file` and `.key.alias`; the
|
||||
passwords go only through `ORG_GRADLE_PROJECT_android.injected.signing.*.password` in the child environment, never argv.
|
||||
- **Guard:** `signingArgs` / `maskArgs` (`cli/lib/gradle.ts`); right after the build, and before `play upload` /
|
||||
`play release` of a local AAB, `assertAabSigned` checks the META-INF `*.SF` + `*.RSA|DSA|EC` entries (and runs
|
||||
`jarsigner -verify` when a JDK is on PATH) and fails with the fix, before any upload (`tests/build-sign.test.ts`).
|
||||
|
|
|
|||
|
|
@ -532,13 +532,16 @@ describe('signed AAB, masked signing, IPA version train, release notes', () => {
|
|||
test('gradleArgs passes the injected signing properties, maskArgs hides the passwords', () => {
|
||||
const argv = gradleArgs(t, { hasWrapper: true, signing: s }, 'linux');
|
||||
expect(argv).toContain('-Pandroid.injected.signing.store.file=/k/upload.jks');
|
||||
expect(argv).toContain('-Pandroid.injected.signing.store.password=pw-store');
|
||||
expect(argv).toContain('-Pandroid.injected.signing.key.alias=upload');
|
||||
expect(argv).toContain('-Pandroid.injected.signing.key.password=pw-key');
|
||||
expect(argv.join(' ')).not.toContain('pw-store');
|
||||
expect(argv.join(' ')).not.toContain('pw-key');
|
||||
expect(argv.join(' ')).not.toContain('password');
|
||||
const env = signingEnv(s);
|
||||
expect(env['ORG_GRADLE_PROJECT_android.injected.signing.store.password']).toBe('pw-store');
|
||||
expect(env['ORG_GRADLE_PROJECT_android.injected.signing.key.password']).toBe('pw-key');
|
||||
const shown = maskArgs(argv).join(' ');
|
||||
expect(shown).not.toContain('pw-store');
|
||||
expect(shown).not.toContain('pw-key');
|
||||
expect(shown).toContain('store.password=***');
|
||||
expect(shown).toContain('key.alias=upload');
|
||||
expect(gradleArgs(t, { hasWrapper: true }, 'linux').join(' ')).not.toContain('signing');
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue