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
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
✋ To keep the backlog clean and actionable, issues will be
🚫 closed if they do not follow one of the issue templates:
👉 https://github.com/react-native-community/template/issues/new/choose

8 changes: 4 additions & 4 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: 🐛 Bug Report
description: Report a reproducible bug or regression in React Native Community Template.
labels: ["Needs: Triage :mag:"]
labels: ['Needs: Triage :mag:']
body:
- type: markdown
attributes:
value: "## Reporting a bug to the React Native Community Template"
value: '## Reporting a bug to the React Native Community Template'
- type: markdown
attributes:
value: |
Expand Down Expand Up @@ -42,7 +42,7 @@ body:
attributes:
label: React Native Community Template Version
description: The version of Template that this issue reproduces on. Bear in mind that only issues on the latest version of the Template will be supported.
placeholder: "0.75.0"
placeholder: '0.75.0'
validations:
required: true
- type: dropdown
Expand Down Expand Up @@ -107,7 +107,7 @@ body:
attributes:
label: Reproducer
description: A link to the public repository that reproduces this bug, using [this template](https://github.com/react-native-community/reproducer-react-native). Reproducers are **mandatory**.
placeholder: "https://github.com/<myuser>/<myreproducer>"
placeholder: 'https://github.com/<myuser>/<myreproducer>'
validations:
required: true
- type: textarea
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ on:
workflow_dispatch:
inputs:
version:
description: "The version of the react-native we the template to use in this release. For example 0.75.0-rc.0"
description: 'The version of the react-native we the template to use in this release. For example 0.75.0-rc.0'
required: true
type: string
is_latest_on_npm:
description: "Whether we want to tag this template release as `latest` on NPM"
description: 'Whether we want to tag this template release as `latest` on NPM'
required: true
type: boolean
default: false
dry_run:
description: "Run without making persistent changes to git or npm"
description: 'Run without making persistent changes to git or npm'
type: boolean
default: true

Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,3 @@ jobs:
node-version: 18
- name: Run unit tests
run: npm install && npm test


2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
template/android/
template/ios/
5 changes: 5 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
arrowParens: 'avoid',
singleQuote: true,
trailingComma: 'all',
};
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,23 @@ The template used by `npx @react-native-community/cli init` to bootstrap a React

[![Build Status][build-badge]][build] [![Version][version-badge]][package] [![MIT License][license-badge]][license] [![PRs Welcome][prs-welcome-badge]][prs-welcome]


# Create Latest CLI Project

Using this command create latest react-native project with this template

```
npx @react-native-community/cli@latest init TestApp
```

# Create Specific Version React-Native CLI Project

Add version flag and specify that existing version of react-native to create project.
Note that this command will create a new project from the template using the specific version passed to the flag

npx @react-native-community/cli init TestApp --version <VERSION>

Replace `<VERSION>` with the version number you need. For example: 0.75.2.


## Contents

- [About](#about)
Expand Down
6 changes: 2 additions & 4 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
/** @type {import('jest').Config} */
const config = {
coverageProvider: "v8",
testMatch: [
"**/__tests__/*.js",
],
coverageProvider: 'v8',
testMatch: ['**/__tests__/*.js'],
};

module.exports = config;
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"access": "public"
},
"scripts": {
"format": "prettier --write .",
"test": "jest"
},
"type": "commonjs",
Expand All @@ -17,6 +18,7 @@
"dependencies": {},
"devDependencies": {
"jest": "^29.7.0",
"prettier": "^3.6.2",
"semver": "^7.6.3"
},
"homepage": "https://github.com/react-native-community/template/tree/main",
Expand Down
70 changes: 41 additions & 29 deletions scripts/__tests__/bumpTemplateVersion-test.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,37 @@
const {execSync, exec: _exec} = require('child_process');
const { execSync, exec: _exec } = require('child_process');
const fs = require('fs');
const {promisify} = require('util');
const { promisify } = require('util');
const path = require('path');
const semver = require('semver');

function run(version) {
return execSync(`./bumpedTemplateVersion.sh ${version}`, { cwd: 'scripts', stdio: ['ignore', 'pipe', 'ignore'] }).toString().trim();
return execSync(`./bumpedTemplateVersion.sh ${version}`, {
cwd: 'scripts',
stdio: ['ignore', 'pipe', 'ignore'],
})
.toString()
.trim();
}

const FIFO_PATH = '/tmp/_npm_fifo'
const FIFO_PATH = '/tmp/_npm_fifo';

const exec = promisify(_exec);
const writeFile = promisify(fs.writeFile);

async function runStubbedNpm(version, response) {
cleanUpStubbedNpm();
execSync(`mkfifo ${FIFO_PATH}`);
return Promise.all(
[
writeFile(FIFO_PATH, JSON.stringify(response)),
exec(`./bumpedTemplateVersion.sh ${version}`, {
cwd: 'scripts',
stdio: ['ignore', 'pipe', 'ignore'],
env: {
PATH: `${__dirname}/stub:${process.env.PATH}`,
NPM_STUB_FIFO: FIFO_PATH,
}
}).then(raw => raw.stdout.toString().trim()),
]
).then(([, resp]) => resp);
return Promise.all([
writeFile(FIFO_PATH, JSON.stringify(response)),
exec(`./bumpedTemplateVersion.sh ${version}`, {
cwd: 'scripts',
stdio: ['ignore', 'pipe', 'ignore'],
env: {
PATH: `${__dirname}/stub:${process.env.PATH}`,
NPM_STUB_FIFO: FIFO_PATH,
},
}).then(raw => raw.stdout.toString().trim()),
]).then(([, resp]) => resp);
}

function cleanUpStubbedNpm() {
Expand All @@ -40,9 +43,10 @@ function cleanUpStubbedNpm() {
}

describe('bumpTemplateVersion.sh', () => {

it('nightlies stay the same', () => {
expect(run('0.75.0-nightly-20240606-4324f0874')).toEqual('0.75.0-nightly-20240606-4324f0874');
expect(run('0.75.0-nightly-20240606-4324f0874')).toEqual(
'0.75.0-nightly-20240606-4324f0874',
);
});

it('release candidates appended with a sha', () => {
Expand All @@ -56,24 +60,32 @@ describe('bumpTemplateVersion.sh', () => {

it('bumps the patch if a version of the template already exists', async () => {
// This sucks I know:
const {version} = await fetch('https://registry.npmjs.com/@react-native-community/template/latest').then(resp => resp.json());
const {major, minor, patch} = semver.parse(version);
expect(run(`${major}.${minor}.${patch}`)).toEqual(`${major}.${minor}.${patch+1}`);
const { version } = await fetch(
'https://registry.npmjs.com/@react-native-community/template/latest',
).then(resp => resp.json());
const { major, minor, patch } = semver.parse(version);
expect(run(`${major}.${minor}.${patch}`)).toEqual(
`${major}.${minor}.${patch + 1}`,
);
});

describe('handles different npm responses', () => {
afterAll(cleanUpStubbedNpm);
it('arrays of versions', async () => {
expect(await runStubbedNpm('0.76.0', [
{ version: '0.76.0' },
{ version: '0.76.2' },
// Expecting +1 on this:
{ version: '0.76.3' },
])).toEqual('0.76.4');
expect(
await runStubbedNpm('0.76.0', [
{ version: '0.76.0' },
{ version: '0.76.2' },
// Expecting +1 on this:
{ version: '0.76.3' },
]),
).toEqual('0.76.4');
});

it('single version', async () => {
expect(await runStubbedNpm('0.76.0', { version: '0.76.0' })).toEqual('0.76.1');
expect(await runStubbedNpm('0.76.0', { version: '0.76.0' })).toEqual(
'0.76.1',
);
});
});
});
15 changes: 9 additions & 6 deletions scripts/__tests__/package_json-test.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
const fs = require('fs');
const {execSync} = require('child_process');
const { execSync } = require('child_process');

const branch = execSync('git rev-parse --abbrev-ref HEAD').toString().trim();

const isStableBranch = /\d+\.\d+-stable$/.test(branch);

const isReactNativePackage = pkg => pkg === "react-native" || pkg.startsWith("@react-native/");
const isReactNativePackage = pkg =>
pkg === 'react-native' || pkg.startsWith('@react-native/');

const label = isStableBranch ? 'react-native and ' : '';

describe("react-native packages on a version branch need to be aligned", () => {
describe('react-native packages on a version branch need to be aligned', () => {
it(`has a consistent version for ${label}@react-native/ scoped packages in the template/package.json`, () => {
const pkgJson = JSON.parse(fs.readFileSync('template/package.json'));

const everything = Object.entries({
...pkgJson.dependencies,
...pkgJson.devDependencies,
...pkgJson.peerDependencies ?? {}
...(pkgJson.peerDependencies ?? {}),
});

const versions = Object.fromEntries(everything.filter(([name]) => isReactNativePackage(name)));
const versions = Object.fromEntries(
everything.filter(([name]) => isReactNativePackage(name)),
);

if (!isStableBranch) {
// This is the one case where "react-native" doesn't have to match
delete versions["react-native"];
delete versions['react-native'];
}

const allReactNativeVersions = new Set(Object.values(versions));
Expand Down
4 changes: 2 additions & 2 deletions scripts/updateReactNativeVersion.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const REACT_NATIVE_SCOPE = '@react-native/';
*/
function normalizeReactNativeDeps(deps, version) {
const updated = {};
for (const key of Object.keys(deps ?? {}).filter((pkg) =>
for (const key of Object.keys(deps ?? {}).filter(pkg =>
pkg.startsWith(REACT_NATIVE_SCOPE),
)) {
updated[key] = version;
Expand Down Expand Up @@ -102,7 +102,7 @@ the template.
`);
process.exit(1);
}
main(process.argv.pop()).catch((e) => {
main(process.argv.pop()).catch(e => {
throw e;
});
}
2 changes: 1 addition & 1 deletion template/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": "@react-native/typescript-config",
"compilerOptions": {
"types": ["jest"],
"types": ["jest"]
},
"include": ["**/*.ts", "**/*.tsx"],
"exclude": ["**/node_modules", "**/Pods"]
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1816,6 +1816,11 @@ pkg-dir@^4.2.0:
dependencies:
find-up "^4.0.0"

prettier@^3.6.2:
version "3.6.2"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.6.2.tgz#ccda02a1003ebbb2bfda6f83a074978f608b9393"
integrity sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==

pretty-format@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812"
Expand Down