Add beachball change transformer (#9488)
* Add beachball change transformer Beachball has a relatively recent option, which allows modifying changefiles before trying to bump/publish. We can use this to workaround two common painpoints. 1. Changes backported to 0.69 and later will not need any modification to changefiles when cherry-picking. 2. We do some formatting to create consistency of omiting the version in change messages in our changelogs * Remove stale file * Change files * Fix bug around missing packages * Fuller JS env in setup * Simplify logic * Fix template path * use remote midgard-yarn on ubuntu agent * yaml * Build more * Move beachball config to its own package * Consistency * Cleanup yarn install logic for hosted vs managed images * Fixup lockfile issues * Update min to node 14 * Import shared variables and rename * Variable fixup
This commit is contained in:
Родитель
e8f0f0d844
Коммит
dfc6ca9c55
|
@ -2,30 +2,16 @@
|
||||||
jobs:
|
jobs:
|
||||||
- job: MacTests
|
- job: MacTests
|
||||||
displayName: macOS Tests
|
displayName: macOS Tests
|
||||||
|
timeoutInMinutes: 20
|
||||||
variables:
|
variables: [template: ../variables/shared.yml]
|
||||||
- template: ../variables/macos.yml
|
pool: {vmImage: macOS-10.15}
|
||||||
|
|
||||||
pool:
|
|
||||||
vmImage: $(VmImage)
|
|
||||||
|
|
||||||
timeoutInMinutes: 20 # how long to run the job before automatically cancelling
|
|
||||||
cancelTimeoutInMinutes: 5 # how much time to give 'run always even if cancelled tasks' before killing them
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- template: ../templates/checkout-shallow.yml
|
- template: ../templates/checkout-shallow.yml
|
||||||
|
|
||||||
# Explicitly set Node version and install midgard-yarn since we are
|
|
||||||
# running on a public pool
|
|
||||||
- task: NodeTool@0
|
|
||||||
displayName: Set Node Version
|
|
||||||
inputs:
|
|
||||||
versionSpec: '16.x'
|
|
||||||
|
|
||||||
- script: npm install -g midgard-yarn@1.23.33
|
|
||||||
displayName: Install midgard-yarn
|
|
||||||
|
|
||||||
- template: ../templates/prepare-js-env.yml
|
- template: ../templates/prepare-js-env.yml
|
||||||
|
parameters:
|
||||||
|
agentImage: HostedImage
|
||||||
|
|
||||||
- script: yarn test
|
- script: yarn test
|
||||||
displayName: yarn test
|
displayName: yarn test
|
||||||
|
|
|
@ -7,9 +7,11 @@ parameters:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
- job: Setup
|
- job: Setup
|
||||||
timeoutInMinutes: 3
|
displayName: Setup
|
||||||
pool:
|
timeoutInMinutes: 3 # Kill the job early to catch Beachball hangs
|
||||||
vmImage: ubuntu-latest
|
variables: [template: ../variables/shared.yml]
|
||||||
|
pool: {vmImage: ubuntu-latest}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- template: ../templates/checkout-full.yml
|
- template: ../templates/checkout-full.yml
|
||||||
|
|
||||||
|
@ -18,8 +20,12 @@ jobs:
|
||||||
|
|
||||||
- template: ../templates/compute-beachball-branch-name.yml
|
- template: ../templates/compute-beachball-branch-name.yml
|
||||||
|
|
||||||
- script: npm install -g beachball@2.18.0
|
- template: ../templates/yarn-install.yml
|
||||||
displayName: Install beachball
|
parameters:
|
||||||
|
agentImage: HostedImage
|
||||||
|
|
||||||
|
- script: npx lage build --scope @rnw-scripts/beachball-config --no-deps
|
||||||
|
displayName: Minimal build
|
||||||
|
|
||||||
- ${{ if eq(parameters.buildEnvironment, 'PullRequest') }}:
|
- ${{ if eq(parameters.buildEnvironment, 'PullRequest') }}:
|
||||||
- script: npx beachball check --branch origin/$(BeachBallBranchName) --verbose --changehint "##vso[task.logissue type=error]Run `yarn change` from root of repo to generate a change file."
|
- script: npx beachball check --branch origin/$(BeachBallBranchName) --verbose --changehint "##vso[task.logissue type=error]Run `yarn change` from root of repo to generate a change file."
|
||||||
|
|
|
@ -1,7 +1,21 @@
|
||||||
# Steps to setup an environment that can run JavaScript executables
|
parameters:
|
||||||
|
- name: agentImage
|
||||||
|
type: string
|
||||||
|
default: ManagedImage
|
||||||
|
values:
|
||||||
|
- ManagedImage
|
||||||
|
- HostedImage
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- ${{ if eq(parameters.agentImage, 'HostedImage') }}:
|
||||||
|
- task: NodeTool@0
|
||||||
|
displayName: Set Node Version
|
||||||
|
inputs:
|
||||||
|
versionSpec: '16.x'
|
||||||
|
|
||||||
- template: yarn-install.yml
|
- template: yarn-install.yml
|
||||||
|
parameters:
|
||||||
|
agentImage: ${{ parameters.agentImage }}
|
||||||
|
|
||||||
- script: yarn build
|
- script: yarn build
|
||||||
displayName: yarn build
|
displayName: yarn build
|
||||||
|
|
|
@ -2,15 +2,22 @@ parameters:
|
||||||
- name: workingDirectory
|
- name: workingDirectory
|
||||||
type: string
|
type: string
|
||||||
default: .
|
default: .
|
||||||
- name: frozenLockfile
|
- name: agentImage
|
||||||
type: boolean
|
type: string
|
||||||
default: true
|
default: ManagedImage
|
||||||
|
values:
|
||||||
|
- ManagedImage
|
||||||
|
- HostedImage
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- ${{ if eq(parameters.frozenLockfile, true) }}:
|
# When using our own images, prefer the machine-installed version of
|
||||||
|
# `midgard-yarn`.
|
||||||
|
- ${{ if eq(parameters.agentImage, 'ManagedImage') }}:
|
||||||
- script: midgard-yarn --frozen-lockfile --cwd ${{ parameters.workingDirectory }}
|
- script: midgard-yarn --frozen-lockfile --cwd ${{ parameters.workingDirectory }}
|
||||||
displayName: midgard-yarn (faster yarn install)
|
displayName: midgard-yarn (faster yarn install)
|
||||||
|
|
||||||
- ${{ if eq(parameters.frozenLockfile, false) }}:
|
# If using an image we don't control, acquire a fixed version of midgard-yarn
|
||||||
- script: midgard-yarn --cwd ${{ parameters.workingDirectory }}
|
# before install
|
||||||
|
- ${{ else }}:
|
||||||
|
- script: npx --yes midgard-yarn@1.23.34 --frozen-lockfile --cwd ${{ parameters.workingDirectory }}
|
||||||
displayName: midgard-yarn (faster yarn install)
|
displayName: midgard-yarn (faster yarn install)
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
variables:
|
|
||||||
- template: shared.yml
|
|
||||||
|
|
||||||
- name: VmImage
|
|
||||||
value: macOS-10.15
|
|
|
@ -174,5 +174,6 @@ nul
|
||||||
.verdaccio-db.json
|
.verdaccio-db.json
|
||||||
|
|
||||||
# Graveyard of old packages (whose build-outputs may exist on disk after pull)
|
# Graveyard of old packages (whose build-outputs may exist on disk after pull)
|
||||||
|
/packages/@rnw-bots/*
|
||||||
/packages/jest-environment-winappdriver/*
|
/packages/jest-environment-winappdriver/*
|
||||||
/packages/node-rnw-rpc/*
|
/packages/node-rnw-rpc/*
|
||||||
|
|
|
@ -4,5 +4,7 @@
|
||||||
"esbenp.prettier-vscode",
|
"esbenp.prettier-vscode",
|
||||||
"dbaeumer.vscode-eslint",
|
"dbaeumer.vscode-eslint",
|
||||||
"orta.vscode-jest",
|
"orta.vscode-jest",
|
||||||
|
"ms-azure-devops.azure-pipelines",
|
||||||
|
"streetsidesoftware.code-spell-checker",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,13 @@
|
||||||
"files.exclude": {
|
"files.exclude": {
|
||||||
"**/.git": true
|
"**/.git": true
|
||||||
},
|
},
|
||||||
|
"files.associations": {
|
||||||
|
"**/.ado/**/*.yml": "azure-pipelines"
|
||||||
|
},
|
||||||
"search.exclude": {
|
"search.exclude": {
|
||||||
"**/node_modules": true,
|
"**/node_modules": true,
|
||||||
"**/lib": true,
|
"**/lib/**/*.js": true,
|
||||||
"**/dist": true
|
"**/dist/**/*.js": true
|
||||||
},
|
},
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"eslint.format.enable": true,
|
"eslint.format.enable": true,
|
||||||
|
|
|
@ -1,26 +1 @@
|
||||||
/**
|
module.exports = require("@rnw-scripts/beachball-config");
|
||||||
* Copyright (c) Microsoft Corporation.
|
|
||||||
* Licensed under the MIT License.
|
|
||||||
* @format
|
|
||||||
* @ts-check
|
|
||||||
*/
|
|
||||||
|
|
||||||
const {execSync} = require('child_process');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
...require(`${__dirname}/packages/@rnw-scripts/generated-beachball-config/beachball.config.g.json`),
|
|
||||||
|
|
||||||
// Do not generate tags for monorepo packages by default, to avoid a GitHub
|
|
||||||
// release for every package.
|
|
||||||
gitTags: false,
|
|
||||||
|
|
||||||
hooks: {
|
|
||||||
// Stamp versions when we publish a new package
|
|
||||||
postbump: (_packagePath, name, version) => {
|
|
||||||
if (name === 'react-native-windows') {
|
|
||||||
console.log(`Stamping RNW Version ${version}`);
|
|
||||||
execSync(`yarn stamp-version ${version}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"type": "prerelease",
|
||||||
|
"comment": "Sync variants",
|
||||||
|
"packageName": "@react-native-windows/find-repo-root",
|
||||||
|
"email": "ngerlem@microsoft.com",
|
||||||
|
"dependentChangeType": "patch"
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"type": "prerelease",
|
||||||
|
"comment": "Sync variants",
|
||||||
|
"packageName": "@react-native-windows/package-utils",
|
||||||
|
"email": "ngerlem@microsoft.com",
|
||||||
|
"dependentChangeType": "patch"
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
"type": "prerelease",
|
|
||||||
"comment": "Use PackageReference for C++ dependencies",
|
|
||||||
"packageName": "node-rnw-rpc",
|
|
||||||
"email": "julio.rocha@microsoft.com",
|
|
||||||
"dependentChangeType": "patch"
|
|
||||||
}
|
|
|
@ -16,6 +16,7 @@
|
||||||
"directory": "packages/@react-native-windows/find-repo-root"
|
"directory": "packages/@react-native-windows/find-repo-root"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@react-native-windows/fs": "^1.0.1",
|
||||||
"find-up": "^4.1.0"
|
"find-up": "^4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -7,12 +7,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import findUp from 'find-up';
|
import findUp from 'find-up';
|
||||||
|
import fs from '@react-native-windows/fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the root directory of a repo upward from cwd
|
* Find the root directory of a repo upward from cwd
|
||||||
*/
|
*/
|
||||||
export default async (): Promise<string> => {
|
async function findRepoRoot(): Promise<string> {
|
||||||
const root = await findUp(
|
const root = await findUp(
|
||||||
async (dir: string): Promise<findUp.Match> => {
|
async (dir: string): Promise<findUp.Match> => {
|
||||||
return (await findUp.exists(path.join(dir, '.git'))) ? dir : undefined;
|
return (await findUp.exists(path.join(dir, '.git'))) ? dir : undefined;
|
||||||
|
@ -27,4 +28,27 @@ export default async (): Promise<string> => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronously finds the root directory of a repo upward from cwd
|
||||||
|
*/
|
||||||
|
function findRepoRootSync(): string {
|
||||||
|
const root = findUp.sync(
|
||||||
|
(dir: string): findUp.Match => {
|
||||||
|
return fs.existsSync(path.join(dir, '.git')) ? dir : undefined;
|
||||||
|
},
|
||||||
|
{type: 'directory'},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!root) {
|
||||||
|
throw new Error(
|
||||||
|
'Unable to find the root of react-native-windows. Are you running within the repo?',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
const exportObj = Object.assign(findRepoRoot, {sync: findRepoRootSync});
|
||||||
|
export default exportObj;
|
||||||
|
|
|
@ -120,6 +120,23 @@ export async function enumerateRepoPackages(
|
||||||
return filteredPackages;
|
return filteredPackages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronously Finds monorepo-local packages matching a given predicate. The
|
||||||
|
* root package is not included.
|
||||||
|
*
|
||||||
|
* @param pred predicate describing whether to match a package
|
||||||
|
*/
|
||||||
|
export function enumerateRepoPackagesSync(
|
||||||
|
pred: (pkg: NpmPackage) => boolean = () => true,
|
||||||
|
): WritableNpmPackage[] {
|
||||||
|
const repoRoot = findRepoRoot.sync();
|
||||||
|
const allPackges = getMonorepoPackages(repoRoot).map(
|
||||||
|
(pkg) => new WritableNpmPackage(pkg.location, pkg.package),
|
||||||
|
);
|
||||||
|
|
||||||
|
return allPackges.filter(pred);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a package with a given name (local or dependency)
|
* Finds a package with a given name (local or dependency)
|
||||||
*/
|
*/
|
||||||
|
@ -164,3 +181,16 @@ export async function findRepoPackage(
|
||||||
return packages[0];
|
return packages[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronously a monorepo-local package with a given name
|
||||||
|
*/
|
||||||
|
export function findRepoPackageSync(name: string): WritableNpmPackage | null {
|
||||||
|
const packages = enumerateRepoPackagesSync((p) => p.json.name === name);
|
||||||
|
|
||||||
|
if (packages.length === 0) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return packages[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
import { Context } from "@azure/functions";
|
|
||||||
declare const _default: (context: Context) => Promise<void>;
|
|
||||||
export default _default;
|
|
|
@ -1,6 +0,0 @@
|
||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.default = async (context) => {
|
|
||||||
context.log('Hello world');
|
|
||||||
};
|
|
||||||
//# sourceMappingURL=index.js.map
|
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../HeartbeatFunction/index.ts"],"names":[],"mappings":";;AAEA,kBAAe,KAAK,EAAE,OAAgB,EAAE,EAAE;IACtC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAC/B,CAAC,CAAC","sourcesContent":["import { Context } from \"@azure/functions\"\n\nexport default async (context: Context) => {\n context.log('Hello world');\n};\n"]}
|
|
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@rnw-bots/coordinator",
|
|
||||||
"version": "1.0.12",
|
|
||||||
"license": "MIT",
|
|
||||||
"description": "Azure functions application for coordinating react-native-windows bots",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/microsoft/react-native-windows.git",
|
|
||||||
"directory": "packages/@rnw-bots/coordinator"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"build": "rnw-scripts build",
|
|
||||||
"clean": "rnw-scripts clean",
|
|
||||||
"lint": "rnw-scripts lint",
|
|
||||||
"lint:fix": "rnw-scripts lint:fix",
|
|
||||||
"start": "func start --typescript",
|
|
||||||
"test": "rnw-scripts test",
|
|
||||||
"watch": "rnw-scripts watch"
|
|
||||||
},
|
|
||||||
"dependencies": {},
|
|
||||||
"devDependencies": {
|
|
||||||
"@azure/functions": "^1.0.2-beta2",
|
|
||||||
"@rnw-scripts/eslint-config": "1.1.9",
|
|
||||||
"@rnw-scripts/jest-unittest-config": "1.2.4",
|
|
||||||
"@rnw-scripts/just-task": "2.2.1",
|
|
||||||
"@rnw-scripts/ts-config": "2.0.1",
|
|
||||||
"@types/node": "^14.14.22",
|
|
||||||
"babel-jest": "^26.3.0",
|
|
||||||
"eslint": "^7.32.0",
|
|
||||||
"jest": "^26.6.3",
|
|
||||||
"just-scripts": "^1.3.3",
|
|
||||||
"prettier": "^2.4.1",
|
|
||||||
"typescript": "^4.4.4"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
lib/
|
||||||
|
lib-commonjs/
|
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"name": "@rnw-scripts/beachball-config",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"scripts": {
|
||||||
|
"build": "rnw-scripts build",
|
||||||
|
"clean": "rnw-scripts clean",
|
||||||
|
"lint": "rnw-scripts lint",
|
||||||
|
"lint:fix": "rnw-scripts lint:fix",
|
||||||
|
"watch": "rnw-scripts watch"
|
||||||
|
},
|
||||||
|
"main": "lib-commonjs/beachball.config.js",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/microsoft/react-native-windows.git",
|
||||||
|
"directory": "packages/@rnw-scripts/beachball-config"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@react-native-windows/package-utils": "0.0.0-canary.25",
|
||||||
|
"@rnw-scripts/stamp-version": "0.0.0",
|
||||||
|
"find-up": "^4.1.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@rnw-scripts/eslint-config": "1.1.11",
|
||||||
|
"@rnw-scripts/just-task": "2.2.3",
|
||||||
|
"@rnw-scripts/ts-config": "2.0.2",
|
||||||
|
"@types/node": "^14.14.22",
|
||||||
|
"beachball": "^2.20.0",
|
||||||
|
"eslint": "^7.32.0",
|
||||||
|
"just-scripts": "^1.3.3",
|
||||||
|
"prettier": "^2.4.1",
|
||||||
|
"typescript": "^4.4.4"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"lib-commonjs"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14.0.0"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
* Licensed under the MIT License.
|
||||||
|
*
|
||||||
|
* @format
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {execSync} from 'child_process';
|
||||||
|
import {findRepoPackageSync} from '@react-native-windows/package-utils';
|
||||||
|
|
||||||
|
import type {BeachballOptions} from 'beachball/lib/types/BeachballOptions';
|
||||||
|
import type {ChangeInfo} from 'beachball/lib/types/ChangeInfo';
|
||||||
|
|
||||||
|
const Options: BeachballOptions = {
|
||||||
|
...require("@rnw-scripts/generated-beachball-config"),
|
||||||
|
|
||||||
|
// Do not generate tags for monorepo packages by default, to avoid a GitHub
|
||||||
|
// release for every package.
|
||||||
|
gitTags: false,
|
||||||
|
|
||||||
|
hooks: {
|
||||||
|
// Stamp versions when we publish a new package
|
||||||
|
postbump: (_packagePath, name, version) => {
|
||||||
|
if (name === 'react-native-windows') {
|
||||||
|
console.log(`Stamping RNW Version ${version}`);
|
||||||
|
execSync(`yarn stamp-version ${version}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
transform: {
|
||||||
|
changeFiles: (changeInfo) => Array.isArray(changeInfo.changes)
|
||||||
|
? {...changeInfo, changes: changeInfo.changes.map(transformChangeInfo)}
|
||||||
|
: transformChangeInfo(changeInfo as ChangeInfo),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformChangeInfo(changeInfo: ChangeInfo) : ChangeInfo {
|
||||||
|
return {
|
||||||
|
...changeInfo,
|
||||||
|
type: correctChangeType(changeInfo),
|
||||||
|
comment: formatComment(changeInfo.comment),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function correctChangeType(changeInfo: ChangeInfo) {
|
||||||
|
// Changes made to our main branch are often rolled into prerelease packages,
|
||||||
|
// where a released branch should treat these changes as creating a new patch
|
||||||
|
// release.
|
||||||
|
if (changeInfo.type === 'prerelease' && !isPrerelease(changeInfo.packageName)) {
|
||||||
|
return 'patch';
|
||||||
|
}
|
||||||
|
|
||||||
|
return changeInfo.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPrerelease(packageName: string): boolean {
|
||||||
|
const packageJson = findRepoPackageSync(packageName)?.json;
|
||||||
|
return packageJson && packageJson.version.includes('-');
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatComment(comment: string): string {
|
||||||
|
// Remove versions from messages that look like "[0.xx] Message"
|
||||||
|
return comment.match(/(\s*\[[\d\.]+\]\s*)?((.|\n)*)/)?.[2] ?? comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Options;
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"extends": "@rnw-scripts/ts-config",
|
||||||
|
"include": ["src"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче