chore(android): move release signing secrets to gitignored keystore.properties
This commit is contained in:
parent
0ac57d4250
commit
fc0231bea5
3 changed files with 102 additions and 3 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -35,6 +35,7 @@ yarn.lock
|
|||
# Local secrets & signing material (never commit)
|
||||
*.jks
|
||||
*.keystore
|
||||
keystore.properties
|
||||
local.properties
|
||||
|
||||
# Local build artifacts
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@
|
|||
"build": "npm i --silent && vite build -l error && cp dist/index.html dist/404.html && echo 'Project built successfully!'",
|
||||
"test": "npm i --silent && tsc --noEmit && eslint && vitest run --reporter=dot --silent && vite build -l error && cp dist/index.html dist/404.html && echo 'All tests passed!'",
|
||||
"deploy": "npm i --silent && npm run build && npx -y nostr-deploy-cli deploy --skip-setup",
|
||||
"android:init": "npm run android:build:apk && npx cap add android && npx cap sync android && node scripts/inject-amber-queries.mjs && node scripts/inject-main-activity.mjs && node scripts/inject-network-security.mjs",
|
||||
"android:sync": "npm run android:build:apk && npx cap sync android && node scripts/sync-android-version.mjs && node scripts/inject-amber-queries.mjs && node scripts/inject-main-activity.mjs && node scripts/inject-network-security.mjs",
|
||||
"android:init": "npm run android:build:apk && npx cap add android && npx cap sync android && node scripts/inject-amber-queries.mjs && node scripts/inject-main-activity.mjs && node scripts/inject-network-security.mjs && node scripts/inject-signing-config.mjs",
|
||||
"android:sync": "npm run android:build:apk && npx cap sync android && node scripts/sync-android-version.mjs && node scripts/inject-amber-queries.mjs && node scripts/inject-main-activity.mjs && node scripts/inject-network-security.mjs && node scripts/inject-signing-config.mjs",
|
||||
"android:open": "npx cap open android",
|
||||
"android:version": "node scripts/sync-android-version.mjs",
|
||||
"android:build": "npm run android:build:apk && npx cap sync android && node scripts/sync-android-version.mjs && node scripts/inject-amber-queries.mjs && node scripts/inject-main-activity.mjs && node scripts/inject-network-security.mjs && cd android && ./gradlew assembleRelease",
|
||||
"android:build": "npm run android:build:apk && npx cap sync android && node scripts/sync-android-version.mjs && node scripts/inject-amber-queries.mjs && node scripts/inject-main-activity.mjs && node scripts/inject-network-security.mjs && node scripts/inject-signing-config.mjs && cd android && ./gradlew assembleRelease",
|
||||
"android:build:apk": "CAPACITOR_BUILD=1 vite build && sed -i 's|<script type=\"module\" src=\"/shakespeare_tailwind[^\"]*\\.js\"></script>||g' dist/index.html && sed -i 's|<style type=\"text/tailwindcss\">|<style>|g' dist/index.html && cp dist/index.html dist/404.html"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
|||
98
scripts/inject-signing-config.mjs
Normal file
98
scripts/inject-signing-config.mjs
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* Inject the Android release signing configuration.
|
||||
*
|
||||
* WHY THIS EXISTS
|
||||
* ───────────────
|
||||
* The Android project (android/) is generated and NOT tracked in git —
|
||||
* `npm run android:init` recreates it with `cap add android`. Release signing
|
||||
* therefore has to be re-applied after every regeneration, and its secrets must
|
||||
* never be committed. Previously the keystore path, alias and passwords were
|
||||
* hardcoded inline in android/app/build.gradle.
|
||||
*
|
||||
* This script (idempotent, part of the android build, same pattern as the other
|
||||
* scripts/inject-*.mjs helpers):
|
||||
* 1. Removes any previously managed signing block.
|
||||
* 2. Removes a legacy hardcoded signingConfigs block (inline passwords).
|
||||
* 3. Writes a managed signingConfigs block into android/app/build.gradle that
|
||||
* reads secrets from the gitignored keystore.properties at the repo root.
|
||||
*
|
||||
* It exits quietly (0) when android/ isn't generated yet, or when
|
||||
* keystore.properties is absent — so debug-only builds without a keystore still
|
||||
* work.
|
||||
*/
|
||||
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname, join } from 'node:path';
|
||||
|
||||
const root = join(dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const buildGradle = join(root, 'android', 'app', 'build.gradle');
|
||||
const keystoreProps = join(root, 'keystore.properties');
|
||||
|
||||
const BEGIN = '// >>> managed by scripts/inject-signing-config.mjs';
|
||||
const END = '// <<< managed by scripts/inject-signing-config.mjs <<<';
|
||||
|
||||
if (!existsSync(buildGradle)) {
|
||||
console.log('[inject-signing-config] android/ not generated yet — skipping.');
|
||||
process.exit(0);
|
||||
}
|
||||
if (!existsSync(keystoreProps)) {
|
||||
console.log('[inject-signing-config] keystore.properties not found — skipping release signing.');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const managedLines = [
|
||||
`${BEGIN} >>>`,
|
||||
'// Release signing is read from keystore.properties at the repo root',
|
||||
'// (gitignored). Edit that file, not this block.',
|
||||
'def _keystoreProps = new Properties()',
|
||||
"def _keystorePropsFile = rootProject.file('../keystore.properties')",
|
||||
'if (_keystorePropsFile.exists()) {',
|
||||
' _keystorePropsFile.withInputStream { _keystoreProps.load(it) }',
|
||||
'}',
|
||||
'signingConfigs {',
|
||||
' release {',
|
||||
' if (_keystorePropsFile.exists()) {',
|
||||
" storeFile rootProject.file('../' + _keystoreProps['storeFile'])",
|
||||
" storePassword _keystoreProps['storePassword']",
|
||||
" keyAlias _keystoreProps['keyAlias']",
|
||||
" keyPassword _keystoreProps['keyPassword']",
|
||||
' }',
|
||||
' }',
|
||||
'}',
|
||||
END,
|
||||
];
|
||||
const managed = managedLines.map((l) => ' ' + l).join('\n');
|
||||
|
||||
let src = readFileSync(buildGradle, 'utf8');
|
||||
const before = src;
|
||||
|
||||
// 1. Drop any previously managed block so the script is idempotent.
|
||||
const bIdx = src.indexOf(BEGIN);
|
||||
if (bIdx !== -1) {
|
||||
const eIdx = src.indexOf(END, bIdx);
|
||||
if (eIdx !== -1) {
|
||||
const lineStart = src.lastIndexOf('\n', bIdx);
|
||||
const lineEnd = src.indexOf('\n', eIdx);
|
||||
src = src.slice(0, lineStart) + (lineEnd === -1 ? '' : src.slice(lineEnd));
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Drop a legacy hardcoded signingConfigs block (has an inline keyPassword).
|
||||
src = src.replace(/\n[ \t]*signingConfigs\s*\{[\s\S]*?keyPassword\s+"[^"]*"\s*\}\s*\}/g, '');
|
||||
|
||||
// 3. Insert the managed block immediately after the `android {` opening.
|
||||
const androidIdx = src.indexOf('android {');
|
||||
if (androidIdx === -1) {
|
||||
console.error('[inject-signing-config] could not find `android {` in build.gradle — aborting.');
|
||||
process.exit(1);
|
||||
}
|
||||
const lineEnd = src.indexOf('\n', androidIdx);
|
||||
src = src.slice(0, lineEnd + 1) + managed + '\n' + src.slice(lineEnd + 1);
|
||||
|
||||
if (src === before) {
|
||||
console.log('[inject-signing-config] already up to date.');
|
||||
} else {
|
||||
writeFileSync(buildGradle, src);
|
||||
console.log('[inject-signing-config] ✓ Wrote managed release signing config into android/app/build.gradle.');
|
||||
}
|
||||
Loading…
Reference in a new issue