fix(js): allow publishable library to run release command (#29775)
<!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> - there is no option `fallbackCurrentVersionResolver: 'disk',` - can't run release for newly created publishable libraries ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> - move code to add release for publishable libraries into its own file to be reused by other stacks - add `fallbackCurrentVersionResolver: 'disk',` to project's release.version. generatorOptions ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes https://github.com/nrwl/nx/issues/29723
This commit is contained in:
parent
48421fdb9e
commit
540aeff488
124
e2e/release/src/release publishable-libraries.test.ts
Normal file
124
e2e/release/src/release publishable-libraries.test.ts
Normal file
@ -0,0 +1,124 @@
|
||||
import {
|
||||
cleanupProject,
|
||||
newProject,
|
||||
runCLI,
|
||||
runCommandAsync,
|
||||
uniq,
|
||||
} from '@nx/e2e/utils';
|
||||
import { execSync } from 'node:child_process';
|
||||
|
||||
expect.addSnapshotSerializer({
|
||||
serialize(str: string) {
|
||||
return (
|
||||
str
|
||||
// Remove all output unique to specific projects to ensure deterministic snapshots
|
||||
.replaceAll(/my-pkg-\d+/g, '{project-name}')
|
||||
.replaceAll(
|
||||
/integrity:\s*.*/g,
|
||||
'integrity: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
|
||||
)
|
||||
.replaceAll(/\b[0-9a-f]{40}\b/g, '{SHASUM}')
|
||||
.replaceAll(/\d*B index\.js/g, 'XXB index.js')
|
||||
.replaceAll(/\d*B project\.json/g, 'XXB project.json')
|
||||
.replaceAll(/\d*B package\.json/g, 'XXXB package.json')
|
||||
.replaceAll(/size:\s*\d*\s?B/g, 'size: XXXB')
|
||||
.replaceAll(/\d*\.\d*\s?kB/g, 'XXX.XXX kb')
|
||||
.replaceAll(/[a-fA-F0-9]{7}/g, '{COMMIT_SHA}')
|
||||
.replaceAll(/Test @[\w\d]+/g, 'Test @{COMMIT_AUTHOR}')
|
||||
.replaceAll(/(\w+) lock file/g, 'PM lock file')
|
||||
// Normalize the version title date.
|
||||
.replaceAll(/\(\d{4}-\d{2}-\d{2}\)/g, '(YYYY-MM-DD)')
|
||||
// We trim each line to reduce the chances of snapshot flakiness
|
||||
.split('\n')
|
||||
.map((r) => r.trim())
|
||||
.filter(Boolean)
|
||||
.join('\n')
|
||||
);
|
||||
},
|
||||
test(val: string) {
|
||||
return val != null && typeof val === 'string';
|
||||
},
|
||||
});
|
||||
|
||||
describe('release publishable libraries', () => {
|
||||
let e2eRegistryUrl: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
newProject({
|
||||
packages: ['@nx/js'],
|
||||
});
|
||||
|
||||
// Normalize git committer information so it is deterministic in snapshots
|
||||
await runCommandAsync(`git config user.email "test@test.com"`);
|
||||
await runCommandAsync(`git config user.name "Test"`);
|
||||
// Create a baseline version tag
|
||||
await runCommandAsync(`git tag v0.0.0`);
|
||||
|
||||
// We need a valid git origin to exist for the commit references to work (and later the test for createRelease)
|
||||
await runCommandAsync(
|
||||
`git remote add origin https://github.com/nrwl/fake-repo.git`
|
||||
);
|
||||
|
||||
// This is the verdaccio instance that the e2e tests themselves are working from
|
||||
e2eRegistryUrl = execSync('npm config get registry').toString().trim();
|
||||
});
|
||||
afterAll(() => cleanupProject());
|
||||
|
||||
it('should be able to release publishable js library', async () => {
|
||||
const jsLib = uniq('my-pkg-');
|
||||
runCLI(
|
||||
`generate @nx/js:lib ${jsLib} --publishable --importPath=@proj/${jsLib}`
|
||||
);
|
||||
|
||||
let releaseOutput = runCLI(`release --first-release`);
|
||||
expect(releaseOutput).toContain('Executing pre-version command');
|
||||
releaseOutput = runCLI(`release --specifier 0.0.2 --yes`);
|
||||
expect(releaseOutput).toMatchInlineSnapshot(`
|
||||
NX Executing pre-version command
|
||||
NX Running release version for project: {project-name}
|
||||
{project-name} 🔍 Reading data for package "@proj/{project-name}" from dist/{project-name}/package.json
|
||||
{project-name} 📄 Resolved the current version as 0.0.0 from git tag "v0.0.0".
|
||||
{project-name} 📄 Using the provided version specifier "0.0.2".
|
||||
{project-name} ✍️ New version 0.0.2 written to dist/{project-name}/package.json
|
||||
"name": "@proj/{project-name}",
|
||||
- "version": "0.0.1",
|
||||
+ "version": "0.0.2",
|
||||
"type": "commonjs",
|
||||
}
|
||||
+
|
||||
NX Staging changed files with git
|
||||
No files to stage. Skipping git add.
|
||||
NX Generating an entry in CHANGELOG.md for v0.0.2
|
||||
+ ## 0.0.2 (YYYY-MM-DD)
|
||||
+
|
||||
+ This was a version bump only, there were no code changes.
|
||||
NX Staging changed files with git
|
||||
NX Committing changes with git
|
||||
NX Tagging commit with git
|
||||
NX Running target nx-release-publish for project {project-name}:
|
||||
- {project-name}
|
||||
> nx run {project-name}:nx-release-publish
|
||||
📦 @proj/{project-name}@0.0.2
|
||||
=== Tarball Contents ===
|
||||
248B README.md
|
||||
XXXB package.json
|
||||
38B src/index.d.ts
|
||||
208B src/index.js
|
||||
137B src/index.js.map
|
||||
48B src/lib/{project-name}.d.ts
|
||||
213B src/lib/{project-name}.js
|
||||
210B src/lib/{project-name}.js.map
|
||||
=== Tarball Details ===
|
||||
name: @proj/{project-name}
|
||||
version: 0.0.2
|
||||
filename: proj-{project-name}-0.0.2.tgz
|
||||
package size: XXXB
|
||||
unpacked size: XXX.XXX kb
|
||||
shasum: {SHASUM}
|
||||
integrity: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
total files: 8
|
||||
Published to ${e2eRegistryUrl} with tag "latest"
|
||||
NX Successfully ran target nx-release-publish for project {project-name}
|
||||
`);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,123 @@
|
||||
import {
|
||||
cleanupProject,
|
||||
newProject,
|
||||
runCLI,
|
||||
runCommandAsync,
|
||||
uniq,
|
||||
} from '@nx/e2e/utils';
|
||||
import { execSync } from 'node:child_process';
|
||||
|
||||
expect.addSnapshotSerializer({
|
||||
serialize(str: string) {
|
||||
return (
|
||||
str
|
||||
// Remove all output unique to specific projects to ensure deterministic snapshots
|
||||
.replaceAll(/my-pkg-\d+/g, '{project-name}')
|
||||
.replaceAll(
|
||||
/integrity:\s*.*/g,
|
||||
'integrity: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
|
||||
)
|
||||
.replaceAll(/\b[0-9a-f]{40}\b/g, '{SHASUM}')
|
||||
.replaceAll(/\d*B index\.js/g, 'XXB index.js')
|
||||
.replaceAll(/\d*B project\.json/g, 'XXB project.json')
|
||||
.replaceAll(/\d*B package\.json/g, 'XXXB package.json')
|
||||
.replaceAll(/size:\s*\d*\s?B/g, 'size: XXXB')
|
||||
.replaceAll(/\d*\.\d*\s?kB/g, 'XXX.XXX kb')
|
||||
.replaceAll(/[a-fA-F0-9]{7}/g, '{COMMIT_SHA}')
|
||||
.replaceAll(/Test @[\w\d]+/g, 'Test @{COMMIT_AUTHOR}')
|
||||
.replaceAll(/(\w+) lock file/g, 'PM lock file')
|
||||
// Normalize the version title date.
|
||||
.replaceAll(/\(\d{4}-\d{2}-\d{2}\)/g, '(YYYY-MM-DD)')
|
||||
// We trim each line to reduce the chances of snapshot flakiness
|
||||
.split('\n')
|
||||
.map((r) => r.trim())
|
||||
.filter(Boolean)
|
||||
.join('\n')
|
||||
);
|
||||
},
|
||||
test(val: string) {
|
||||
return val != null && typeof val === 'string';
|
||||
},
|
||||
});
|
||||
|
||||
describe('release publishable libraries in workspace with ts solution setup', () => {
|
||||
let e2eRegistryUrl: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
newProject({
|
||||
packages: ['@nx/js'],
|
||||
preset: 'ts',
|
||||
});
|
||||
|
||||
// Normalize git committer information so it is deterministic in snapshots
|
||||
await runCommandAsync(`git config user.email "test@test.com"`);
|
||||
await runCommandAsync(`git config user.name "Test"`);
|
||||
// Create a baseline version tag
|
||||
await runCommandAsync(`git tag v0.0.0`);
|
||||
|
||||
// We need a valid git origin to exist for the commit references to work (and later the test for createRelease)
|
||||
await runCommandAsync(
|
||||
`git remote add origin https://github.com/nrwl/fake-repo.git`
|
||||
);
|
||||
|
||||
// This is the verdaccio instance that the e2e tests themselves are working from
|
||||
e2eRegistryUrl = execSync('npm config get registry').toString().trim();
|
||||
});
|
||||
afterAll(() => cleanupProject());
|
||||
|
||||
it('should be able to release publishable js library', async () => {
|
||||
const jsLib = uniq('my-pkg-');
|
||||
runCLI(
|
||||
`generate @nx/js:lib ${jsLib} --publishable --importPath=@proj/${jsLib}`
|
||||
);
|
||||
|
||||
let releaseOutput = runCLI(`release --first-release`);
|
||||
expect(releaseOutput).toContain('Executing pre-version command');
|
||||
releaseOutput = runCLI(`release --specifier 0.0.2 --yes`);
|
||||
expect(releaseOutput).toMatchInlineSnapshot(`
|
||||
NX Executing pre-version command
|
||||
NX Running release version for project: @proj/{project-name}
|
||||
@proj/{project-name} 🔍 Reading data for package "@proj/{project-name}" from {project-name}/package.json
|
||||
@proj/{project-name} 📄 Resolved the current version as 0.0.1 from {project-name}/package.json
|
||||
@proj/{project-name} 📄 Using the provided version specifier "0.0.2".
|
||||
@proj/{project-name} ✍️ New version 0.0.2 written to {project-name}/package.json
|
||||
"name": "@proj/{project-name}",
|
||||
- "version": "0.0.1",
|
||||
+ "version": "0.0.2",
|
||||
"type": "module",
|
||||
NX Updating PM lock file
|
||||
NX Staging changed files with git
|
||||
NX Generating an entry in CHANGELOG.md for v0.0.2
|
||||
+ ## 0.0.2 (YYYY-MM-DD)
|
||||
+
|
||||
+ This was a version bump only, there were no code changes.
|
||||
NX Staging changed files with git
|
||||
NX Committing changes with git
|
||||
NX Tagging commit with git
|
||||
NX Running target nx-release-publish for project @proj/{project-name}:
|
||||
- @proj/{project-name}
|
||||
> nx run @proj/{project-name}:nx-release-publish
|
||||
📦 @proj/{project-name}@0.0.2
|
||||
=== Tarball Contents ===
|
||||
138B README.md
|
||||
76B dist/index.d.ts
|
||||
125B dist/index.d.ts.map
|
||||
41B dist/index.js
|
||||
92B dist/lib/{project-name}.d.ts
|
||||
161B dist/lib/{project-name}.d.ts.map
|
||||
64B dist/lib/{project-name}.js
|
||||
XXXB package.json
|
||||
=== Tarball Details ===
|
||||
name: @proj/{project-name}
|
||||
version: 0.0.2
|
||||
filename: proj-{project-name}-0.0.2.tgz
|
||||
package size: XXXB
|
||||
unpacked size: XXX.XXX kb
|
||||
shasum: {SHASUM}
|
||||
integrity: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
total files: 8
|
||||
Published to ${e2eRegistryUrl} with tag "latest"
|
||||
NX Successfully ran target nx-release-publish for project @proj/{project-name}
|
||||
`);
|
||||
});
|
||||
});
|
||||
@ -31,7 +31,6 @@ describe('lib', () => {
|
||||
beforeEach(() => {
|
||||
tree = createTreeWithEmptyWorkspace();
|
||||
tree.write('/.gitignore', '');
|
||||
tree.write('/.gitignore', '');
|
||||
});
|
||||
|
||||
it.each`
|
||||
|
||||
@ -5,14 +5,11 @@ import {
|
||||
formatFiles,
|
||||
generateFiles,
|
||||
GeneratorCallback,
|
||||
getPackageManagerCommand,
|
||||
installPackagesTask,
|
||||
joinPathFragments,
|
||||
names,
|
||||
offsetFromRoot,
|
||||
output,
|
||||
ProjectConfiguration,
|
||||
ProjectGraphProjectNode,
|
||||
readNxJson,
|
||||
readProjectConfiguration,
|
||||
runTasksInSerial,
|
||||
@ -69,6 +66,11 @@ import type {
|
||||
} from './schema';
|
||||
import { sortPackageJsonFields } from '../../utils/package-json/sort-fields';
|
||||
import { getImportPath } from '../../utils/get-import-path';
|
||||
import {
|
||||
addReleaseConfigForNonTsSolution,
|
||||
addReleaseConfigForTsSolution,
|
||||
releaseTasks,
|
||||
} from './utils/add-release-config';
|
||||
|
||||
const defaultOutputDirectory = 'dist';
|
||||
|
||||
@ -115,10 +117,6 @@ export async function libraryGeneratorInternal(
|
||||
tasks.push(addProjectDependencies(tree, options));
|
||||
}
|
||||
|
||||
if (options.publishable) {
|
||||
tasks.push(await setupVerdaccio(tree, { ...options, skipFormat: true }));
|
||||
}
|
||||
|
||||
if (options.bundler === 'rollup') {
|
||||
const { configurationGenerator } = ensurePackage('@nx/rollup', nxVersion);
|
||||
await configurationGenerator(tree, {
|
||||
@ -249,9 +247,7 @@ export async function libraryGeneratorInternal(
|
||||
}
|
||||
|
||||
if (options.publishable) {
|
||||
tasks.push(() => {
|
||||
logNxReleaseDocsInfo();
|
||||
});
|
||||
tasks.push(await releaseTasks(tree));
|
||||
}
|
||||
|
||||
// Always run install to link packages.
|
||||
@ -337,32 +333,20 @@ async function configureProject(
|
||||
}
|
||||
|
||||
if (options.publishable) {
|
||||
if (!options.isUsingTsSolutionConfig) {
|
||||
const packageRoot = joinPathFragments(
|
||||
defaultOutputDirectory,
|
||||
'{projectRoot}'
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
await addReleaseConfigForTsSolution(
|
||||
tree,
|
||||
options.name,
|
||||
projectConfiguration
|
||||
);
|
||||
} else {
|
||||
await addReleaseConfigForNonTsSolution(
|
||||
tree,
|
||||
options.name,
|
||||
projectConfiguration,
|
||||
defaultOutputDirectory
|
||||
);
|
||||
|
||||
projectConfiguration.targets ??= {};
|
||||
projectConfiguration.targets['nx-release-publish'] = {
|
||||
options: {
|
||||
packageRoot,
|
||||
},
|
||||
};
|
||||
|
||||
projectConfiguration.release = {
|
||||
version: {
|
||||
generatorOptions: {
|
||||
packageRoot,
|
||||
// using git tags to determine the current version is required here because
|
||||
// the version in the package root is overridden with every build
|
||||
currentVersionResolver: 'git-tag',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
await addProjectToNxReleaseConfig(tree, options, projectConfiguration);
|
||||
}
|
||||
|
||||
if (!options.useProjectJson) {
|
||||
@ -1259,120 +1243,6 @@ function determineEntryFields(
|
||||
}
|
||||
}
|
||||
|
||||
function projectsConfigMatchesProject(
|
||||
projectsConfig: string | string[] | undefined,
|
||||
project: ProjectGraphProjectNode
|
||||
): boolean {
|
||||
if (!projectsConfig) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof projectsConfig === 'string') {
|
||||
projectsConfig = [projectsConfig];
|
||||
}
|
||||
|
||||
const graph: Record<string, ProjectGraphProjectNode> = {
|
||||
[project.name]: project,
|
||||
};
|
||||
|
||||
const matchingProjects = findMatchingProjects(projectsConfig, graph);
|
||||
|
||||
return matchingProjects.includes(project.name);
|
||||
}
|
||||
|
||||
async function addProjectToNxReleaseConfig(
|
||||
tree: Tree,
|
||||
options: NormalizedLibraryGeneratorOptions,
|
||||
projectConfiguration: ProjectConfiguration
|
||||
) {
|
||||
const nxJson = readNxJson(tree);
|
||||
|
||||
const addPreVersionCommand = () => {
|
||||
const pmc = getPackageManagerCommand();
|
||||
|
||||
nxJson.release = {
|
||||
...nxJson.release,
|
||||
version: {
|
||||
preVersionCommand: `${pmc.dlx} nx run-many -t build`,
|
||||
...nxJson.release?.version,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
if (!nxJson.release || (!nxJson.release.projects && !nxJson.release.groups)) {
|
||||
// skip adding any projects configuration since the new project should be
|
||||
// automatically included by nx release's default project detection logic
|
||||
addPreVersionCommand();
|
||||
writeJson(tree, 'nx.json', nxJson);
|
||||
return;
|
||||
}
|
||||
|
||||
const project: ProjectGraphProjectNode = {
|
||||
name: options.name,
|
||||
type: 'lib' as const,
|
||||
data: {
|
||||
root: projectConfiguration.root,
|
||||
tags: projectConfiguration.tags,
|
||||
},
|
||||
};
|
||||
|
||||
if (projectsConfigMatchesProject(nxJson.release.projects, project)) {
|
||||
output.log({
|
||||
title: `Project already included in existing release configuration`,
|
||||
});
|
||||
addPreVersionCommand();
|
||||
writeJson(tree, 'nx.json', nxJson);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Array.isArray(nxJson.release.projects)) {
|
||||
nxJson.release.projects.push(options.name);
|
||||
addPreVersionCommand();
|
||||
writeJson(tree, 'nx.json', nxJson);
|
||||
output.log({
|
||||
title: `Added project to existing release configuration`,
|
||||
});
|
||||
}
|
||||
|
||||
if (nxJson.release.groups) {
|
||||
const allGroups = Object.entries(nxJson.release.groups);
|
||||
|
||||
for (const [name, group] of allGroups) {
|
||||
if (projectsConfigMatchesProject(group.projects, project)) {
|
||||
addPreVersionCommand();
|
||||
writeJson(tree, 'nx.json', nxJson);
|
||||
return `Project already included in existing release configuration for group ${name}`;
|
||||
}
|
||||
}
|
||||
|
||||
output.warn({
|
||||
title: `Could not find a release group that includes ${options.name}`,
|
||||
bodyLines: [
|
||||
`Ensure that ${options.name} is included in a release group's "projects" list in nx.json so it can be published with "nx release"`,
|
||||
],
|
||||
});
|
||||
addPreVersionCommand();
|
||||
writeJson(tree, 'nx.json', nxJson);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof nxJson.release.projects === 'string') {
|
||||
nxJson.release.projects = [nxJson.release.projects, options.name];
|
||||
addPreVersionCommand();
|
||||
writeJson(tree, 'nx.json', nxJson);
|
||||
output.log({
|
||||
title: `Added project to existing release configuration`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function logNxReleaseDocsInfo() {
|
||||
output.log({
|
||||
title: `📦 To learn how to publish this library, see https://nx.dev/core-features/manage-releases.`,
|
||||
});
|
||||
}
|
||||
|
||||
function findRootJestPreset(tree: Tree): string | null {
|
||||
const ext = ['js', 'cjs', 'mjs'].find((ext) =>
|
||||
tree.exists(`jest.preset.${ext}`)
|
||||
|
||||
@ -0,0 +1,598 @@
|
||||
import {
|
||||
getPackageManagerCommand,
|
||||
readJson,
|
||||
Tree,
|
||||
updateJson,
|
||||
output,
|
||||
ProjectConfiguration,
|
||||
} from '@nx/devkit';
|
||||
import { createTreeWithEmptyWorkspace } from 'nx/src/devkit-testing-exports';
|
||||
import {
|
||||
addReleaseConfigForNonTsSolution,
|
||||
addReleaseConfigForTsSolution,
|
||||
} from './add-release-config';
|
||||
|
||||
describe('add release config', () => {
|
||||
let tree: Tree;
|
||||
|
||||
beforeEach(() => {
|
||||
tree = createTreeWithEmptyWorkspace();
|
||||
tree.write('/.gitignore', '');
|
||||
});
|
||||
|
||||
describe('addReleaseConfigForNonTsSolution', () => {
|
||||
it('should update the nx-release-publish target to specify dist/{projectRoot} as the package root', async () => {
|
||||
const projectConfig: ProjectConfiguration = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForNonTsSolution(tree, 'my-lib', projectConfig);
|
||||
expect(projectConfig.targets?.['nx-release-publish']).toEqual({
|
||||
options: {
|
||||
packageRoot: 'dist/{projectRoot}',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not change preVersionCommand if it already exists', async () => {
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = {
|
||||
version: {
|
||||
preVersionCommand: 'echo "hello world"',
|
||||
},
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForNonTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
version: {
|
||||
preVersionCommand: 'echo "hello world"',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not add projects if no release config exists', async () => {
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
delete json.release;
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForNonTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should not add projects if release config exists but doesn't specify groups or projects", async () => {
|
||||
const existingReleaseConfig = {
|
||||
version: {
|
||||
git: {},
|
||||
},
|
||||
changelog: {
|
||||
projectChangelogs: true,
|
||||
},
|
||||
};
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = existingReleaseConfig;
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForNonTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
...existingReleaseConfig,
|
||||
version: {
|
||||
...existingReleaseConfig.version,
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not change projects if it already exists as a string and matches the new project', async () => {
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = {
|
||||
projects: '*',
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForNonTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
projects: '*',
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not change projects if it already exists as an array and matches the new project by name', async () => {
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = {
|
||||
projects: ['something-else', 'my-lib'],
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForNonTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
projects: ['something-else', 'my-lib'],
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not change projects if it already exists and matches the new project by tag', async () => {
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = {
|
||||
projects: ['tag:one'],
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig: ProjectConfiguration = {
|
||||
root: 'libs/my-lib',
|
||||
tags: ['one', 'two'],
|
||||
};
|
||||
await addReleaseConfigForNonTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
projects: ['tag:one'],
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not change projects if it already exists and matches the new project by root directory', async () => {
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = {
|
||||
projects: ['packages/*'],
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'packages/my-lib' };
|
||||
await addReleaseConfigForNonTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
projects: ['packages/*'],
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should append project to projects if projects exists as an array, but doesn't already match the new project", async () => {
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = {
|
||||
projects: ['something-else'],
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForNonTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
projects: ['something-else', 'my-lib'],
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should convert projects to an array and append the new project to it if projects exists as a string, but doesn't already match the new project", async () => {
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = {
|
||||
projects: 'packages',
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForNonTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
projects: ['packages', 'my-lib'],
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not change projects if it already exists as groups config and matches the new project', async () => {
|
||||
const existingReleaseConfig = {
|
||||
groups: {
|
||||
group1: {
|
||||
projects: ['something-else'],
|
||||
},
|
||||
group2: {
|
||||
projects: ['my-lib'],
|
||||
},
|
||||
},
|
||||
};
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = existingReleaseConfig;
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForNonTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
groups: existingReleaseConfig.groups,
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should warn the user if their defined groups don't match the new project", async () => {
|
||||
const outputSpy = jest
|
||||
.spyOn(output, 'warn')
|
||||
.mockImplementationOnce(() => {
|
||||
return undefined as never;
|
||||
});
|
||||
|
||||
const existingReleaseConfig = {
|
||||
groups: {
|
||||
group1: {
|
||||
projects: ['something-else'],
|
||||
},
|
||||
group2: {
|
||||
projects: ['other-thing'],
|
||||
},
|
||||
},
|
||||
};
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = existingReleaseConfig;
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForNonTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
groups: existingReleaseConfig.groups,
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
expect(outputSpy).toHaveBeenCalledWith({
|
||||
title: `Could not find a release group that includes my-lib`,
|
||||
bodyLines: [
|
||||
`Ensure that my-lib is included in a release group's "projects" list in nx.json so it can be published with "nx release"`,
|
||||
],
|
||||
});
|
||||
|
||||
outputSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe('addReleaseConfigForTsSolution', () => {
|
||||
it('should not update set nx-release-publish target', async () => {
|
||||
const projectConfig: ProjectConfiguration = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForTsSolution(tree, 'my-lib', projectConfig);
|
||||
expect(projectConfig.targets?.['nx-release-publish']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should not change preVersionCommand if it already exists', async () => {
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = {
|
||||
version: {
|
||||
preVersionCommand: 'echo "hello world"',
|
||||
},
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
version: {
|
||||
preVersionCommand: 'echo "hello world"',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not add projects if no release config exists', async () => {
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
delete json.release;
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should not add projects if release config exists but doesn't specify groups or projects", async () => {
|
||||
const existingReleaseConfig = {
|
||||
version: {
|
||||
git: {},
|
||||
},
|
||||
changelog: {
|
||||
projectChangelogs: true,
|
||||
},
|
||||
};
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = existingReleaseConfig;
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
...existingReleaseConfig,
|
||||
version: {
|
||||
...existingReleaseConfig.version,
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not change projects if it already exists as a string and matches the new project', async () => {
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = {
|
||||
projects: '*',
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
projects: '*',
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not change projects if it already exists as an array and matches the new project by name', async () => {
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = {
|
||||
projects: ['something-else', 'my-lib'],
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
projects: ['something-else', 'my-lib'],
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not change projects if it already exists and matches the new project by tag', async () => {
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = {
|
||||
projects: ['tag:one'],
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig: ProjectConfiguration = {
|
||||
root: 'libs/my-lib',
|
||||
tags: ['one', 'two'],
|
||||
};
|
||||
await addReleaseConfigForTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
projects: ['tag:one'],
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not change projects if it already exists and matches the new project by root directory', async () => {
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = {
|
||||
projects: ['packages/*'],
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'packages/my-lib' };
|
||||
await addReleaseConfigForTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
projects: ['packages/*'],
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should append project to projects if projects exists as an array, but doesn't already match the new project", async () => {
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = {
|
||||
projects: ['something-else'],
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
projects: ['something-else', 'my-lib'],
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should convert projects to an array and append the new project to it if projects exists as a string, but doesn't already match the new project", async () => {
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = {
|
||||
projects: 'packages',
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
projects: ['packages', 'my-lib'],
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not change projects if it already exists as groups config and matches the new project', async () => {
|
||||
const existingReleaseConfig = {
|
||||
groups: {
|
||||
group1: {
|
||||
projects: ['something-else'],
|
||||
},
|
||||
group2: {
|
||||
projects: ['my-lib'],
|
||||
},
|
||||
},
|
||||
};
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = existingReleaseConfig;
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
groups: existingReleaseConfig.groups,
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should warn the user if their defined groups don't match the new project", async () => {
|
||||
const outputSpy = jest
|
||||
.spyOn(output, 'warn')
|
||||
.mockImplementationOnce(() => {
|
||||
return undefined as never;
|
||||
});
|
||||
|
||||
const existingReleaseConfig = {
|
||||
groups: {
|
||||
group1: {
|
||||
projects: ['something-else'],
|
||||
},
|
||||
group2: {
|
||||
projects: ['other-thing'],
|
||||
},
|
||||
},
|
||||
};
|
||||
updateJson(tree, 'nx.json', (json) => {
|
||||
json.release = existingReleaseConfig;
|
||||
return json;
|
||||
});
|
||||
|
||||
const projectConfig = { root: 'libs/my-lib' };
|
||||
await addReleaseConfigForTsSolution(tree, 'my-lib', projectConfig);
|
||||
|
||||
const nxJson = readJson(tree, 'nx.json');
|
||||
expect(nxJson.release).toEqual({
|
||||
groups: existingReleaseConfig.groups,
|
||||
version: {
|
||||
preVersionCommand: `${
|
||||
getPackageManagerCommand().dlx
|
||||
} nx run-many -t build`,
|
||||
},
|
||||
});
|
||||
expect(outputSpy).toHaveBeenCalledWith({
|
||||
title: `Could not find a release group that includes my-lib`,
|
||||
bodyLines: [
|
||||
`Ensure that my-lib is included in a release group's "projects" list in nx.json so it can be published with "nx release"`,
|
||||
],
|
||||
});
|
||||
|
||||
outputSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
});
|
||||
183
packages/js/src/generators/library/utils/add-release-config.ts
Normal file
183
packages/js/src/generators/library/utils/add-release-config.ts
Normal file
@ -0,0 +1,183 @@
|
||||
import {
|
||||
GeneratorCallback,
|
||||
getPackageManagerCommand,
|
||||
joinPathFragments,
|
||||
output,
|
||||
ProjectConfiguration,
|
||||
ProjectGraphProjectNode,
|
||||
readNxJson,
|
||||
runTasksInSerial,
|
||||
Tree,
|
||||
writeJson,
|
||||
} from '@nx/devkit';
|
||||
import { findMatchingProjects } from 'nx/src/utils/find-matching-projects';
|
||||
import setupVerdaccio from '../../setup-verdaccio/generator';
|
||||
|
||||
/**
|
||||
* Adds release option in nx.json to build the project before versioning
|
||||
*/
|
||||
export async function addReleaseConfigForTsSolution(
|
||||
tree: Tree,
|
||||
projectName: string,
|
||||
projectConfiguration: ProjectConfiguration
|
||||
): Promise<void> {
|
||||
const nxJson = readNxJson(tree);
|
||||
|
||||
const addPreVersionCommand = () => {
|
||||
const pmc = getPackageManagerCommand();
|
||||
|
||||
nxJson.release = {
|
||||
...nxJson.release,
|
||||
version: {
|
||||
preVersionCommand: `${pmc.dlx} nx run-many -t build`,
|
||||
...nxJson.release?.version,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
// if the release configuration does not exist, it will be created
|
||||
if (!nxJson.release || (!nxJson.release.projects && !nxJson.release.groups)) {
|
||||
// skip adding any projects configuration since the new project should be
|
||||
// automatically included by nx release's default project detection logic
|
||||
addPreVersionCommand();
|
||||
writeJson(tree, 'nx.json', nxJson);
|
||||
return;
|
||||
}
|
||||
|
||||
const project: ProjectGraphProjectNode = {
|
||||
name: projectName,
|
||||
type: 'lib' as const,
|
||||
data: {
|
||||
root: projectConfiguration.root,
|
||||
tags: projectConfiguration.tags,
|
||||
},
|
||||
};
|
||||
|
||||
// if the project is already included in the release configuration, it will not be added again
|
||||
if (projectsConfigMatchesProject(nxJson.release.projects, project)) {
|
||||
output.log({
|
||||
title: `Project already included in existing release configuration`,
|
||||
});
|
||||
addPreVersionCommand();
|
||||
writeJson(tree, 'nx.json', nxJson);
|
||||
return;
|
||||
}
|
||||
|
||||
// if the release configuration is a string, it will be converted to an array and added to it
|
||||
if (Array.isArray(nxJson.release.projects)) {
|
||||
nxJson.release.projects.push(projectName);
|
||||
addPreVersionCommand();
|
||||
writeJson(tree, 'nx.json', nxJson);
|
||||
output.log({
|
||||
title: `Added project to existing release configuration`,
|
||||
});
|
||||
}
|
||||
|
||||
if (nxJson.release.groups) {
|
||||
const allGroups = Object.entries(nxJson.release.groups);
|
||||
|
||||
for (const [name, group] of allGroups) {
|
||||
if (projectsConfigMatchesProject(group.projects, project)) {
|
||||
addPreVersionCommand();
|
||||
writeJson(tree, 'nx.json', nxJson);
|
||||
output.log({
|
||||
title: `Project already included in existing release configuration for group ${name}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
output.warn({
|
||||
title: `Could not find a release group that includes ${projectName}`,
|
||||
bodyLines: [
|
||||
`Ensure that ${projectName} is included in a release group's "projects" list in nx.json so it can be published with "nx release"`,
|
||||
],
|
||||
});
|
||||
addPreVersionCommand();
|
||||
writeJson(tree, 'nx.json', nxJson);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof nxJson.release.projects === 'string') {
|
||||
nxJson.release.projects = [nxJson.release.projects, projectName];
|
||||
addPreVersionCommand();
|
||||
writeJson(tree, 'nx.json', nxJson);
|
||||
output.log({
|
||||
title: `Added project to existing release configuration`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add release configuration for non-ts solution projects
|
||||
* Add release option in project.json and add packageRoot to nx-release-publish target
|
||||
*/
|
||||
export async function addReleaseConfigForNonTsSolution(
|
||||
tree: Tree,
|
||||
projectName: string,
|
||||
projectConfiguration: ProjectConfiguration,
|
||||
defaultOutputDirectory: string = 'dist'
|
||||
) {
|
||||
const packageRoot = joinPathFragments(
|
||||
defaultOutputDirectory,
|
||||
'{projectRoot}'
|
||||
);
|
||||
|
||||
projectConfiguration.targets ??= {};
|
||||
projectConfiguration.targets['nx-release-publish'] = {
|
||||
options: {
|
||||
packageRoot,
|
||||
},
|
||||
};
|
||||
|
||||
projectConfiguration.release = {
|
||||
version: {
|
||||
generatorOptions: {
|
||||
packageRoot,
|
||||
// using git tags to determine the current version is required here because
|
||||
// the version in the package root is overridden with every build
|
||||
currentVersionResolver: 'git-tag',
|
||||
fallbackCurrentVersionResolver: 'disk',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
await addReleaseConfigForTsSolution(tree, projectName, projectConfiguration);
|
||||
|
||||
return projectConfiguration;
|
||||
}
|
||||
|
||||
function projectsConfigMatchesProject(
|
||||
projectsConfig: string | string[] | undefined,
|
||||
project: ProjectGraphProjectNode
|
||||
): boolean {
|
||||
if (!projectsConfig) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof projectsConfig === 'string') {
|
||||
projectsConfig = [projectsConfig];
|
||||
}
|
||||
|
||||
const graph: Record<string, ProjectGraphProjectNode> = {
|
||||
[project.name]: project,
|
||||
};
|
||||
|
||||
const matchingProjects = findMatchingProjects(projectsConfig, graph);
|
||||
|
||||
return matchingProjects.includes(project.name);
|
||||
}
|
||||
|
||||
export async function releaseTasks(tree: Tree): Promise<GeneratorCallback> {
|
||||
return runTasksInSerial(
|
||||
await setupVerdaccio(tree, { skipFormat: true }),
|
||||
() => logNxReleaseDocsInfo()
|
||||
);
|
||||
}
|
||||
|
||||
function logNxReleaseDocsInfo() {
|
||||
output.log({
|
||||
title: `📦 To learn how to publish this library, see https://nx.dev/core-features/manage-releases.`,
|
||||
});
|
||||
}
|
||||
@ -110,10 +110,7 @@ async function execAsync(command: string, cwd: string): Promise<string> {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
exec(command, { cwd, windowsHide: false }, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
return reject(error);
|
||||
}
|
||||
if (stderr) {
|
||||
return reject(stderr);
|
||||
return reject((stderr ? `${stderr}\n` : '') + error);
|
||||
}
|
||||
return resolve(stdout.trim());
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user