Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/CI.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,6 @@ jobs:

- name: Lint
run: npm run lint

- name: Check formatting
run: npm run format:check
13 changes: 7 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"pretest": "node -e \"require('fs').rmSync('bin', { recursive: true, force: true })\"",
"test": "tsc && node -e \"require('fs').cpSync('test/resources', 'bin/test/resources', { recursive: true })\" && mocha",
"prettier": "prettier --write \"./**/*.ts\"",
"format:check": "prettier --check \"script/**/*.ts\" \"test/**/*.ts\"",
"lint": "eslint \"script/**/*.ts\" \"test/**/*.ts\"",
"lint:fix": "eslint \"script/**/*.ts\" \"test/**/*.ts\" --fix"
},
Expand Down Expand Up @@ -68,7 +69,7 @@
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.45.0",
"mocha": "^12.0.1",
"prettier": "^2.8.8",
"prettier": "^3.9.10",
"sinon": "15.1.2",
"superagent-mock": "^4.0.0",
"typescript": "^5.1.3"
Expand Down
2 changes: 2 additions & 0 deletions prettier.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@
module.exports = {
printWidth: 135,
endOfLine: "auto",
// Prettier 3 defaults to "all"; keep the existing style
trailingComma: "es5",
};
10 changes: 7 additions & 3 deletions script/binary-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import * as yauzl from "yauzl";
import { readFile } from "node:fs/promises";
import { buffer as readStreamToBuffer } from "node:stream/consumers";
import * as protobuf from "protobufjs";
import * as plist from "plist"
import * as plist from "plist";
import * as bplist from "bplist-parser";

export async function extractMetadataFromAndroid(extractFolder, outputFolder) {
Expand Down Expand Up @@ -219,13 +219,17 @@ const AAB_MANIFEST_ENTRY_NAME = "base/manifest/AndroidManifest.xml";
// An AAB's <manifest> is protobuf-encoded as an aapt.pb.XmlNode. We only read a
// few attributes, so we declare just that slice (field numbers from AOSP
// aapt2/Resources.proto); the decoder skips every field we omit.
const XmlNode = protobuf.parse(`
const XmlNode = protobuf
.parse(
`
syntax = "proto3";
package aapt.pb;
message XmlAttribute { string name = 2; string value = 3; }
message XmlElement { string name = 3; repeated XmlAttribute attribute = 4; }
message XmlNode { XmlElement element = 1; }
`).root.lookupType("aapt.pb.XmlNode");
`
)
.root.lookupType("aapt.pb.XmlNode");

async function readManifestAttributes(file: string | Buffer): Promise<ManifestAttribute[]> {
const zipFile = typeof file === "string" ? await yauzl.openPromise(file) : await yauzl.fromBufferPromise(file);
Expand Down
12 changes: 5 additions & 7 deletions script/command-executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1050,8 +1050,7 @@ async function patch(command: cli.IPatchCommand): Promise<void> {

// Standard fields use null as "not provided"; buildNumber uses undefined (null means reset).
// Check both to avoid treating an unset buildNumber (undefined) as a valid update.
const hasUpdate =
Object.values(packageInfo).some((v) => v !== null && v !== undefined) || command.buildNumber !== undefined;
const hasUpdate = Object.values(packageInfo).some((v) => v !== null && v !== undefined) || command.buildNumber !== undefined;

if (!hasUpdate) {
throw new Error("At least one property must be specified to patch a release.");
Expand Down Expand Up @@ -1169,10 +1168,7 @@ interface ReactReleaseInputs {
// Up-front validation for the React-style release flows (release-react / release-expo).
// Throws on the first violation and returns the derived inputs. The semver-range check
// is done by the caller since it needs the resolved app version.
function validateReactReleaseCommand(
command: cli.IReleaseReactCommand,
options: { resolveEntryFile: boolean }
): ReactReleaseInputs {
function validateReactReleaseCommand(command: cli.IReleaseReactCommand, options: { resolveEntryFile: boolean }): ReactReleaseInputs {
const { resolveEntryFile } = options;
const platform: string = (command.platform = command.platform.toLowerCase());

Expand All @@ -1194,7 +1190,9 @@ function validateReactReleaseCommand(
try {
projectPackageJson = require(path.join(process.cwd(), "package.json"));
} catch (error) {
throw new Error('Unable to find or read "package.json" in the CWD. The command must be executed in a React Native project folder.');
throw new Error(
'Unable to find or read "package.json" in the CWD. The command must be executed in a React Native project folder.'
);
}

const projectName: string = projectPackageJson.name;
Expand Down
22 changes: 14 additions & 8 deletions script/utils/gradle-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ const FALLBACK_HINT = "Pass the version explicitly with --targetBinaryVersion to
// "revopush"-prefixed to avoid collisions with project tasks; written in Groovy,
// which Gradle accepts as an init script for projects of either DSL.
const PRINT_VERSION_TASK = "_revopushPrintVersion";
const printVersionInitScript = (moduleName: string) => `
const printVersionInitScript = (moduleName: string) =>
`
allprojects {
afterEvaluate { proj ->
if (proj.name == '${moduleName}') {
Expand Down Expand Up @@ -68,10 +69,12 @@ export async function getAndroidVersionInfo(gradleFile?: string | null): Promise
const appVersion = resolveAppVersion(versionName, buildFile);
const buildNumber = resolveBuildNumber(versionCode, buildFile);
if (!buildNumber) {
console.log(chalk.yellow(
`Warning: Unable to read "android.defaultConfig.versionCode" from "${buildFile}". ` +
`This is expected if it is set dynamically (e.g. on CI). Pass --buildNumber explicitly to include it in the release.`
));
console.log(
chalk.yellow(
`Warning: Unable to read "android.defaultConfig.versionCode" from "${buildFile}". ` +
`This is expected if it is set dynamically (e.g. on CI). Pass --buildNumber explicitly to include it in the release.`
)
);
}
return { appVersion, buildNumber };
}
Expand Down Expand Up @@ -135,7 +138,10 @@ async function parseGroovyDslBuildFile(buildFile: string): Promise<any> {
function getLegacyReactProperty(parsed: any, key: string): string | undefined {
const entries: string[] = parsed["project.ext.react"] || [];
const entry = entries.map((prop) => prop.replace(/\/\/.*$/gm, "").trim()).find((prop) => prop.startsWith(`${key}:`));
return entry?.slice(key.length + 1).trim().replace(/^["']|["']$/g, "");
return entry
?.slice(key.length + 1)
.trim()
.replace(/^["']|["']$/g, "");
}

async function parseGroovyDslVersion(buildFile: string): Promise<GradleVersionFields> {
Expand All @@ -146,7 +152,7 @@ async function parseGroovyDslVersion(buildFile: string): Promise<GradleVersionFi
if (!defaultConfig && /^\s*val\s+/m.test(fs.readFileSync(buildFile, "utf8"))) {
throw new Error(
`"${buildFile}" appears to contain Kotlin DSL syntax. Gradle determines the script language by file extension — ` +
`rename the file to "${path.basename(buildFile)}.kts" to make it a valid Kotlin DSL build script.`
`rename the file to "${path.basename(buildFile)}.kts" to make it a valid Kotlin DSL build script.`
);
}
return {
Expand Down Expand Up @@ -193,7 +199,7 @@ function resolveAppVersion(versionName: string | null, buildFile: string): strin
if (!appVersion || !isValidVersion(appVersion)) {
throw new Error(
`Unable to resolve a valid semver app version (e.g. 1.3.2) from "android.defaultConfig.versionName" in "${buildFile}" ` +
`(found: "${versionName}"). ${FALLBACK_HINT}`
`(found: "${versionName}"). ${FALLBACK_HINT}`
);
}
return appVersion;
Expand Down
Loading