nx 21.0.0-canary.20250429-cf4a1f3 → 21.0.0-canary.20250501-8f50358

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/migrations.json +16 -1
  2. package/package.json +11 -11
  3. package/release/changelog-renderer/index.d.ts +7 -7
  4. package/release/changelog-renderer/index.js +12 -31
  5. package/schemas/nx-schema.json +8 -3
  6. package/src/command-line/migrate/migrate-ui-api.d.ts +2 -1
  7. package/src/command-line/migrate/migrate-ui-api.js +4 -3
  8. package/src/command-line/migrate/migrate.d.ts +12 -6
  9. package/src/command-line/migrate/migrate.js +31 -9
  10. package/src/command-line/release/changelog.d.ts +3 -2
  11. package/src/command-line/release/changelog.js +57 -70
  12. package/src/command-line/release/command-object.d.ts +1 -1
  13. package/src/command-line/release/config/config.d.ts +8 -1
  14. package/src/command-line/release/config/config.js +18 -11
  15. package/src/command-line/release/release.js +30 -18
  16. package/src/command-line/release/utils/git.d.ts +1 -0
  17. package/src/command-line/release/utils/git.js +27 -8
  18. package/src/command-line/release/utils/remote-release-clients/github.d.ts +57 -0
  19. package/src/command-line/release/utils/remote-release-clients/github.js +309 -0
  20. package/src/command-line/release/utils/remote-release-clients/gitlab.d.ts +62 -0
  21. package/src/command-line/release/utils/remote-release-clients/gitlab.js +271 -0
  22. package/src/command-line/release/utils/remote-release-clients/remote-release-client.d.ts +111 -0
  23. package/src/command-line/release/utils/remote-release-clients/remote-release-client.js +136 -0
  24. package/src/command-line/repair/repair.js +8 -2
  25. package/src/command-line/report/report.js +1 -1
  26. package/src/command-line/yargs-utils/shared-options.d.ts +1 -1
  27. package/src/command-line/yargs-utils/shared-options.js +22 -3
  28. package/src/config/misc-interfaces.d.ts +9 -1
  29. package/src/config/nx-json.d.ts +8 -5
  30. package/src/core/graph/main.js +1 -1
  31. package/src/core/graph/styles.css +1 -1
  32. package/src/devkit-exports.d.ts +1 -1
  33. package/src/migrations/update-21-0-0/release-changelog-config-changes.d.ts +2 -0
  34. package/src/migrations/update-21-0-0/release-changelog-config-changes.js +38 -0
  35. package/src/migrations/update-21-0-0/remove-custom-tasks-runner.d.ts +2 -0
  36. package/src/migrations/update-21-0-0/remove-custom-tasks-runner.js +38 -0
  37. package/src/migrations/update-21-0-0/remove-legacy-cache.d.ts +2 -0
  38. package/src/migrations/update-21-0-0/remove-legacy-cache.js +17 -0
  39. package/src/native/index.d.ts +6 -1
  40. package/src/native/native-bindings.js +1 -0
  41. package/src/native/native-file-cache-location.js +2 -1
  42. package/src/native/nx.wasm32-wasi.wasm +0 -0
  43. package/src/project-graph/plugins/get-plugins.js +19 -14
  44. package/src/tasks-runner/batch/run-batch.js +1 -1
  45. package/src/tasks-runner/cache.d.ts +1 -2
  46. package/src/tasks-runner/cache.js +2 -18
  47. package/src/tasks-runner/is-tui-enabled.d.ts +16 -1
  48. package/src/tasks-runner/is-tui-enabled.js +40 -28
  49. package/src/tasks-runner/life-cycles/tui-summary-life-cycle.js +8 -7
  50. package/src/tasks-runner/pseudo-terminal.d.ts +1 -0
  51. package/src/tasks-runner/pseudo-terminal.js +11 -1
  52. package/src/tasks-runner/run-command.js +5 -27
  53. package/src/tasks-runner/running-tasks/node-child-process.d.ts +1 -0
  54. package/src/tasks-runner/running-tasks/node-child-process.js +7 -0
  55. package/src/tasks-runner/task-graph-utils.d.ts +3 -0
  56. package/src/tasks-runner/task-graph-utils.js +31 -2
  57. package/src/tasks-runner/task-orchestrator.js +16 -4
  58. package/src/utils/is-ci.d.ts +1 -1
  59. package/src/utils/is-ci.js +4 -1
  60. package/src/utils/package-manager.d.ts +1 -0
  61. package/src/utils/package-manager.js +29 -16
  62. package/src/command-line/release/utils/github.d.ts +0 -32
  63. package/src/command-line/release/utils/github.js +0 -326
@@ -0,0 +1,111 @@
1
+ import type { AxiosRequestConfig } from 'axios';
2
+ import type { PostGitTask } from '../../changelog';
3
+ import { ResolvedCreateRemoteReleaseProvider } from '../../config/config';
4
+ import type { Reference } from '../git';
5
+ import { type ReleaseVersion } from '../shared';
6
+ import type { GithubRemoteReleaseClient } from './github';
7
+ import type { GitLabRemoteReleaseClient } from './gitlab';
8
+ export type RemoteRepoSlug = `${string}/${string}`;
9
+ export interface RemoteRepoData {
10
+ hostname: string;
11
+ slug: RemoteRepoSlug;
12
+ apiBaseUrl: string;
13
+ }
14
+ export interface RemoteReleaseOptions {
15
+ version: string;
16
+ body: string;
17
+ prerelease: boolean;
18
+ commit: string;
19
+ }
20
+ export interface RemoteReleaseResult {
21
+ status: 'created' | 'updated' | 'manual';
22
+ id?: string;
23
+ url?: string;
24
+ error?: any;
25
+ requestData?: any;
26
+ }
27
+ /**
28
+ * Abstract base class for remote release clients
29
+ */
30
+ export declare abstract class RemoteReleaseClient<RemoteRelease extends Record<string, any>> {
31
+ private remoteRepoData;
32
+ protected createReleaseConfig: false | ResolvedCreateRemoteReleaseProvider;
33
+ protected tokenData: {
34
+ token: string;
35
+ headerName: string;
36
+ } | null;
37
+ /**
38
+ * Used in user-facing messaging
39
+ */
40
+ abstract remoteReleaseProviderName: string;
41
+ protected tokenHeader: Record<string, string>;
42
+ constructor(remoteRepoData: RemoteRepoData | null, createReleaseConfig: false | ResolvedCreateRemoteReleaseProvider, tokenData: {
43
+ token: string;
44
+ headerName: string;
45
+ } | null);
46
+ getRemoteRepoData<T extends RemoteRepoData>(): T | null;
47
+ /**
48
+ * Create a post git task that will be executed by nx release changelog after performing any relevant
49
+ * git operations, if the user has opted into remote release creation.
50
+ */
51
+ abstract createPostGitTask(releaseVersion: ReleaseVersion, changelogContents: string, dryRun: boolean): PostGitTask;
52
+ /**
53
+ * Apply authors' corresponding usernames, if applicable, on the remote release provider. It is designed to be
54
+ * invoked by a changelog renderer implementation.
55
+ */
56
+ abstract applyUsernameToAuthors(authors: Map<string, {
57
+ email: Set<string>;
58
+ username?: string;
59
+ }>): Promise<void>;
60
+ /**
61
+ * Make an (optionally authenticated) API request to the remote release provider
62
+ */
63
+ protected makeRequest(url: string, opts?: AxiosRequestConfig): Promise<any>;
64
+ createOrUpdateRelease(releaseVersion: ReleaseVersion, changelogContents: string, latestCommit: string, { dryRun }: {
65
+ dryRun: boolean;
66
+ }): Promise<void>;
67
+ /**
68
+ * Format references for the release (e.g., PRs, issues)
69
+ */
70
+ formatReferences(_references: Reference[]): string;
71
+ /**
72
+ * Handle non-auth related errors when creating releases
73
+ */
74
+ protected abstract handleError(error: any, result: RemoteReleaseResult): Promise<void>;
75
+ /**
76
+ * Display authentication error message
77
+ */
78
+ protected abstract handleAuthError(): void;
79
+ /**
80
+ * Log the release action (create or update)
81
+ */
82
+ protected abstract logReleaseAction(existingRelease: RemoteRelease | undefined, gitTag: string, dryRun: boolean): void;
83
+ /**
84
+ * Print changelog changes
85
+ */
86
+ protected printRemoteReleaseContents(existingBody: string, newBody: string): void;
87
+ /**
88
+ * Get a release by tag
89
+ */
90
+ protected abstract getReleaseByTag(tag: string): Promise<RemoteRelease>;
91
+ /**
92
+ * Create a manual release URL used to create/edit a release in the remote release provider's UI
93
+ */
94
+ protected abstract getManualRemoteReleaseURL(remoteReleaseOptions: RemoteReleaseOptions): string;
95
+ /**
96
+ * Create a new release
97
+ */
98
+ protected abstract createRelease(body: RemoteRelease): Promise<any>;
99
+ /**
100
+ * Update an existing release
101
+ */
102
+ protected abstract updateRelease(id: string, body: RemoteRelease): Promise<any>;
103
+ /**
104
+ * Synchronize a release with the remote release provider
105
+ */
106
+ protected abstract syncRelease(remoteReleaseOptions: RemoteReleaseOptions, existingRelease?: RemoteRelease): Promise<RemoteReleaseResult>;
107
+ }
108
+ /**
109
+ * Factory function to create a remote release client based on the given configuration
110
+ */
111
+ export declare function createRemoteReleaseClient(createReleaseConfig: false | ResolvedCreateRemoteReleaseProvider, remoteName?: string): Promise<GithubRemoteReleaseClient | GitLabRemoteReleaseClient | null>;
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RemoteReleaseClient = void 0;
4
+ exports.createRemoteReleaseClient = createRemoteReleaseClient;
5
+ const axios_1 = require("axios");
6
+ const print_changes_1 = require("../print-changes");
7
+ const shared_1 = require("../shared");
8
+ /**
9
+ * Abstract base class for remote release clients
10
+ */
11
+ class RemoteReleaseClient {
12
+ constructor(
13
+ // A workspace isn't guaranteed to have a remote
14
+ remoteRepoData, createReleaseConfig, tokenData) {
15
+ this.remoteRepoData = remoteRepoData;
16
+ this.createReleaseConfig = createReleaseConfig;
17
+ this.tokenData = tokenData;
18
+ this.tokenHeader = {};
19
+ if (tokenData) {
20
+ if (tokenData.headerName === 'Authorization') {
21
+ this.tokenHeader[tokenData.headerName] = `Bearer ${tokenData.token}`;
22
+ }
23
+ else {
24
+ this.tokenHeader[tokenData.headerName] = tokenData.token;
25
+ }
26
+ }
27
+ }
28
+ getRemoteRepoData() {
29
+ return this.remoteRepoData;
30
+ }
31
+ /**
32
+ * Make an (optionally authenticated) API request to the remote release provider
33
+ */
34
+ async makeRequest(url, opts = {}) {
35
+ const remoteRepoData = this.getRemoteRepoData();
36
+ if (!remoteRepoData) {
37
+ throw new Error(`No remote repo data could be resolved for the current workspace`);
38
+ }
39
+ const config = {
40
+ ...opts,
41
+ baseURL: remoteRepoData.apiBaseUrl,
42
+ headers: {
43
+ ...opts.headers,
44
+ ...this.tokenHeader,
45
+ },
46
+ };
47
+ return (await (0, axios_1.default)(url, config)).data;
48
+ }
49
+ async createOrUpdateRelease(releaseVersion, changelogContents, latestCommit, { dryRun }) {
50
+ let existingRelease;
51
+ try {
52
+ existingRelease = await this.getReleaseByTag(releaseVersion.gitTag);
53
+ }
54
+ catch (err) {
55
+ if (err.response?.status === 401) {
56
+ this.handleAuthError();
57
+ process.exit(1);
58
+ }
59
+ if (err.response?.status === 404) {
60
+ // No existing release found, this is fine
61
+ }
62
+ else {
63
+ // Rethrow unknown errors for now
64
+ throw err;
65
+ }
66
+ }
67
+ this.logReleaseAction(existingRelease, releaseVersion.gitTag, dryRun);
68
+ this.printRemoteReleaseContents(existingRelease
69
+ ? 'body' in existingRelease
70
+ ? existingRelease.body
71
+ : 'description' in existingRelease
72
+ ? existingRelease.description
73
+ : ''
74
+ : '', changelogContents);
75
+ if (!dryRun) {
76
+ const remoteReleaseOptions = {
77
+ version: releaseVersion.gitTag,
78
+ prerelease: releaseVersion.isPrerelease,
79
+ body: changelogContents,
80
+ commit: latestCommit,
81
+ };
82
+ const result = await this.syncRelease(remoteReleaseOptions, existingRelease);
83
+ if (result.status === 'manual') {
84
+ await this.handleError(result.error, result);
85
+ }
86
+ }
87
+ }
88
+ /**
89
+ * Format references for the release (e.g., PRs, issues)
90
+ */
91
+ formatReferences(_references) {
92
+ // Base implementation - to be overridden by specific providers
93
+ return '';
94
+ }
95
+ /**
96
+ * Print changelog changes
97
+ */
98
+ printRemoteReleaseContents(existingBody, newBody) {
99
+ console.log('');
100
+ (0, print_changes_1.printDiff)(existingBody, newBody, 3, shared_1.noDiffInChangelogMessage);
101
+ }
102
+ }
103
+ exports.RemoteReleaseClient = RemoteReleaseClient;
104
+ /**
105
+ * Factory function to create a remote release client based on the given configuration
106
+ */
107
+ async function createRemoteReleaseClient(createReleaseConfig, remoteName = 'origin') {
108
+ switch (true) {
109
+ // GitHub and GitHub Enterprise Server
110
+ case typeof createReleaseConfig === 'object' &&
111
+ (createReleaseConfig.provider === 'github-enterprise-server' ||
112
+ createReleaseConfig.provider === 'github'):
113
+ // If remote releases are disabled, assume GitHub repo data resolution (but don't attempt to resolve a token) to match existing behavior
114
+ case createReleaseConfig === false: {
115
+ const { GithubRemoteReleaseClient } = await Promise.resolve().then(() => require('./github'));
116
+ const repoData = GithubRemoteReleaseClient.resolveRepoData(createReleaseConfig, remoteName);
117
+ const token = createReleaseConfig && repoData
118
+ ? await GithubRemoteReleaseClient.resolveTokenData(repoData.hostname)
119
+ : null;
120
+ return new GithubRemoteReleaseClient(repoData, createReleaseConfig, token);
121
+ }
122
+ // GitLab
123
+ case typeof createReleaseConfig === 'object' &&
124
+ createReleaseConfig.provider === 'gitlab':
125
+ {
126
+ const { GitLabRemoteReleaseClient } = await Promise.resolve().then(() => require('./gitlab'));
127
+ const repoData = GitLabRemoteReleaseClient.resolveRepoData(createReleaseConfig, remoteName);
128
+ const tokenData = repoData
129
+ ? await GitLabRemoteReleaseClient.resolveTokenData(repoData.hostname)
130
+ : null;
131
+ return new GitLabRemoteReleaseClient(repoData, createReleaseConfig, tokenData);
132
+ }
133
+ default:
134
+ throw new Error(`Unsupported remote release configuration: ${JSON.stringify(createReleaseConfig)}`);
135
+ }
136
+ }
@@ -20,8 +20,8 @@ async function repair(args, extraMigrations = []) {
20
20
  return agg;
21
21
  }, []);
22
22
  const migrations = [...nxMigrations, ...extraMigrations];
23
- const migrationsThatMadeNoChanges = await (0, migrate_1.executeMigrations)(process.cwd(), migrations, args.verbose, false, '');
24
- if (migrationsThatMadeNoChanges.length < migrations.length) {
23
+ const { migrationsWithNoChanges, nextSteps } = await (0, migrate_1.executeMigrations)(process.cwd(), migrations, args.verbose, false, '');
24
+ if (migrationsWithNoChanges.length < migrations.length) {
25
25
  output_1.output.success({
26
26
  title: `Successfully repaired your configuration. This workspace is up to date!`,
27
27
  });
@@ -31,5 +31,11 @@ async function repair(args, extraMigrations = []) {
31
31
  title: `No changes were necessary. This workspace is up to date!`,
32
32
  });
33
33
  }
34
+ if (nextSteps.length) {
35
+ output_1.output.log({
36
+ title: 'Some repairs have additional information, see below.',
37
+ bodyLines: nextSteps.map((line) => ` - ${line}`),
38
+ });
39
+ }
34
40
  });
35
41
  }
@@ -182,7 +182,7 @@ async function getReportData() {
182
182
  nxKeyError = e;
183
183
  }
184
184
  }
185
- let cache = (0, cache_1.dbCacheEnabled)(nxJson)
185
+ let cache = (0, cache_1.dbCacheEnabled)()
186
186
  ? {
187
187
  max: nxJson.maxCacheSize !== undefined
188
188
  ? (0, cache_1.parseMaxCacheSize)(nxJson.maxCacheSize)
@@ -64,7 +64,7 @@ export declare function withOverrides<T extends {
64
64
  }>(args: T, commandLevel?: number): T & {
65
65
  __overrides_unparsed__: string[];
66
66
  };
67
- declare const allOutputStyles: readonly ["dynamic", "static", "stream", "stream-without-prefixes", "compact"];
67
+ declare const allOutputStyles: readonly ["tui", "dynamic", "dynamic-legacy", "static", "stream", "stream-without-prefixes", "compact"];
68
68
  export type OutputStyle = (typeof allOutputStyles)[number];
69
69
  export declare function withOutputStyleOption(yargs: Argv, choices?: ReadonlyArray<OutputStyle>): Argv<{
70
70
  "output-style": string;
@@ -15,6 +15,8 @@ exports.withOutputStyleOption = withOutputStyleOption;
15
15
  exports.withRunOneOptions = withRunOneOptions;
16
16
  exports.parseCSV = parseCSV;
17
17
  exports.readParallelFromArgsAndEnv = readParallelFromArgsAndEnv;
18
+ const nx_json_1 = require("../../config/nx-json");
19
+ const is_tui_enabled_1 = require("../../tasks-runner/is-tui-enabled");
18
20
  exports.defaultYargsParserConfiguration = {
19
21
  'strip-dashed': true,
20
22
  'unknown-options-as-args': true,
@@ -229,23 +231,40 @@ function withOverrides(args, commandLevel = 1) {
229
231
  };
230
232
  }
231
233
  const allOutputStyles = [
234
+ 'tui',
232
235
  'dynamic',
236
+ 'dynamic-legacy',
233
237
  'static',
234
238
  'stream',
235
239
  'stream-without-prefixes',
236
240
  'compact',
237
241
  ];
238
242
  function withOutputStyleOption(yargs, choices = [
243
+ 'dynamic-legacy',
239
244
  'dynamic',
245
+ 'tui',
240
246
  'static',
241
247
  'stream',
242
248
  'stream-without-prefixes',
243
249
  ]) {
244
- return yargs.option('output-style', {
245
- describe: `Defines how Nx emits outputs tasks logs. **dynamic**: use dynamic output life cycle, previous content is overwritten or modified as new outputs are added, display minimal logs by default, always show errors. This output format is recommended on your local development environments. **static**: uses static output life cycle, no previous content is rewritten or modified as new outputs are added. This output format is recommened for CI environments. **stream**: nx by default logs output to an internal output stream, enable this option to stream logs to stdout / stderr. **stream-without-prefixes**: nx prefixes the project name the target is running on, use this option remove the project name prefix from output.`,
250
+ return yargs
251
+ .option('output-style', {
252
+ describe: `Defines how Nx emits outputs tasks logs. **tui**: enables the Nx Terminal UI, recommended for local development environments. **dynamic-legacy**: use dynamic-legacy output life cycle, previous content is overwritten or modified as new outputs are added, display minimal logs by default, always show errors. This output format is recommended for local development environments where tui is not supported. **static**: uses static output life cycle, no previous content is rewritten or modified as new outputs are added. This output format is recommened for CI environments. **stream**: nx by default logs output to an internal output stream, enable this option to stream logs to stdout / stderr. **stream-without-prefixes**: nx prefixes the project name the target is running on, use this option remove the project name prefix from output.`,
246
253
  type: 'string',
247
254
  choices,
248
- });
255
+ })
256
+ .middleware([
257
+ (args) => {
258
+ const useTui = (0, is_tui_enabled_1.shouldUseTui)((0, nx_json_1.readNxJson)(), args);
259
+ if (useTui) {
260
+ // We have to set both of these because `check` runs after the normalization that
261
+ // handles the kebab-case'd args -> camelCase'd args translation.
262
+ args['output-style'] = 'tui';
263
+ args.outputStyle = 'tui';
264
+ }
265
+ process.env.NX_TUI = useTui.toString();
266
+ },
267
+ ]);
249
268
  }
250
269
  function withRunOneOptions(yargs) {
251
270
  const executorShouldShowHelp = !(process.argv[2] === 'run' && process.argv[3] === '--help');
@@ -3,7 +3,8 @@ import { ProjectGraph } from './project-graph';
3
3
  import { Task, TaskGraph } from './task-graph';
4
4
  import { TargetConfiguration, ProjectsConfigurations } from './workspace-json-project-json';
5
5
  import type { NxJsonConfiguration } from './nx-json';
6
- import { Schema } from '../utils/params';
6
+ import type { Schema } from '../utils/params';
7
+ import type { Tree } from '../generators/tree';
7
8
  /**
8
9
  * A callback function that is executed after changes are made to the file system
9
10
  */
@@ -50,6 +51,13 @@ export type PackageJsonUpdates = {
50
51
  requires?: Record<string, string>;
51
52
  };
52
53
  };
54
+ /**
55
+ * Represents a migration that is executed when running `nx migrate`.
56
+ *
57
+ * Returning a string[] from the migration function will be interpreted as
58
+ * a list of next steps to be displayed to the user.
59
+ */
60
+ export type Migration = (tree: Tree) => void | Promise<void> | string[] | Promise<string[]>;
53
61
  export interface MigrationsJsonEntry {
54
62
  version: string;
55
63
  description?: string;
@@ -165,13 +165,20 @@ export interface NxReleaseChangelogConfiguration {
165
165
  * NOTE: if createRelease is set on a group of projects, it will cause the default releaseTagPattern of
166
166
  * "{projectName}@{version}" to be used for those projects, even when versioning everything together.
167
167
  */
168
- createRelease?: false | 'github' | {
168
+ createRelease?: false | 'github' | 'gitlab' | {
169
169
  provider: 'github-enterprise-server';
170
170
  hostname: string;
171
171
  /**
172
172
  * If not set, this will default to `https://${hostname}/api/v3`
173
173
  */
174
174
  apiBaseUrl?: string;
175
+ } | {
176
+ provider: 'gitlab';
177
+ hostname: string;
178
+ /**
179
+ * If not set, this will default to `https://${hostname}/api/v4`
180
+ */
181
+ apiBaseUrl?: string;
175
182
  };
176
183
  /**
177
184
  * This can either be set to a string value that will be written to the changelog file(s)
@@ -590,10 +597,6 @@ export interface NxJsonConfiguration<T = '*' | string[]> {
590
597
  * Configuration for the `nx sync` command.
591
598
  */
592
599
  sync?: NxSyncConfiguration;
593
- /**
594
- * Use the legacy file system cache instead of the db cache
595
- */
596
- useLegacyCache?: boolean;
597
600
  /**
598
601
  * Sets the maximum size of the local cache. Accepts a number followed by a unit (e.g. 100MB). Accepted units are B, KB, MB, and GB.
599
602
  */