Skip to content

Commit e1c0b10

Browse files
billnbellkelset
authored andcommitted
chore(releases): improve bump oss script to allow less human errors
Summary: This added React-ImageManager to the use_frameworks! - a lot of rpm modules podspec need this. bypass-github-export-checks [iOS] [FIXED] - Add React-ImageManager path to work with use_frameworks! For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests Pull Request resolved: #38247 Test Plan: Should not be breaking - it will add to the header_search_paths React-ImageManager Reviewed By: dmytrorykun Differential Revision: D47593749 Pulled By: cipolleschi fbshipit-source-id: a66e90707e5fa73573deab1f04e8d8693869a90c chore(releases): improve bump oss script to allow less human errors (#38666) Summary: One of the limitations of the existing flow for the release crew is that they need to manually remember to publish all the other packages in the monorepo ahead of a new patch release - this PR modifies the logic for the bump-oss-version script (and makes it available via yarn) so that it will not run if: * there are git changes lying around * if some of the packages need a new release it required a bit of refactoring to extract some portions of the logic from the bump-all-package-versions script, but I think the end result is pretty decent. ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [INTERNAL] [CHANGED] - improve bump oss script to allow less human errors Pull Request resolved: #38666 Test Plan: * checkout this branch * comment L54 of bump-oss-version.js (to remove the check on the branch name) * run `yarn bump-all-updated-packages`, verify that it works and that it detects that some packages have unreleased code * run `yarn bump-oss-version -t asd -v asd` (the "fake" parameters are needed to pass the yargs check), verify that it will throw an error because it finds a package that has unreleased code Reviewed By: mdvacca Differential Revision: D48156963 Pulled By: cortinico fbshipit-source-id: 2473ad5a84578c5236c905fd9aa9a88113fe8d22 # Conflicts: # scripts/publish-npm.js re-add the file nit Revert "Update new_architecture.rb for React-ImageManager (#38247)" This reverts commit 645264e249f566ce87f6aaf462e029909302fd92.
1 parent 768c960 commit e1c0b10

File tree

5 files changed

+134
-31
lines changed

5 files changed

+134
-31
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
"test-ios": "./scripts/objc-test.sh test",
4141
"test-typescript": "dtslint packages/react-native/types",
4242
"test-typescript-offline": "dtslint --localTs node_modules/typescript/lib packages/react-native/types",
43-
"bump-all-updated-packages": "node ./scripts/monorepo/bump-all-updated-packages"
43+
"bump-all-updated-packages": "node ./scripts/monorepo/bump-all-updated-packages",
44+
"trigger-react-native-release": "node ./scripts/trigger-react-native-release.js"
4445
},
4546
"workspaces": [
4647
"packages/*"
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
*/
9+
10+
const chalk = require('chalk');
11+
const {echo, exec} = require('shelljs');
12+
13+
const detectPackageUnreleasedChanges = (
14+
packageRelativePathFromRoot,
15+
packageName,
16+
ROOT_LOCATION,
17+
) => {
18+
const hashOfLastCommitInsidePackage = exec(
19+
`git log -n 1 --format=format:%H -- ${packageRelativePathFromRoot}`,
20+
{cwd: ROOT_LOCATION, silent: true},
21+
).stdout.trim();
22+
23+
const hashOfLastCommitThatChangedVersion = exec(
24+
`git log -G\\"version\\": --format=format:%H -n 1 -- ${packageRelativePathFromRoot}/package.json`,
25+
{cwd: ROOT_LOCATION, silent: true},
26+
).stdout.trim();
27+
28+
if (hashOfLastCommitInsidePackage === hashOfLastCommitThatChangedVersion) {
29+
echo(
30+
`\uD83D\uDD0E No changes for package ${chalk.green(
31+
packageName,
32+
)} since last version bump`,
33+
);
34+
return false;
35+
} else {
36+
echo(`\uD83D\uDCA1 Found changes for ${chalk.yellow(packageName)}:`);
37+
exec(
38+
`git log --pretty=oneline ${hashOfLastCommitThatChangedVersion}..${hashOfLastCommitInsidePackage} ${packageRelativePathFromRoot}`,
39+
{
40+
cwd: ROOT_LOCATION,
41+
},
42+
);
43+
echo();
44+
45+
return true;
46+
}
47+
};
48+
49+
module.exports = detectPackageUnreleasedChanges;

scripts/monorepo/bump-all-updated-packages/index.js

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const {
2525
const forEachPackage = require('../for-each-package');
2626
const checkForGitChanges = require('../check-for-git-changes');
2727
const bumpPackageVersion = require('./bump-package-version');
28+
const detectPackageUnreleasedChanges = require('./bump-utils');
2829

2930
const ROOT_LOCATION = path.join(__dirname, '..', '..', '..');
3031

@@ -62,35 +63,16 @@ const buildExecutor =
6263
return;
6364
}
6465

65-
const hashOfLastCommitInsidePackage = exec(
66-
`git log -n 1 --format=format:%H -- ${packageRelativePathFromRoot}`,
67-
{cwd: ROOT_LOCATION, silent: true},
68-
).stdout.trim();
69-
70-
const hashOfLastCommitThatChangedVersion = exec(
71-
`git log -G\\"version\\": --format=format:%H -n 1 -- ${packageRelativePathFromRoot}/package.json`,
72-
{cwd: ROOT_LOCATION, silent: true},
73-
).stdout.trim();
74-
75-
if (hashOfLastCommitInsidePackage === hashOfLastCommitThatChangedVersion) {
76-
echo(
77-
`\uD83D\uDD0E No changes for package ${chalk.green(
78-
packageName,
79-
)} since last version bump`,
80-
);
81-
66+
if (
67+
!detectPackageUnreleasedChanges(
68+
packageRelativePathFromRoot,
69+
packageName,
70+
ROOT_LOCATION,
71+
)
72+
) {
8273
return;
8374
}
8475

85-
echo(`\uD83D\uDCA1 Found changes for ${chalk.yellow(packageName)}:`);
86-
exec(
87-
`git log --pretty=oneline ${hashOfLastCommitThatChangedVersion}..${hashOfLastCommitInsidePackage} ${packageRelativePathFromRoot}`,
88-
{
89-
cwd: ROOT_LOCATION,
90-
},
91-
);
92-
echo();
93-
9476
await inquirer
9577
.prompt([
9678
{

scripts/publish-npm.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ const rawVersion =
9090
: // For nightly we continue to use 0.0.0 for clarity for npm
9191
nightlyBuild
9292
? '0.0.0'
93-
: // For pre-release and stable releases, we use the git tag of the version we're releasing (set in bump-oss-version)
93+
: // For pre-release and stable releases, we use the git tag of the version we're releasing (set in trigger-react-native-release)
9494
buildTag;
9595

9696
let version,

scripts/bump-oss-version.js renamed to scripts/trigger-react-native-release.js

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,21 @@
1414
* This script walks a releaser through bumping the version for a release
1515
* It will commit the appropriate tags to trigger the CircleCI jobs.
1616
*/
17-
const {exit} = require('shelljs');
17+
const {exit, echo} = require('shelljs');
18+
const chalk = require('chalk');
1819
const yargs = require('yargs');
1920
const inquirer = require('inquirer');
2021
const request = require('request');
22+
const path = require('path');
2123
const {getBranchName, exitIfNotOnGit} = require('./scm-utils');
2224

2325
const {parseVersion, isReleaseBranch} = require('./version-utils');
2426
const {failIfTagExists} = require('./release-utils');
27+
const checkForGitChanges = require('./monorepo/check-for-git-changes');
28+
const forEachPackage = require('./monorepo/for-each-package');
29+
const detectPackageUnreleasedChanges = require('./monorepo/bump-all-updated-packages/bump-utils.js');
30+
31+
const ROOT_LOCATION = path.join(__dirname, '..');
2532

2633
let argv = yargs
2734
.option('r', {
@@ -42,7 +49,7 @@ let argv = yargs
4249
.check(() => {
4350
const branch = exitIfNotOnGit(
4451
() => getBranchName(),
45-
"Not in git. You can't invoke bump-oss-versions.js from outside a git repo.",
52+
"Not in git. You can't invoke trigger-react-native-release from outside a git repo.",
4653
);
4754
exitIfNotOnReleaseBranch(branch);
4855
return true;
@@ -57,6 +64,52 @@ function exitIfNotOnReleaseBranch(branch) {
5764
}
5865
}
5966

67+
const buildExecutor =
68+
(packageAbsolutePath, packageRelativePathFromRoot, packageManifest) =>
69+
async () => {
70+
const {name: packageName} = packageManifest;
71+
if (packageManifest.private) {
72+
return;
73+
}
74+
75+
if (
76+
detectPackageUnreleasedChanges(
77+
packageRelativePathFromRoot,
78+
packageName,
79+
ROOT_LOCATION,
80+
)
81+
) {
82+
// if I enter here, I want to throw an error upward
83+
throw new Error(
84+
`Package ${packageName} has unreleased changes. Please release it first.`,
85+
);
86+
}
87+
};
88+
89+
const buildAllExecutors = () => {
90+
const executors = [];
91+
92+
forEachPackage((...params) => {
93+
executors.push(buildExecutor(...params));
94+
});
95+
96+
return executors;
97+
};
98+
99+
async function exitIfUnreleasedPackages() {
100+
// use the other script to verify that there's no packages in the monorepo
101+
// that have changes that haven't been released
102+
103+
const executors = buildAllExecutors();
104+
for (const executor of executors) {
105+
await executor().catch(error => {
106+
echo(chalk.red(error));
107+
// need to throw upward
108+
throw error;
109+
});
110+
}
111+
}
112+
60113
function triggerReleaseWorkflow(options) {
61114
return new Promise((resolve, reject) => {
62115
request(options, function (error, response, body) {
@@ -72,8 +125,26 @@ function triggerReleaseWorkflow(options) {
72125
async function main() {
73126
const branch = exitIfNotOnGit(
74127
() => getBranchName(),
75-
"Not in git. You can't invoke bump-oss-versions.js from outside a git repo.",
128+
"Not in git. You can't invoke trigger-react-native-release from outside a git repo.",
76129
);
130+
131+
// check for uncommitted changes
132+
if (checkForGitChanges()) {
133+
echo(
134+
chalk.red(
135+
'Found uncommitted changes. Please commit or stash them before running this script',
136+
),
137+
);
138+
exit(1);
139+
}
140+
141+
// now check for unreleased packages
142+
try {
143+
await exitIfUnreleasedPackages();
144+
} catch (error) {
145+
exit(1);
146+
}
147+
77148
const token = argv.token;
78149
const releaseVersion = argv.toVersion;
79150
failIfTagExists(releaseVersion, 'release');

0 commit comments

Comments
 (0)