Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
20 changes: 7 additions & 13 deletions scripts/beachball/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AllPackageInfo, getAllPackageInfo, isConvergedPackage } from '@fluentui/scripts-monorepo';
import { getAllPackageInfo, isConvergedPackage } from '@fluentui/scripts-monorepo';

/**
* Reads package info from the monorepo and generates the scopes for beachball bump and release.
Expand All @@ -17,8 +17,7 @@ export function getConfig({ version }: { version: 'vNext' }): {
};
};
export function getConfig({ version }: { version: 'v8' | 'vNext' }) {
const allPackageInfo = getAllPackageInfo();
const vNextPackagePaths = getVNextPackagePaths(allPackageInfo);
const vNextPackagePaths = getVNextPackagePaths();

if (version === 'vNext') {
return {
Expand All @@ -32,22 +31,17 @@ export function getConfig({ version }: { version: 'v8' | 'vNext' }) {
}

if (version === 'v8') {
const ignoreVNextScope = vNextPackagePaths.map(path => `!${path}`);
const ignoreVNextScope = vNextPackagePaths.map(pkgPath => `!${pkgPath}`);

return { scope: [...ignoreVNextScope] };
}

throw new Error('Unsupported version scopes acquisition');
}

function getVNextPackagePaths(allPackageInfo: AllPackageInfo) {
return Object.values(allPackageInfo)
.map(packageInfo => {
if (isConvergedPackage({ packagePathOrJson: packageInfo.packageJson })) {
return packageInfo.packagePath;
}
function getVNextPackagePaths() {
const allProjects = getAllPackageInfo(isConvergedPackage);
const values = Object.values(allProjects);

return false;
})
.filter(Boolean) as string[];
return values.map(project => project.packagePath);
}
4 changes: 2 additions & 2 deletions scripts/executors/runPublished.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ function getLageArgs(options) {
// (which must be built and uploaded with each release). This is similar to "--scope \"!packages/fluentui/*\""
// in the root package.json's publishing-related scripts and will need to be updated if --scope changes.
const beachballPackageScopes = Object.values(workspacePackagesMetadata)
.filter(({ packageJson, packagePath }) => {
.filter(({ packageJson, projectConfig, packagePath }) => {
const isNorthstar = /[\\/]fluentui[\\/]/.test(packagePath);
const isWebComponents = packageJson.name === '@fluentui/web-components';

if (isNorthstar || isWebComponents) {
return false;
}

const isConverged = isConvergedPackage({ packagePathOrJson: packageJson });
const isConverged = isConvergedPackage({ packageJson, project: projectConfig });
if (releaseScope === 'v9' && isConverged) {
return packageJson.private !== true;
}
Expand Down
8 changes: 8 additions & 0 deletions scripts/executors/runPublished.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,26 @@ describe(`#runPublished`, () => {
'@fluentui/web-components': {
packagePath: 'packages/web-components',
packageJson: { name: '@fluentui/web-components', version: '1.0.0', main: 'lib/index.js', private: false },
projectConfig: { name: '@fluentui/web-components', root: 'packages/web-components', tags: [] },
},
'@fluentui/react': {
packagePath: 'packages/react',
packageJson: { name: '@fluentui/react', version: '8.0.0', main: 'lib/index.js', private: false },
projectConfig: { name: '@fluentui/react', root: 'packages/react', tags: [] },
},
'@fluentui/react-northstar': {
packagePath: 'packages/fluentui/react-northstar',
packageJson: { name: '@fluentui/react-northstar', version: '0.1.0', main: 'lib/index.js', private: false },
projectConfig: { name: '@fluentui/react-northstar', root: 'packages/fluentui/react-northstar', tags: [] },
},
'@fluentui/react-components': {
packagePath: 'packages/react-components/react-components',
packageJson: { name: '@fluentui/react-components', version: '9.0.0', main: 'lib/index.js', private: false },
projectConfig: {
name: '@fluentui/react-components',
root: 'packages/react-components/react-components',
tags: [],
},
},
};

Expand Down
10 changes: 6 additions & 4 deletions scripts/executors/tag-react-components.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { execSync } from 'child_process';
import * as semver from 'semver';
import yargs from 'yargs';

import { AllPackageInfo, getAllPackageInfo, isConvergedPackage } from '@fluentui/scripts-monorepo';
import * as semver from 'semver';
import yargs from 'yargs';

function tagPackages(npmToken: string) {
const packagesToTag = getPackagesToTag();
Expand Down Expand Up @@ -42,10 +42,10 @@ function tagPackage(name: string, version: string, npmToken: string): boolean {
}

function getPackagesToTag() {
const packageInfos: AllPackageInfo = getAllPackageInfo();
const packageInfos: AllPackageInfo = getAllPackageInfo(isConvergedPackage);
return Object.values(packageInfos)
.map(packageInfo => {
if (!packageInfo.packageJson.private && isConvergedPackage({ packagePathOrJson: packageInfo.packageJson })) {
if (!packageInfo.packageJson.private) {
return {
name: packageInfo.packageJson.name,
version: packageInfo.packageJson.version,
Expand All @@ -67,4 +67,6 @@ function main(argv: yargs.Arguments) {

if (require.main === module && process.env.RELEASE_VNEXT) {
main(yargs.argv);
} else {
console.log('"RELEASE_VNEXT" not set - skipping');
}
16 changes: 13 additions & 3 deletions scripts/monorepo/src/getAllPackageInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ let cwdForPackageInfo;

/**
* @returns {typeof packageInfo}
* @param {(metadata:{project:import('@nx/devkit').ProjectConfiguration;packageJson:import('nx/src/utils/package-json').PackageJson})=>boolean} [predicate]
*/
function getAllPackageInfo() {
if (packageInfo && cwdForPackageInfo === process.cwd()) {
function getAllPackageInfo(predicate) {
if (!predicate && packageInfo && cwdForPackageInfo === process.cwd()) {
return packageInfo;
}

Expand All @@ -28,9 +29,18 @@ function getAllPackageInfo() {
cwdForPackageInfo = process.cwd();

for (const [projectName, projectConfig] of projects) {
const packageJson = JSON.parse(
fs.readFileSync(path.join(workspaceRoot, projectConfig.root, 'package.json'), 'utf-8'),
);

if (predicate && !predicate({ project: projectConfig, packageJson })) {
continue;
}

packageInfo[projectName] = {
packagePath: projectConfig.root,
packageJson: JSON.parse(fs.readFileSync(path.join(workspaceRoot, projectConfig.root, 'package.json'), 'utf-8')),
packageJson,
projectConfig,
};
}

Expand Down
17 changes: 17 additions & 0 deletions scripts/monorepo/src/getAllPackageInfo.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as path from 'path';

import getAllPackageInfo from './getAllPackageInfo';

describe(`#getAllPackageinfo`, () => {
Expand All @@ -9,13 +10,29 @@ describe(`#getAllPackageinfo`, () => {

expect(allPackages['@fluentui/noop']).toBe(undefined);
expect(packageName).toEqual(expect.stringMatching(/^@fluentui\/[a-z-]+/));

expect(packageMetadata).toEqual({
packagePath: expect.any(String),
packageJson: expect.objectContaining({
name: expect.any(String),
version: expect.any(String),
}),
projectConfig: expect.objectContaining({
$schema: expect.any(String),
implicitDependencies: expect.any(Array),
name: expect.any(String),
projectType: expect.any(String),
root: expect.any(String),
}),
});
expect(path.isAbsolute(packageMetadata.packagePath)).toBe(false);
});

it(`should accept predicate filter function`, () => {
const allPackages = getAllPackageInfo(metadata => {
return metadata.packageJson.name === '@fluentui/non-existent-package';
});

expect(allPackages).toEqual({});
});
});
2 changes: 1 addition & 1 deletion scripts/monorepo/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export { getDependencies } from './getDependencies';
export { default as findGitRoot } from './findGitRoot';
export { default as findRepoDeps } from './findRepoDeps';
export { default as getAllPackageInfo } from './getAllPackageInfo';
export { isConvergedPackage, shipsAMD } from './isConvergedPackage';
export { isConvergedPackage } from './isConvergedPackage';
export { getAffectedPackages } from './getAffectedPackages';
export { getDefaultEnvironmentVars } from './getDefaultEnvironmentVars';
export { getProjectMetadata, workspaceRoot, getUncommittedFiles, getUntrackedFiles } from './utils';
Expand Down
78 changes: 4 additions & 74 deletions scripts/monorepo/src/isConvergedPackage.js
Original file line number Diff line number Diff line change
@@ -1,85 +1,16 @@
const { readConfig } = require('@fluentui/scripts-utils');
const semver = require('semver');

const { getProjectMetadata } = require('./utils');

/**
* @typedef {string | import('./index').PackageJson} PathOrPackageJson
*/

/**
* Determines whether a package is converged, based on its version.
*
* @param {Object} [options]
* @param {PathOrPackageJson} [options.packagePathOrJson] - optional different package path to run in OR previously-read package.json
* (defaults to reading package.json from `process.cwd()`)
* @param {'library' | 'application' | 'all'} [options.projectType] - filter for what project types you wanna apply the condition
*
* @returns {boolean} true if it's a converged package (version >= 9)
* @param {{project:import('@nx/devkit').ProjectConfiguration;packageJson:import('nx/src/utils/package-json').PackageJson}} metadata
*/
function isConvergedPackage(options = {}) {
const { packagePathOrJson, projectType = 'all' } = options;
const packageJson =
!packagePathOrJson || typeof packagePathOrJson === 'string'
? readConfig('package.json', /** @type {string|undefined} */ (packagePathOrJson))
: packagePathOrJson;

if (!packageJson) {
throw new Error(`package.json doesn't exist`);
}

const metadata = getProjectMetadata(packageJson.name);

if (projectType !== 'all' && metadata.projectType !== projectType) {
return false;
}

const hasVNextTag = !!metadata.tags?.includes('vNext');
function isConvergedPackage(metadata) {
const { packageJson, project } = metadata;
const hasVNextTag = Boolean(project.tags?.includes('vNext'));

return semver.major(packageJson.version) >= 9 || isNightlyVersion(packageJson.version) || hasVNextTag;
}

/**
* @param {Object} [options]
* @param {PathOrPackageJson} [options.packagePathOrJson] - optional different package path to run in OR previously-read package.json
* (defaults to reading package.json from `process.cwd()`)
* @returns
*/
function shipsAMD(options = {}) {
const { packagePathOrJson } = options;
const packageJson =
!packagePathOrJson || typeof packagePathOrJson === 'string'
? readConfig('package.json', /** @type {string|undefined} */ (packagePathOrJson))
: packagePathOrJson;

if (!packageJson) {
throw new Error(`package.json doesn't exist`);
}

const metadata = getProjectMetadata(packageJson.name);

if (metadata.projectType !== 'library') {
return false;
}

const tags = new Set(metadata.tags ?? []);
const isV8 = tags.has('v8');
const isV9 = tags.has('vNext');
const needsAMD = tags.has('ships-amd');
const isMixedProject = isV9 && isV8;

if (needsAMD) {
return true;
}
if (isMixedProject) {
return true;
}
if (isV9) {
return false;
}
return true;
}

/**
* Determines if a version is the 0.0.0 nightly version used by converged packages
* @param {string} version
Expand All @@ -89,4 +20,3 @@ function isNightlyVersion(version) {
}

exports.isConvergedPackage = isConvergedPackage;
exports.shipsAMD = shipsAMD;
39 changes: 39 additions & 0 deletions scripts/monorepo/src/isConvergedPackage.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { isConvergedPackage } from './isConvergedPackage';

describe(`#isConverged`, () => {
it(`should return true for vNext package`, () => {
const actual = isConvergedPackage({
packageJson: {
name: '@proj/one',
version: '9.0.0',
},
project: { root: 'packages/foo/bar/one', projectType: 'library', tags: ['vNext'] },
});

expect(actual).toBe(true);
});

it(`should return true for vNext nightly package`, () => {
const actual = isConvergedPackage({
packageJson: {
name: '@proj/one',
version: '0.0.0-nightly.20210101',
},
project: { root: 'packages/foo/bar/one', projectType: 'library', tags: ['vNext'] },
});

expect(actual).toBe(true);
});

it(`should return false for non vNext Package`, () => {
const actual = isConvergedPackage({
packageJson: {
name: '@proj/one',
version: '8.1.2',
},
project: { root: 'packages/foo/bar/one', projectType: 'library', tags: ['v8'] },
});

expect(actual).toBe(false);
});
});
1 change: 1 addition & 0 deletions scripts/monorepo/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface PackageInfo {
packagePath: string;
/** package.json contents */
packageJson: PackageJson;
projectConfig: import('@nx/devkit').ProjectConfiguration;
}

/**
Expand Down
13 changes: 12 additions & 1 deletion scripts/monorepo/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,20 @@ const TEN_MEGABYTES = 1024 * 10000;
/**
* Gets nx project metadata
* @param {string} projectName - package name
* @param {ReturnType<typeof import('@nx/devkit').getProjects>=} allProjects - all workspace projects
* @returns {import('@nx/devkit').ProjectConfiguration}
*/
function getProjectMetadata(projectName) {
function getProjectMetadata(projectName, allProjects) {
if (allProjects) {
const project = allProjects.get(projectName);

if (!project) {
throw new Error(`Project ${projectName} not found in workspace`);
}

return project;
}

return readProjectConfiguration(tree, projectName);
}

Expand Down
4 changes: 0 additions & 4 deletions scripts/tasks/src/babel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ function addSourceMappingUrl(code: string, loc: string): string {
return code + '\n//# sourceMappingURL=' + path.basename(loc);
}

export function hasBabel() {
return fs.existsSync(path.join(process.cwd(), '.babelrc.json'));
}

export async function babel() {
const files = glob.sync('lib/**/*.styles.js');

Expand Down
Loading