Skip to content

Commit 6b35ff7

Browse files
Move @generated from build to sync (#29799)
## Overview Reverts #26616 and implements the suggested way instead. This change in #26616 broken the internal sync command, which now results in duplicated `@generated` headers. It also makes it harder to detect changes during the diff train sync. Instead, we will check for changes, and if there are changes sign the files and commit them to the sync branch. ## Strategy The new sync strategy accounts for the generated headers during the sync: - **Revert Version**: Revert the version strings - **Revert @generated**: Re-sign the files (will be the same hash as before if unchanged) - **Check**: Check if there are changes **if not, skip** - **Re-apply Version**: Now add back the new version string - **Re-sign @generated**: And re-generate the headers Then commit to branch. This ensures that if there are no changes, we'll skip. --------- Co-authored-by: Timothy Yung <[email protected]>
1 parent f5af92d commit 6b35ff7

File tree

10 files changed

+211
-56
lines changed

10 files changed

+211
-56
lines changed

.github/workflows/commit_artifacts.yml

Lines changed: 187 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ jobs:
5252
CIRCLECI_TOKEN: ${{secrets.CIRCLECI_TOKEN_DIFFTRAIN}}
5353
with:
5454
script: |
55+
// TODO: Move this to a script file.
5556
const cp = require('child_process');
5657
5758
function sleep(ms) {
@@ -250,14 +251,18 @@ jobs:
250251
grep -rl "$CURRENT_VERSION_MODERN" ./compiled || echo "No files found with $CURRENT_VERSION_MODERN"
251252
grep -rl "$CURRENT_VERSION_MODERN" ./compiled | xargs -r sed -i -e "s/$CURRENT_VERSION_MODERN/$LAST_VERSION_MODERN/g"
252253
grep -rl "$CURRENT_VERSION_MODERN" ./compiled || echo "Modern version reverted"
253-
- name: Check if only the REVISION file has changed
254+
- name: Check for changes
254255
id: check_should_commit
255256
run: |
256257
echo "Full git status"
258+
git add .
257259
git status
258260
echo "===================="
259261
if git status --porcelain | grep -qv '/REVISION'; then
260262
echo "Changes detected"
263+
echo "===== Changes ====="
264+
git --no-pager diff -U0 | grep '^[+-]' | head -n 50
265+
echo "==================="
261266
echo "should_commit=true" >> "$GITHUB_OUTPUT"
262267
else
263268
echo "No Changes detected"
@@ -322,17 +327,109 @@ jobs:
322327
grep -rl "$CURRENT_VERSION" ./compiled-rn || echo "No files found with $CURRENT_VERSION"
323328
grep -rl "$CURRENT_VERSION" ./compiled-rn | xargs -r sed -i -e "s/$CURRENT_VERSION/$LAST_VERSION/g"
324329
grep -rl "$CURRENT_VERSION" ./compiled-rn || echo "Version reverted"
325-
- name: Check if only the REVISION file has changed
326-
id: check_should_commit
330+
- name: Check changes before signing
327331
run: |
328332
echo "Full git status"
333+
git add .
329334
git status
330335
echo "===================="
331-
echo "Checking for changes"
332-
# Check if there are changes in the files other than REVISION or @generated headers
333-
# We also filter out the file name lines with "---" and "+++".
334-
if git diff -- . ':(exclude)*REVISION' | grep -vE "^(@@|diff|index|\-\-\-|\+\+\+|@generated SignedSource)" | grep "^[+-]" > /dev/null; then
336+
if git status --porcelain | grep -qv '/REVISION'; then
337+
echo "Changes detected"
338+
echo "===== Changes ====="
339+
git --no-pager diff -U0 --cached | grep '^[+-]' | head -n 50
340+
echo "==================="
341+
else
342+
echo "No Changes detected"
343+
fi
344+
- name: Revert signatures
345+
uses: actions/github-script@v6
346+
with:
347+
script: |
348+
// TODO: Move this to a script file.
349+
// We currently can't call scripts from the repo because
350+
// at this point in the workflow, we're on the compiled
351+
// artifact branch (so the scripts don't exist).
352+
// We can fix this with a composite action in the main repo.
353+
// This script is duplicated below.
354+
const fs = require('fs');
355+
const crypto = require('crypto');
356+
const {execSync} = require('child_process');
357+
358+
// TODO: when we move this to a script, we can use this from npm.
359+
// Copy of signedsource since we can't install deps on this branch
360+
const GENERATED = '@' + 'generated';
361+
const NEWTOKEN = '<<SignedSource::*O*zOeWoEQle#+L!plEphiEmie@IsG>>';
362+
const PATTERN = new RegExp(`${GENERATED} (?:SignedSource<<([a-f0-9]{32})>>)`);
363+
364+
const TokenNotFoundError = new Error(
365+
`SignedSource.signFile(...): Cannot sign file without token: ${NEWTOKEN}`
366+
);
367+
368+
function hash(data, encoding) {
369+
const md5sum = crypto.createHash('md5');
370+
md5sum.update(data, encoding);
371+
return md5sum.digest('hex');
372+
}
373+
374+
const SignedSource = {
375+
getSigningToken() {
376+
return `${GENERATED} ${NEWTOKEN}`;
377+
},
378+
isSigned(data) {
379+
return PATTERN.exec(data) != null;
380+
},
381+
signFile(data) {
382+
if (!data.includes(NEWTOKEN)) {
383+
if (SignedSource.isSigned(data)) {
384+
// Signing a file that was previously signed.
385+
data = data.replace(PATTERN, SignedSource.getSigningToken());
386+
} else {
387+
throw TokenNotFoundError;
388+
}
389+
}
390+
return data.replace(NEWTOKEN, `SignedSource<<${hash(data, 'utf8')}>>`);
391+
},
392+
};
393+
394+
const directory = './compiled-rn';
395+
console.log('Signing files in directory:', directory);
396+
try {
397+
const result = execSync(`git status --porcelain ${directory}`, {encoding: 'utf8'});
398+
399+
// Parse the git status output to get file paths
400+
const files = result.split('\n').filter(file => file.endsWith('.js'));
401+
402+
if (files.length === 0) {
403+
throw new Error(
404+
'git status returned no files to sign. this job should not have run.'
405+
);
406+
} else {
407+
files.forEach(line => {
408+
const file = line.slice(3).trim();
409+
if (file) {
410+
console.log(' Signing file:', file);
411+
const originalContents = fs.readFileSync(file, 'utf8');
412+
const signedContents = SignedSource.signFile(originalContents);
413+
fs.writeFileSync(file, signedContents, 'utf8');
414+
}
415+
});
416+
}
417+
} catch (e) {
418+
process.exitCode = 1;
419+
console.error('Error signing files:', e);
420+
}
421+
- name: Check for changes
422+
id: check_should_commit
423+
run: |
424+
echo "Full git status"
425+
git add .
426+
git status --porcelain
427+
echo "===================="
428+
if git status --porcelain | grep -qv '/REVISION'; then
335429
echo "Changes detected"
430+
echo "===== Changes ====="
431+
git --no-pager diff -U0 --cached | grep '^[+-]' | head -n 50
432+
echo "==================="
336433
echo "should_commit=true" >> "$GITHUB_OUTPUT"
337434
else
338435
echo "No Changes detected"
@@ -348,10 +445,92 @@ jobs:
348445
grep -rl "$LAST_VERSION" ./compiled-rn || echo "No files found with $LAST_VERSION"
349446
grep -rl "$LAST_VERSION" ./compiled-rn | xargs -r sed -i -e "s/$LAST_VERSION/$CURRENT_VERSION/g"
350447
grep -rl "$LAST_VERSION" ./compiled-rn || echo "Version re-applied"
351-
- name: Will commit these changes
448+
- name: Add files
352449
if: steps.check_should_commit.outputs.should_commit == 'true'
353450
run: |
354451
echo ":"
452+
git add .
453+
- name: Signing files
454+
if: steps.check_should_commit.outputs.should_commit == 'true'
455+
uses: actions/github-script@v6
456+
with:
457+
script: |
458+
// TODO: Move this to a script file.
459+
// We currently can't call scripts from the repo because
460+
// at this point in the workflow, we're on the compiled
461+
// artifact branch (so the scripts don't exist).
462+
// We can fix this with a composite action in the main repo.
463+
// This script is duplicated above.
464+
const fs = require('fs');
465+
const crypto = require('crypto');
466+
const {execSync} = require('child_process');
467+
468+
// TODO: when we move this to a script, we can use this from npm.
469+
// Copy of signedsource since we can't install deps on this branch.
470+
const GENERATED = '@' + 'generated';
471+
const NEWTOKEN = '<<SignedSource::*O*zOeWoEQle#+L!plEphiEmie@IsG>>';
472+
const PATTERN = new RegExp(`${GENERATED} (?:SignedSource<<([a-f0-9]{32})>>)`);
473+
474+
const TokenNotFoundError = new Error(
475+
`SignedSource.signFile(...): Cannot sign file without token: ${NEWTOKEN}`
476+
);
477+
478+
function hash(data, encoding) {
479+
const md5sum = crypto.createHash('md5');
480+
md5sum.update(data, encoding);
481+
return md5sum.digest('hex');
482+
}
483+
484+
const SignedSource = {
485+
getSigningToken() {
486+
return `${GENERATED} ${NEWTOKEN}`;
487+
},
488+
isSigned(data) {
489+
return PATTERN.exec(data) != null;
490+
},
491+
signFile(data) {
492+
if (!data.includes(NEWTOKEN)) {
493+
if (SignedSource.isSigned(data)) {
494+
// Signing a file that was previously signed.
495+
data = data.replace(PATTERN, SignedSource.getSigningToken());
496+
} else {
497+
throw TokenNotFoundError;
498+
}
499+
}
500+
return data.replace(NEWTOKEN, `SignedSource<<${hash(data, 'utf8')}>>`);
501+
},
502+
};
503+
504+
const directory = './compiled-rn';
505+
console.log('Signing files in directory:', directory);
506+
try {
507+
const result = execSync(`git status --porcelain ${directory}`, {encoding: 'utf8'});
508+
509+
// Parse the git status output to get file paths
510+
const files = result.split('\n').filter(file => file.endsWith('.js'));
511+
512+
if (files.length === 0) {
513+
throw new Error(
514+
'git status returned no files to sign. this job should not have run.'
515+
);
516+
} else {
517+
files.forEach(line => {
518+
const file = line.slice(3).trim();
519+
if (file) {
520+
console.log(' Signing file:', file);
521+
const originalContents = fs.readFileSync(file, 'utf8');
522+
const signedContents = SignedSource.signFile(originalContents);
523+
fs.writeFileSync(file, signedContents, 'utf8');
524+
}
525+
});
526+
}
527+
} catch (e) {
528+
process.exitCode = 1;
529+
console.error('Error signing files:', e);
530+
}
531+
- name: Will commit these changes
532+
if: steps.check_should_commit.outputs.should_commit == 'true'
533+
run: |
355534
git status -u
356535
- name: Commit changes to branch
357536
if: steps.check_should_commit.outputs.should_commit == 'true'

packages/react-native-renderer/src/ReactNativeTypes.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @format
7+
* @noformat
8+
* @nolint
89
* @flow strict
910
*/
1011

packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/deepDiffer.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @format
8-
* @flow
97
*/
108

119
'use strict';

scripts/rollup/packaging.js

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,13 @@ const {
77
readFileSync,
88
writeFileSync,
99
} = require('fs');
10-
const path = require('path');
1110
const Bundles = require('./bundles');
1211
const {
1312
asyncCopyTo,
1413
asyncExecuteCommand,
1514
asyncExtractTar,
1615
asyncRimRaf,
1716
} = require('./utils');
18-
const {getSigningToken, signFile} = require('signedsource');
1917

2018
const {
2119
NODE_ES2015,
@@ -127,24 +125,6 @@ async function copyRNShims() {
127125
require.resolve('react-native-renderer/src/ReactNativeTypes.js'),
128126
'build/react-native/shims/ReactNativeTypes.js'
129127
);
130-
processGenerated('build/react-native/shims');
131-
}
132-
133-
function processGenerated(directory) {
134-
const files = readdirSync(directory)
135-
.filter(dir => dir.endsWith('.js'))
136-
.map(file => path.join(directory, file));
137-
138-
files.forEach(file => {
139-
const originalContents = readFileSync(file, 'utf8');
140-
const contents = originalContents
141-
// Replace {@}format with {@}noformat
142-
.replace(/(\r?\n\s*\*\s*)@format\b.*(\n)/, '$1@noformat$2')
143-
// Add {@}nolint and {@}generated
144-
.replace(/(\r?\n\s*\*)\//, `$1 @nolint$1 ${getSigningToken()}$1/`);
145-
const signedContents = signFile(contents);
146-
writeFileSync(file, signedContents, 'utf8');
147-
});
148128
}
149129

150130
async function copyAllShims() {

scripts/rollup/shims/react-native/ReactFabric.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @format
7+
* @noformat
8+
* @nolint
89
* @flow
910
*/
1011

scripts/rollup/shims/react-native/ReactFeatureFlags.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @format
7+
* @noformat
8+
* @nolint
89
* @flow strict-local
910
*/
1011

scripts/rollup/shims/react-native/ReactNative.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @format
7+
* @noformat
8+
* @nolint
89
* @flow
910
*/
10-
1111
'use strict';
1212

1313
import type {ReactNativeType} from './ReactNativeTypes';

scripts/rollup/shims/react-native/ReactNativeViewConfigRegistry.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @format
7+
* @noformat
8+
* @nolint
89
* @flow strict-local
910
*/
1011

scripts/rollup/shims/react-native/createReactNativeComponentClass.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @format
7+
* @noformat
8+
* @nolint
89
* @flow strict-local
910
*/
1011

0 commit comments

Comments
 (0)