diff --git a/.circleci/config.yml b/.circleci/config.yml index 6e4c4a1293ad6..d0a00735a361e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -61,7 +61,7 @@ commands: name: Install Dependencies command: | pnpm install --frozen-lockfile - pnpm playwright install --with-deps firefox webkit chrome + pnpm playwright install --with-deps - save_cache: name: Save pnpm Package Cache key: node-deps-{{ arch }}-v3-{{ checksum "pnpm-lock.yaml" }} @@ -162,7 +162,7 @@ jobs: pids+=($!) (pnpm nx affected --targets=lint,test,build --base=$NX_BASE --head=$NX_HEAD --parallel=3 && - pnpm nx affected --targets=e2e,e2e-ci --base=$NX_BASE --head=$NX_HEAD --parallel=1) & + pnpm nx affected --target=e2e --base=$NX_BASE --head=$NX_HEAD --parallel=1) & pids+=($!) for pid in "${pids[@]}"; do diff --git a/.github/workflows/e2e-matrix.yml b/.github/workflows/e2e-matrix.yml index 09ce3c3bcacf6..c490c53c1d734 100644 --- a/.github/workflows/e2e-matrix.yml +++ b/.github/workflows/e2e-matrix.yml @@ -34,7 +34,7 @@ jobs: name: Cache install (${{ matrix.os }}, node v${{ matrix.node_version }}) steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install PNPM run: | @@ -305,7 +305,7 @@ jobs: name: ${{ matrix.os_name }}/${{ matrix.package_manager }}/${{ matrix.node_version }} ${{ join(matrix.project) }} steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Prepare dir for output run: mkdir -p outputs diff --git a/.github/workflows/e2e-windows.yml b/.github/workflows/e2e-windows.yml index 58ddeb11aeb61..80da55ffff32a 100644 --- a/.github/workflows/e2e-windows.yml +++ b/.github/workflows/e2e-windows.yml @@ -27,7 +27,7 @@ jobs: name: Cache install (node v${{ matrix.node_version }}) steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - uses: pnpm/action-setup@v2 name: Install pnpm @@ -43,7 +43,7 @@ jobs: - name: Cache node_modules id: cache-modules - uses: actions/cache@v3 + uses: actions/cache@v4 with: lookup-only: true path: '**/node_modules' @@ -62,7 +62,7 @@ jobs: - name: Install Cypress if: steps.cache-cypress.outputs.cache-hit != 'true' - run: npx cypress install + run: pnpm cypress install e2e: needs: preinstall @@ -234,7 +234,7 @@ jobs: name: ${{ matrix.project }} (v${{ matrix.node_version }}) steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Prepare dir for output run: mkdir -p outputs diff --git a/.nx/workflows/agents.yaml b/.nx/workflows/agents.yaml index a095562a380e7..cef21cd42454d 100644 --- a/.nx/workflows/agents.yaml +++ b/.nx/workflows/agents.yaml @@ -19,7 +19,6 @@ launch-templates: PATHS: | node_modules ~/.cache/Cypress - ~/.cache/ms-playwright ~/.pnpm-store ~/.sdkman ~/.sdkman/candidates/gradle @@ -36,10 +35,8 @@ launch-templates: script: | pnpm install --frozen-lockfile - - name: Install Browsers - script: | - pnpm exec cypress install - pnpm exec playwright install + - name: Install Cypress + script: pnpm exec cypress install - name: Install Rust script: | diff --git a/CODEOWNERS b/CODEOWNERS index b69e2cc895bd3..e8dd6718c7155 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -11,7 +11,7 @@ rust-toolchain @nrwl/nx-native-reviewers # Docs Site + Graph /docs @nrwl/nx-docs-reviewers /docs/nx-cloud @StalkAltan @rarmatei @nrwl/nx-docs-reviewers -/graph/** @philipjfulcher @FrozenPandaz @bcabanes @MaxKless +/graph/** @philipjfulcher @FrozenPandaz @bcabanes @MaxKless @xiongemi /images @nrwl/nx-docs-reviewers /nx-dev/** @nrwl/nx-docs-reviewers /typedoc-theme @nrwl/nx-docs-reviewers diff --git a/docs/generated/devkit/NxPluginV2.md b/docs/generated/devkit/NxPluginV2.md index 52eb73cf5ffa8..98d4a37fa4c1d 100644 --- a/docs/generated/devkit/NxPluginV2.md +++ b/docs/generated/devkit/NxPluginV2.md @@ -15,5 +15,5 @@ A plugin for Nx which creates nodes and dependencies for the [ProjectGraph](../. | Name | Type | Description | | :-------------------- | :------------------------------------------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------- | | `createDependencies?` | [`CreateDependencies`](../../devkit/documents/CreateDependencies)\<`TOptions`\> | Provides a function to analyze files to create dependencies for the [ProjectGraph](../../devkit/documents/ProjectGraph) | -| `createNodes?` | [`CreateNodes`](../../devkit/documents/CreateNodes) | Provides a file pattern and function that retrieves configuration info from those files. e.g. { '\*_/_.csproj': buildProjectsFromCsProjFile } | +| `createNodes?` | [`CreateNodes`](../../devkit/documents/CreateNodes)\<`TOptions`\> | Provides a file pattern and function that retrieves configuration info from those files. e.g. { '\*_/_.csproj': buildProjectsFromCsProjFile } | | `name` | `string` | - | diff --git a/docs/generated/manifests/ci.json b/docs/generated/manifests/ci.json index db1fa909753f0..d515786c10a96 100644 --- a/docs/generated/manifests/ci.json +++ b/docs/generated/manifests/ci.json @@ -201,7 +201,7 @@ "name": "Set up Nx Cloud On-Premise", "description": "Set up Nx Cloud on machines that you control", "mediaImage": "", - "file": "nx-cloud/private/nx-enterprise-on-prem", + "file": "nx-cloud/features/nx-enterprise-on-prem", "itemList": [], "isExternal": false, "path": "/ci/features/on-premise", @@ -283,7 +283,7 @@ "name": "Set up Nx Cloud On-Premise", "description": "Set up Nx Cloud on machines that you control", "mediaImage": "", - "file": "nx-cloud/private/nx-enterprise-on-prem", + "file": "nx-cloud/features/nx-enterprise-on-prem", "itemList": [], "isExternal": false, "path": "/ci/features/on-premise", @@ -576,103 +576,193 @@ "tags": [] }, { - "id": "on-premise", - "name": "On-Premise", - "description": "Manage an on-premise installation of Nx Cloud", + "id": "enterprise", + "name": "Enterprise", + "description": "Recipes for enterprise accounts", "mediaImage": "", "file": "", "itemList": [ { - "id": "auth-single-admin", - "name": "Authenticate with a Single Admin", - "description": "", + "id": "on-premise", + "name": "On-Premise", + "description": "Manage an on-premise installation of Nx Cloud", "mediaImage": "", - "file": "nx-cloud/private/auth-single-admin", - "itemList": [], + "file": "", + "itemList": [ + { + "id": "auth-single-admin", + "name": "Authenticate with a Single Admin", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/on-premise/auth-single-admin", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/auth-single-admin", + "tags": [] + }, + { + "id": "auth-github", + "name": "Authenticate with GitHub", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/on-premise/auth-github", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/auth-github", + "tags": [] + }, + { + "id": "ami-setup", + "name": "On-Prem VM Setup", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/on-premise/ami-setup", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/ami-setup", + "tags": [] + }, + { + "id": "auth-gitlab", + "name": "Authenticate with GitLab", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/on-premise/auth-gitlab", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/auth-gitlab", + "tags": [] + }, + { + "id": "auth-bitbucket", + "name": "Authenticate with BitBucket", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/on-premise/auth-bitbucket", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/auth-bitbucket", + "tags": [] + }, + { + "id": "auth-saml", + "name": "Authenticate via SAML", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/on-premise/auth-saml", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/auth-saml", + "tags": [] + }, + { + "id": "auth-saml-managed", + "name": "Authenticate via SAML on Managed Version", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/on-premise/auth-saml-managed", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/auth-saml-managed", + "tags": [] + }, + { + "id": "advanced-config", + "name": "Advanced Configuration", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/on-premise/advanced-config", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/advanced-config", + "tags": [] + } + ], "isExternal": false, - "path": "/ci/recipes/on-premise/auth-single-admin", + "path": "/ci/recipes/enterprise/on-premise", "tags": [] }, { - "id": "auth-github", - "name": "Authenticate with GitHub", - "description": "", + "id": "dte", + "name": "Custom Distributed Task Execution", + "description": "Custom DTE on your own CI provider", "mediaImage": "", - "file": "nx-cloud/private/auth-github", - "itemList": [], + "file": "", + "itemList": [ + { + "id": "github-dte", + "name": "GitHub Actions Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/github-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/github-dte", + "tags": [] + }, + { + "id": "circle-ci-dte", + "name": "Circle CI Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/circle-ci-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/circle-ci-dte", + "tags": [] + }, + { + "id": "azure-dte", + "name": "Azure Pipelines Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/azure-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/azure-dte", + "tags": [] + }, + { + "id": "bitbucket-dte", + "name": "Bitbucket Pipelines Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/bitbucket-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/bitbucket-dte", + "tags": [] + }, + { + "id": "gitlab-dte", + "name": "GitLab Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/gitlab-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/gitlab-dte", + "tags": [] + }, + { + "id": "jenkins-dte", + "name": "Jenkins Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/jenkins-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/jenkins-dte", + "tags": [] + } + ], "isExternal": false, - "path": "/ci/recipes/on-premise/auth-github", - "tags": [] - }, - { - "id": "ami-setup", - "name": "On-Prem VM Setup", - "description": "", - "mediaImage": "", - "file": "nx-cloud/private/ami-setup", - "itemList": [], - "isExternal": false, - "path": "/ci/recipes/on-premise/ami-setup", - "tags": [] - }, - { - "id": "auth-gitlab", - "name": "Authenticate with GitLab", - "description": "", - "mediaImage": "", - "file": "nx-cloud/private/auth-gitlab", - "itemList": [], - "isExternal": false, - "path": "/ci/recipes/on-premise/auth-gitlab", - "tags": [] - }, - { - "id": "auth-bitbucket", - "name": "Authenticate with BitBucket", - "description": "", - "mediaImage": "", - "file": "nx-cloud/private/auth-bitbucket", - "itemList": [], - "isExternal": false, - "path": "/ci/recipes/on-premise/auth-bitbucket", - "tags": [] - }, - { - "id": "auth-saml", - "name": "Authenticate via SAML", - "description": "", - "mediaImage": "", - "file": "nx-cloud/private/auth-saml", - "itemList": [], - "isExternal": false, - "path": "/ci/recipes/on-premise/auth-saml", - "tags": [] - }, - { - "id": "auth-saml-managed", - "name": "Authenticate via SAML on Managed Version", - "description": "", - "mediaImage": "", - "file": "nx-cloud/private/auth-saml-managed", - "itemList": [], - "isExternal": false, - "path": "/ci/recipes/on-premise/auth-saml-managed", - "tags": [] - }, - { - "id": "advanced-config", - "name": "Advanced Configuration", - "description": "", - "mediaImage": "", - "file": "nx-cloud/private/advanced-config", - "itemList": [], - "isExternal": false, - "path": "/ci/recipes/on-premise/advanced-config", + "path": "/ci/recipes/enterprise/dte", "tags": [] } ], "isExternal": false, - "path": "/ci/recipes/on-premise", + "path": "/ci/recipes/enterprise", "tags": [] }, { @@ -1059,7 +1149,197 @@ "path": "/ci/recipes/source-control-integration/gitlab", "tags": [] }, - "/ci/recipes/on-premise": { + "/ci/recipes/enterprise": { + "id": "enterprise", + "name": "Enterprise", + "description": "Recipes for enterprise accounts", + "mediaImage": "", + "file": "", + "itemList": [ + { + "id": "on-premise", + "name": "On-Premise", + "description": "Manage an on-premise installation of Nx Cloud", + "mediaImage": "", + "file": "", + "itemList": [ + { + "id": "auth-single-admin", + "name": "Authenticate with a Single Admin", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/on-premise/auth-single-admin", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/auth-single-admin", + "tags": [] + }, + { + "id": "auth-github", + "name": "Authenticate with GitHub", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/on-premise/auth-github", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/auth-github", + "tags": [] + }, + { + "id": "ami-setup", + "name": "On-Prem VM Setup", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/on-premise/ami-setup", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/ami-setup", + "tags": [] + }, + { + "id": "auth-gitlab", + "name": "Authenticate with GitLab", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/on-premise/auth-gitlab", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/auth-gitlab", + "tags": [] + }, + { + "id": "auth-bitbucket", + "name": "Authenticate with BitBucket", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/on-premise/auth-bitbucket", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/auth-bitbucket", + "tags": [] + }, + { + "id": "auth-saml", + "name": "Authenticate via SAML", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/on-premise/auth-saml", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/auth-saml", + "tags": [] + }, + { + "id": "auth-saml-managed", + "name": "Authenticate via SAML on Managed Version", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/on-premise/auth-saml-managed", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/auth-saml-managed", + "tags": [] + }, + { + "id": "advanced-config", + "name": "Advanced Configuration", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/on-premise/advanced-config", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/advanced-config", + "tags": [] + } + ], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise", + "tags": [] + }, + { + "id": "dte", + "name": "Custom Distributed Task Execution", + "description": "Custom DTE on your own CI provider", + "mediaImage": "", + "file": "", + "itemList": [ + { + "id": "github-dte", + "name": "GitHub Actions Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/github-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/github-dte", + "tags": [] + }, + { + "id": "circle-ci-dte", + "name": "Circle CI Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/circle-ci-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/circle-ci-dte", + "tags": [] + }, + { + "id": "azure-dte", + "name": "Azure Pipelines Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/azure-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/azure-dte", + "tags": [] + }, + { + "id": "bitbucket-dte", + "name": "Bitbucket Pipelines Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/bitbucket-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/bitbucket-dte", + "tags": [] + }, + { + "id": "gitlab-dte", + "name": "GitLab Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/gitlab-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/gitlab-dte", + "tags": [] + }, + { + "id": "jenkins-dte", + "name": "Jenkins Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/jenkins-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/jenkins-dte", + "tags": [] + } + ], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte", + "tags": [] + } + ], + "isExternal": false, + "path": "/ci/recipes/enterprise", + "tags": [] + }, + "/ci/recipes/enterprise/on-premise": { "id": "on-premise", "name": "On-Premise", "description": "Manage an on-premise installation of Nx Cloud", @@ -1071,10 +1351,10 @@ "name": "Authenticate with a Single Admin", "description": "", "mediaImage": "", - "file": "nx-cloud/private/auth-single-admin", + "file": "nx-cloud/enterprise/on-premise/auth-single-admin", "itemList": [], "isExternal": false, - "path": "/ci/recipes/on-premise/auth-single-admin", + "path": "/ci/recipes/enterprise/on-premise/auth-single-admin", "tags": [] }, { @@ -1082,10 +1362,10 @@ "name": "Authenticate with GitHub", "description": "", "mediaImage": "", - "file": "nx-cloud/private/auth-github", + "file": "nx-cloud/enterprise/on-premise/auth-github", "itemList": [], "isExternal": false, - "path": "/ci/recipes/on-premise/auth-github", + "path": "/ci/recipes/enterprise/on-premise/auth-github", "tags": [] }, { @@ -1093,10 +1373,10 @@ "name": "On-Prem VM Setup", "description": "", "mediaImage": "", - "file": "nx-cloud/private/ami-setup", + "file": "nx-cloud/enterprise/on-premise/ami-setup", "itemList": [], "isExternal": false, - "path": "/ci/recipes/on-premise/ami-setup", + "path": "/ci/recipes/enterprise/on-premise/ami-setup", "tags": [] }, { @@ -1104,10 +1384,10 @@ "name": "Authenticate with GitLab", "description": "", "mediaImage": "", - "file": "nx-cloud/private/auth-gitlab", + "file": "nx-cloud/enterprise/on-premise/auth-gitlab", "itemList": [], "isExternal": false, - "path": "/ci/recipes/on-premise/auth-gitlab", + "path": "/ci/recipes/enterprise/on-premise/auth-gitlab", "tags": [] }, { @@ -1115,10 +1395,10 @@ "name": "Authenticate with BitBucket", "description": "", "mediaImage": "", - "file": "nx-cloud/private/auth-bitbucket", + "file": "nx-cloud/enterprise/on-premise/auth-bitbucket", "itemList": [], "isExternal": false, - "path": "/ci/recipes/on-premise/auth-bitbucket", + "path": "/ci/recipes/enterprise/on-premise/auth-bitbucket", "tags": [] }, { @@ -1126,10 +1406,10 @@ "name": "Authenticate via SAML", "description": "", "mediaImage": "", - "file": "nx-cloud/private/auth-saml", + "file": "nx-cloud/enterprise/on-premise/auth-saml", "itemList": [], "isExternal": false, - "path": "/ci/recipes/on-premise/auth-saml", + "path": "/ci/recipes/enterprise/on-premise/auth-saml", "tags": [] }, { @@ -1137,10 +1417,10 @@ "name": "Authenticate via SAML on Managed Version", "description": "", "mediaImage": "", - "file": "nx-cloud/private/auth-saml-managed", + "file": "nx-cloud/enterprise/on-premise/auth-saml-managed", "itemList": [], "isExternal": false, - "path": "/ci/recipes/on-premise/auth-saml-managed", + "path": "/ci/recipes/enterprise/on-premise/auth-saml-managed", "tags": [] }, { @@ -1148,103 +1428,247 @@ "name": "Advanced Configuration", "description": "", "mediaImage": "", - "file": "nx-cloud/private/advanced-config", + "file": "nx-cloud/enterprise/on-premise/advanced-config", "itemList": [], "isExternal": false, - "path": "/ci/recipes/on-premise/advanced-config", + "path": "/ci/recipes/enterprise/on-premise/advanced-config", "tags": [] } ], "isExternal": false, - "path": "/ci/recipes/on-premise", + "path": "/ci/recipes/enterprise/on-premise", "tags": [] }, - "/ci/recipes/on-premise/auth-single-admin": { + "/ci/recipes/enterprise/on-premise/auth-single-admin": { "id": "auth-single-admin", "name": "Authenticate with a Single Admin", "description": "", "mediaImage": "", - "file": "nx-cloud/private/auth-single-admin", + "file": "nx-cloud/enterprise/on-premise/auth-single-admin", "itemList": [], "isExternal": false, - "path": "/ci/recipes/on-premise/auth-single-admin", + "path": "/ci/recipes/enterprise/on-premise/auth-single-admin", "tags": [] }, - "/ci/recipes/on-premise/auth-github": { + "/ci/recipes/enterprise/on-premise/auth-github": { "id": "auth-github", "name": "Authenticate with GitHub", "description": "", "mediaImage": "", - "file": "nx-cloud/private/auth-github", + "file": "nx-cloud/enterprise/on-premise/auth-github", "itemList": [], "isExternal": false, - "path": "/ci/recipes/on-premise/auth-github", + "path": "/ci/recipes/enterprise/on-premise/auth-github", "tags": [] }, - "/ci/recipes/on-premise/ami-setup": { + "/ci/recipes/enterprise/on-premise/ami-setup": { "id": "ami-setup", "name": "On-Prem VM Setup", "description": "", "mediaImage": "", - "file": "nx-cloud/private/ami-setup", + "file": "nx-cloud/enterprise/on-premise/ami-setup", "itemList": [], "isExternal": false, - "path": "/ci/recipes/on-premise/ami-setup", + "path": "/ci/recipes/enterprise/on-premise/ami-setup", "tags": [] }, - "/ci/recipes/on-premise/auth-gitlab": { + "/ci/recipes/enterprise/on-premise/auth-gitlab": { "id": "auth-gitlab", "name": "Authenticate with GitLab", "description": "", "mediaImage": "", - "file": "nx-cloud/private/auth-gitlab", + "file": "nx-cloud/enterprise/on-premise/auth-gitlab", "itemList": [], "isExternal": false, - "path": "/ci/recipes/on-premise/auth-gitlab", + "path": "/ci/recipes/enterprise/on-premise/auth-gitlab", "tags": [] }, - "/ci/recipes/on-premise/auth-bitbucket": { + "/ci/recipes/enterprise/on-premise/auth-bitbucket": { "id": "auth-bitbucket", "name": "Authenticate with BitBucket", "description": "", "mediaImage": "", - "file": "nx-cloud/private/auth-bitbucket", + "file": "nx-cloud/enterprise/on-premise/auth-bitbucket", "itemList": [], "isExternal": false, - "path": "/ci/recipes/on-premise/auth-bitbucket", + "path": "/ci/recipes/enterprise/on-premise/auth-bitbucket", "tags": [] }, - "/ci/recipes/on-premise/auth-saml": { + "/ci/recipes/enterprise/on-premise/auth-saml": { "id": "auth-saml", "name": "Authenticate via SAML", "description": "", "mediaImage": "", - "file": "nx-cloud/private/auth-saml", + "file": "nx-cloud/enterprise/on-premise/auth-saml", "itemList": [], "isExternal": false, - "path": "/ci/recipes/on-premise/auth-saml", + "path": "/ci/recipes/enterprise/on-premise/auth-saml", "tags": [] }, - "/ci/recipes/on-premise/auth-saml-managed": { + "/ci/recipes/enterprise/on-premise/auth-saml-managed": { "id": "auth-saml-managed", "name": "Authenticate via SAML on Managed Version", "description": "", "mediaImage": "", - "file": "nx-cloud/private/auth-saml-managed", + "file": "nx-cloud/enterprise/on-premise/auth-saml-managed", "itemList": [], "isExternal": false, - "path": "/ci/recipes/on-premise/auth-saml-managed", + "path": "/ci/recipes/enterprise/on-premise/auth-saml-managed", "tags": [] }, - "/ci/recipes/on-premise/advanced-config": { + "/ci/recipes/enterprise/on-premise/advanced-config": { "id": "advanced-config", "name": "Advanced Configuration", "description": "", "mediaImage": "", - "file": "nx-cloud/private/advanced-config", + "file": "nx-cloud/enterprise/on-premise/advanced-config", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/on-premise/advanced-config", + "tags": [] + }, + "/ci/recipes/enterprise/dte": { + "id": "dte", + "name": "Custom Distributed Task Execution", + "description": "Custom DTE on your own CI provider", + "mediaImage": "", + "file": "", + "itemList": [ + { + "id": "github-dte", + "name": "GitHub Actions Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/github-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/github-dte", + "tags": [] + }, + { + "id": "circle-ci-dte", + "name": "Circle CI Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/circle-ci-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/circle-ci-dte", + "tags": [] + }, + { + "id": "azure-dte", + "name": "Azure Pipelines Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/azure-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/azure-dte", + "tags": [] + }, + { + "id": "bitbucket-dte", + "name": "Bitbucket Pipelines Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/bitbucket-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/bitbucket-dte", + "tags": [] + }, + { + "id": "gitlab-dte", + "name": "GitLab Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/gitlab-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/gitlab-dte", + "tags": [] + }, + { + "id": "jenkins-dte", + "name": "Jenkins Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/jenkins-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/jenkins-dte", + "tags": [] + } + ], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte", + "tags": [] + }, + "/ci/recipes/enterprise/dte/github-dte": { + "id": "github-dte", + "name": "GitHub Actions Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/github-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/github-dte", + "tags": [] + }, + "/ci/recipes/enterprise/dte/circle-ci-dte": { + "id": "circle-ci-dte", + "name": "Circle CI Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/circle-ci-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/circle-ci-dte", + "tags": [] + }, + "/ci/recipes/enterprise/dte/azure-dte": { + "id": "azure-dte", + "name": "Azure Pipelines Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/azure-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/azure-dte", + "tags": [] + }, + "/ci/recipes/enterprise/dte/bitbucket-dte": { + "id": "bitbucket-dte", + "name": "Bitbucket Pipelines Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/bitbucket-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/bitbucket-dte", + "tags": [] + }, + "/ci/recipes/enterprise/dte/gitlab-dte": { + "id": "gitlab-dte", + "name": "GitLab Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/gitlab-dte", + "itemList": [], + "isExternal": false, + "path": "/ci/recipes/enterprise/dte/gitlab-dte", + "tags": [] + }, + "/ci/recipes/enterprise/dte/jenkins-dte": { + "id": "jenkins-dte", + "name": "Jenkins Custom DTE", + "description": "", + "mediaImage": "", + "file": "nx-cloud/enterprise/dte/jenkins-dte", "itemList": [], "isExternal": false, - "path": "/ci/recipes/on-premise/advanced-config", + "path": "/ci/recipes/enterprise/dte/jenkins-dte", "tags": [] }, "/ci/recipes/troubleshooting": { diff --git a/docs/generated/manifests/menus.json b/docs/generated/manifests/menus.json index 2c3510534de0c..a12ab7f9385ac 100644 --- a/docs/generated/manifests/menus.json +++ b/docs/generated/manifests/menus.json @@ -2323,6 +2323,14 @@ "isExternal": false, "children": [], "disableCollapsible": false + }, + { + "name": "Update Your Local Registry Setup to use Nx Release", + "path": "/recipes/nx-release/update-local-registry-setup", + "id": "update-local-registry-setup", + "isExternal": false, + "children": [], + "disableCollapsible": false } ], "disableCollapsible": false @@ -4147,6 +4155,14 @@ "isExternal": false, "children": [], "disableCollapsible": false + }, + { + "name": "Update Your Local Registry Setup to use Nx Release", + "path": "/recipes/nx-release/update-local-registry-setup", + "id": "update-local-registry-setup", + "isExternal": false, + "children": [], + "disableCollapsible": false } ], "disableCollapsible": false @@ -4199,6 +4215,14 @@ "children": [], "disableCollapsible": false }, + { + "name": "Update Your Local Registry Setup to use Nx Release", + "path": "/recipes/nx-release/update-local-registry-setup", + "id": "update-local-registry-setup", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Other", "path": "/recipes/other", @@ -6022,73 +6046,139 @@ "disableCollapsible": false }, { - "name": "On-Premise", - "path": "/ci/recipes/on-premise", - "id": "on-premise", + "name": "Enterprise", + "path": "/ci/recipes/enterprise", + "id": "enterprise", "isExternal": false, "children": [ { - "name": "Authenticate with a Single Admin", - "path": "/ci/recipes/on-premise/auth-single-admin", - "id": "auth-single-admin", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "Authenticate with GitHub", - "path": "/ci/recipes/on-premise/auth-github", - "id": "auth-github", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "On-Prem VM Setup", - "path": "/ci/recipes/on-premise/ami-setup", - "id": "ami-setup", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "Authenticate with GitLab", - "path": "/ci/recipes/on-premise/auth-gitlab", - "id": "auth-gitlab", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "Authenticate with BitBucket", - "path": "/ci/recipes/on-premise/auth-bitbucket", - "id": "auth-bitbucket", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "Authenticate via SAML", - "path": "/ci/recipes/on-premise/auth-saml", - "id": "auth-saml", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "Authenticate via SAML on Managed Version", - "path": "/ci/recipes/on-premise/auth-saml-managed", - "id": "auth-saml-managed", + "name": "On-Premise", + "path": "/ci/recipes/enterprise/on-premise", + "id": "on-premise", "isExternal": false, - "children": [], + "children": [ + { + "name": "Authenticate with a Single Admin", + "path": "/ci/recipes/enterprise/on-premise/auth-single-admin", + "id": "auth-single-admin", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Authenticate with GitHub", + "path": "/ci/recipes/enterprise/on-premise/auth-github", + "id": "auth-github", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "On-Prem VM Setup", + "path": "/ci/recipes/enterprise/on-premise/ami-setup", + "id": "ami-setup", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Authenticate with GitLab", + "path": "/ci/recipes/enterprise/on-premise/auth-gitlab", + "id": "auth-gitlab", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Authenticate with BitBucket", + "path": "/ci/recipes/enterprise/on-premise/auth-bitbucket", + "id": "auth-bitbucket", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Authenticate via SAML", + "path": "/ci/recipes/enterprise/on-premise/auth-saml", + "id": "auth-saml", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Authenticate via SAML on Managed Version", + "path": "/ci/recipes/enterprise/on-premise/auth-saml-managed", + "id": "auth-saml-managed", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Advanced Configuration", + "path": "/ci/recipes/enterprise/on-premise/advanced-config", + "id": "advanced-config", + "isExternal": false, + "children": [], + "disableCollapsible": false + } + ], "disableCollapsible": false }, { - "name": "Advanced Configuration", - "path": "/ci/recipes/on-premise/advanced-config", - "id": "advanced-config", + "name": "Custom Distributed Task Execution", + "path": "/ci/recipes/enterprise/dte", + "id": "dte", "isExternal": false, - "children": [], + "children": [ + { + "name": "GitHub Actions Custom DTE", + "path": "/ci/recipes/enterprise/dte/github-dte", + "id": "github-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Circle CI Custom DTE", + "path": "/ci/recipes/enterprise/dte/circle-ci-dte", + "id": "circle-ci-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Azure Pipelines Custom DTE", + "path": "/ci/recipes/enterprise/dte/azure-dte", + "id": "azure-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Bitbucket Pipelines Custom DTE", + "path": "/ci/recipes/enterprise/dte/bitbucket-dte", + "id": "bitbucket-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "GitLab Custom DTE", + "path": "/ci/recipes/enterprise/dte/gitlab-dte", + "id": "gitlab-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Jenkins Custom DTE", + "path": "/ci/recipes/enterprise/dte/jenkins-dte", + "id": "jenkins-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + } + ], "disableCollapsible": false } ], @@ -6374,15 +6464,154 @@ "children": [], "disableCollapsible": false }, + { + "name": "Enterprise", + "path": "/ci/recipes/enterprise", + "id": "enterprise", + "isExternal": false, + "children": [ + { + "name": "On-Premise", + "path": "/ci/recipes/enterprise/on-premise", + "id": "on-premise", + "isExternal": false, + "children": [ + { + "name": "Authenticate with a Single Admin", + "path": "/ci/recipes/enterprise/on-premise/auth-single-admin", + "id": "auth-single-admin", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Authenticate with GitHub", + "path": "/ci/recipes/enterprise/on-premise/auth-github", + "id": "auth-github", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "On-Prem VM Setup", + "path": "/ci/recipes/enterprise/on-premise/ami-setup", + "id": "ami-setup", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Authenticate with GitLab", + "path": "/ci/recipes/enterprise/on-premise/auth-gitlab", + "id": "auth-gitlab", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Authenticate with BitBucket", + "path": "/ci/recipes/enterprise/on-premise/auth-bitbucket", + "id": "auth-bitbucket", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Authenticate via SAML", + "path": "/ci/recipes/enterprise/on-premise/auth-saml", + "id": "auth-saml", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Authenticate via SAML on Managed Version", + "path": "/ci/recipes/enterprise/on-premise/auth-saml-managed", + "id": "auth-saml-managed", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Advanced Configuration", + "path": "/ci/recipes/enterprise/on-premise/advanced-config", + "id": "advanced-config", + "isExternal": false, + "children": [], + "disableCollapsible": false + } + ], + "disableCollapsible": false + }, + { + "name": "Custom Distributed Task Execution", + "path": "/ci/recipes/enterprise/dte", + "id": "dte", + "isExternal": false, + "children": [ + { + "name": "GitHub Actions Custom DTE", + "path": "/ci/recipes/enterprise/dte/github-dte", + "id": "github-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Circle CI Custom DTE", + "path": "/ci/recipes/enterprise/dte/circle-ci-dte", + "id": "circle-ci-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Azure Pipelines Custom DTE", + "path": "/ci/recipes/enterprise/dte/azure-dte", + "id": "azure-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Bitbucket Pipelines Custom DTE", + "path": "/ci/recipes/enterprise/dte/bitbucket-dte", + "id": "bitbucket-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "GitLab Custom DTE", + "path": "/ci/recipes/enterprise/dte/gitlab-dte", + "id": "gitlab-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Jenkins Custom DTE", + "path": "/ci/recipes/enterprise/dte/jenkins-dte", + "id": "jenkins-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + } + ], + "disableCollapsible": false + } + ], + "disableCollapsible": false + }, { "name": "On-Premise", - "path": "/ci/recipes/on-premise", + "path": "/ci/recipes/enterprise/on-premise", "id": "on-premise", "isExternal": false, "children": [ { "name": "Authenticate with a Single Admin", - "path": "/ci/recipes/on-premise/auth-single-admin", + "path": "/ci/recipes/enterprise/on-premise/auth-single-admin", "id": "auth-single-admin", "isExternal": false, "children": [], @@ -6390,7 +6619,7 @@ }, { "name": "Authenticate with GitHub", - "path": "/ci/recipes/on-premise/auth-github", + "path": "/ci/recipes/enterprise/on-premise/auth-github", "id": "auth-github", "isExternal": false, "children": [], @@ -6398,7 +6627,7 @@ }, { "name": "On-Prem VM Setup", - "path": "/ci/recipes/on-premise/ami-setup", + "path": "/ci/recipes/enterprise/on-premise/ami-setup", "id": "ami-setup", "isExternal": false, "children": [], @@ -6406,7 +6635,7 @@ }, { "name": "Authenticate with GitLab", - "path": "/ci/recipes/on-premise/auth-gitlab", + "path": "/ci/recipes/enterprise/on-premise/auth-gitlab", "id": "auth-gitlab", "isExternal": false, "children": [], @@ -6414,7 +6643,7 @@ }, { "name": "Authenticate with BitBucket", - "path": "/ci/recipes/on-premise/auth-bitbucket", + "path": "/ci/recipes/enterprise/on-premise/auth-bitbucket", "id": "auth-bitbucket", "isExternal": false, "children": [], @@ -6422,7 +6651,7 @@ }, { "name": "Authenticate via SAML", - "path": "/ci/recipes/on-premise/auth-saml", + "path": "/ci/recipes/enterprise/on-premise/auth-saml", "id": "auth-saml", "isExternal": false, "children": [], @@ -6430,7 +6659,7 @@ }, { "name": "Authenticate via SAML on Managed Version", - "path": "/ci/recipes/on-premise/auth-saml-managed", + "path": "/ci/recipes/enterprise/on-premise/auth-saml-managed", "id": "auth-saml-managed", "isExternal": false, "children": [], @@ -6438,7 +6667,7 @@ }, { "name": "Advanced Configuration", - "path": "/ci/recipes/on-premise/advanced-config", + "path": "/ci/recipes/enterprise/on-premise/advanced-config", "id": "advanced-config", "isExternal": false, "children": [], @@ -6449,7 +6678,7 @@ }, { "name": "Authenticate with a Single Admin", - "path": "/ci/recipes/on-premise/auth-single-admin", + "path": "/ci/recipes/enterprise/on-premise/auth-single-admin", "id": "auth-single-admin", "isExternal": false, "children": [], @@ -6457,7 +6686,7 @@ }, { "name": "Authenticate with GitHub", - "path": "/ci/recipes/on-premise/auth-github", + "path": "/ci/recipes/enterprise/on-premise/auth-github", "id": "auth-github", "isExternal": false, "children": [], @@ -6465,7 +6694,7 @@ }, { "name": "On-Prem VM Setup", - "path": "/ci/recipes/on-premise/ami-setup", + "path": "/ci/recipes/enterprise/on-premise/ami-setup", "id": "ami-setup", "isExternal": false, "children": [], @@ -6473,7 +6702,7 @@ }, { "name": "Authenticate with GitLab", - "path": "/ci/recipes/on-premise/auth-gitlab", + "path": "/ci/recipes/enterprise/on-premise/auth-gitlab", "id": "auth-gitlab", "isExternal": false, "children": [], @@ -6481,7 +6710,7 @@ }, { "name": "Authenticate with BitBucket", - "path": "/ci/recipes/on-premise/auth-bitbucket", + "path": "/ci/recipes/enterprise/on-premise/auth-bitbucket", "id": "auth-bitbucket", "isExternal": false, "children": [], @@ -6489,7 +6718,7 @@ }, { "name": "Authenticate via SAML", - "path": "/ci/recipes/on-premise/auth-saml", + "path": "/ci/recipes/enterprise/on-premise/auth-saml", "id": "auth-saml", "isExternal": false, "children": [], @@ -6497,7 +6726,7 @@ }, { "name": "Authenticate via SAML on Managed Version", - "path": "/ci/recipes/on-premise/auth-saml-managed", + "path": "/ci/recipes/enterprise/on-premise/auth-saml-managed", "id": "auth-saml-managed", "isExternal": false, "children": [], @@ -6505,12 +6734,117 @@ }, { "name": "Advanced Configuration", - "path": "/ci/recipes/on-premise/advanced-config", + "path": "/ci/recipes/enterprise/on-premise/advanced-config", "id": "advanced-config", "isExternal": false, "children": [], "disableCollapsible": false }, + { + "name": "Custom Distributed Task Execution", + "path": "/ci/recipes/enterprise/dte", + "id": "dte", + "isExternal": false, + "children": [ + { + "name": "GitHub Actions Custom DTE", + "path": "/ci/recipes/enterprise/dte/github-dte", + "id": "github-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Circle CI Custom DTE", + "path": "/ci/recipes/enterprise/dte/circle-ci-dte", + "id": "circle-ci-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Azure Pipelines Custom DTE", + "path": "/ci/recipes/enterprise/dte/azure-dte", + "id": "azure-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Bitbucket Pipelines Custom DTE", + "path": "/ci/recipes/enterprise/dte/bitbucket-dte", + "id": "bitbucket-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "GitLab Custom DTE", + "path": "/ci/recipes/enterprise/dte/gitlab-dte", + "id": "gitlab-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Jenkins Custom DTE", + "path": "/ci/recipes/enterprise/dte/jenkins-dte", + "id": "jenkins-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + } + ], + "disableCollapsible": false + }, + { + "name": "GitHub Actions Custom DTE", + "path": "/ci/recipes/enterprise/dte/github-dte", + "id": "github-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Circle CI Custom DTE", + "path": "/ci/recipes/enterprise/dte/circle-ci-dte", + "id": "circle-ci-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Azure Pipelines Custom DTE", + "path": "/ci/recipes/enterprise/dte/azure-dte", + "id": "azure-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Bitbucket Pipelines Custom DTE", + "path": "/ci/recipes/enterprise/dte/bitbucket-dte", + "id": "bitbucket-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "GitLab Custom DTE", + "path": "/ci/recipes/enterprise/dte/gitlab-dte", + "id": "gitlab-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Jenkins Custom DTE", + "path": "/ci/recipes/enterprise/dte/jenkins-dte", + "id": "jenkins-dte", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Troubleshooting", "path": "/ci/recipes/troubleshooting", diff --git a/docs/generated/manifests/nx.json b/docs/generated/manifests/nx.json index ccce722b176ca..dda34002074c8 100644 --- a/docs/generated/manifests/nx.json +++ b/docs/generated/manifests/nx.json @@ -3177,6 +3177,17 @@ "isExternal": false, "path": "/recipes/nx-release/publish-rust-crates", "tags": ["nx-release"] + }, + { + "id": "update-local-registry-setup", + "name": "Update Your Local Registry Setup to use Nx Release", + "description": "", + "mediaImage": "", + "file": "shared/recipes/nx-release/update-local-registry-setup", + "itemList": [], + "isExternal": false, + "path": "/recipes/nx-release/update-local-registry-setup", + "tags": ["nx-release"] } ], "isExternal": false, @@ -5678,6 +5689,17 @@ "isExternal": false, "path": "/recipes/nx-release/publish-rust-crates", "tags": ["nx-release"] + }, + { + "id": "update-local-registry-setup", + "name": "Update Your Local Registry Setup to use Nx Release", + "description": "", + "mediaImage": "", + "file": "shared/recipes/nx-release/update-local-registry-setup", + "itemList": [], + "isExternal": false, + "path": "/recipes/nx-release/update-local-registry-setup", + "tags": ["nx-release"] } ], "isExternal": false, @@ -5750,6 +5772,17 @@ "path": "/recipes/nx-release/publish-rust-crates", "tags": ["nx-release"] }, + "/recipes/nx-release/update-local-registry-setup": { + "id": "update-local-registry-setup", + "name": "Update Your Local Registry Setup to use Nx Release", + "description": "", + "mediaImage": "", + "file": "shared/recipes/nx-release/update-local-registry-setup", + "itemList": [], + "isExternal": false, + "path": "/recipes/nx-release/update-local-registry-setup", + "tags": ["nx-release"] + }, "/recipes/other": { "id": "other", "name": "Other", diff --git a/docs/generated/manifests/tags.json b/docs/generated/manifests/tags.json index ffd6010310d3f..d3e819b89cc59 100644 --- a/docs/generated/manifests/tags.json +++ b/docs/generated/manifests/tags.json @@ -1029,6 +1029,13 @@ "id": "publish-rust-crates", "name": "Publish Rust Crates", "path": "/recipes/nx-release/publish-rust-crates" + }, + { + "description": "", + "file": "shared/recipes/nx-release/update-local-registry-setup", + "id": "update-local-registry-setup", + "name": "Update Your Local Registry Setup to use Nx Release", + "path": "/recipes/nx-release/update-local-registry-setup" } ], "database": [ @@ -1119,7 +1126,7 @@ "on-premise": [ { "description": "Set up Nx Cloud on machines that you control", - "file": "nx-cloud/private/nx-enterprise-on-prem", + "file": "nx-cloud/features/nx-enterprise-on-prem", "id": "on-premise", "name": "Set up Nx Cloud On-Premise", "path": "/ci/features/on-premise" diff --git a/docs/generated/packages/js/generators/library.json b/docs/generated/packages/js/generators/library.json index 68dfd176d6208..779da183bc076 100644 --- a/docs/generated/packages/js/generators/library.json +++ b/docs/generated/packages/js/generators/library.json @@ -89,7 +89,7 @@ "publishable": { "type": "boolean", "default": false, - "description": "Generate a publishable library.", + "description": "Configure the library ready for use with `nx release` (https://nx.dev/core-features/manage-releases).", "x-priority": "important" }, "importPath": { diff --git a/docs/generated/packages/js/generators/release-version.json b/docs/generated/packages/js/generators/release-version.json index 16f235a9cc234..f58617582f713 100644 --- a/docs/generated/packages/js/generators/release-version.json +++ b/docs/generated/packages/js/generators/release-version.json @@ -50,6 +50,18 @@ "type": "object", "description": "Additional metadata to pass to the current version resolver.", "default": {} + }, + "skipLockFileUpdate": { + "type": "boolean", + "description": "Whether to skip updating the lock file after updating the version." + }, + "installArgs": { + "type": "string", + "description": "Additional arguments to pass to the package manager when updating the lock file with an install command." + }, + "installIgnoreScripts": { + "type": "boolean", + "description": "Whether to ignore install lifecycle scripts when updating the lock file with an install command." } }, "required": ["projects", "projectGraph", "releaseGroup"], diff --git a/docs/map.json b/docs/map.json index d79ab93052639..4cce5071490a3 100644 --- a/docs/map.json +++ b/docs/map.json @@ -1149,6 +1149,12 @@ "id": "publish-rust-crates", "tags": ["nx-release"], "file": "shared/recipes/nx-release/publish-rust-crates" + }, + { + "name": "Update Your Local Registry Setup to use Nx Release", + "id": "update-local-registry-setup", + "tags": ["nx-release"], + "file": "shared/recipes/nx-release/update-local-registry-setup" } ] }, @@ -1715,7 +1721,7 @@ "description": "Set up Nx Cloud on machines that you control", "id": "on-premise", "tags": ["on-premise"], - "file": "nx-cloud/private/nx-enterprise-on-prem" + "file": "nx-cloud/features/nx-enterprise-on-prem" } ] }, @@ -1842,49 +1848,93 @@ ] }, { - "name": "On-Premise", - "id": "on-premise", - "description": "Manage an on-premise installation of Nx Cloud", + "name": "Enterprise", + "id": "enterprise", + "description": "Recipes for enterprise accounts", "itemList": [ { - "name": "Authenticate with a Single Admin", - "id": "auth-single-admin", - "file": "nx-cloud/private/auth-single-admin" - }, - { - "name": "Authenticate with GitHub", - "id": "auth-github", - "file": "nx-cloud/private/auth-github" - }, - { - "name": "On-Prem VM Setup", - "id": "ami-setup", - "file": "nx-cloud/private/ami-setup" - }, - { - "name": "Authenticate with GitLab", - "id": "auth-gitlab", - "file": "nx-cloud/private/auth-gitlab" - }, - { - "name": "Authenticate with BitBucket", - "id": "auth-bitbucket", - "file": "nx-cloud/private/auth-bitbucket" - }, - { - "name": "Authenticate via SAML", - "id": "auth-saml", - "file": "nx-cloud/private/auth-saml" - }, - { - "name": "Authenticate via SAML on Managed Version", - "id": "auth-saml-managed", - "file": "nx-cloud/private/auth-saml-managed" + "name": "On-Premise", + "id": "on-premise", + "description": "Manage an on-premise installation of Nx Cloud", + "itemList": [ + { + "name": "Authenticate with a Single Admin", + "id": "auth-single-admin", + "file": "nx-cloud/enterprise/on-premise/auth-single-admin" + }, + { + "name": "Authenticate with GitHub", + "id": "auth-github", + "file": "nx-cloud/enterprise/on-premise/auth-github" + }, + { + "name": "On-Prem VM Setup", + "id": "ami-setup", + "file": "nx-cloud/enterprise/on-premise/ami-setup" + }, + { + "name": "Authenticate with GitLab", + "id": "auth-gitlab", + "file": "nx-cloud/enterprise/on-premise/auth-gitlab" + }, + { + "name": "Authenticate with BitBucket", + "id": "auth-bitbucket", + "file": "nx-cloud/enterprise/on-premise/auth-bitbucket" + }, + { + "name": "Authenticate via SAML", + "id": "auth-saml", + "file": "nx-cloud/enterprise/on-premise/auth-saml" + }, + { + "name": "Authenticate via SAML on Managed Version", + "id": "auth-saml-managed", + "file": "nx-cloud/enterprise/on-premise/auth-saml-managed" + }, + { + "name": "Advanced Configuration", + "id": "advanced-config", + "file": "nx-cloud/enterprise/on-premise/advanced-config" + } + ] }, { - "name": "Advanced Configuration", - "id": "advanced-config", - "file": "nx-cloud/private/advanced-config" + "name": "Custom Distributed Task Execution", + "id": "dte", + "description": "Custom DTE on your own CI provider", + "itemList": [ + { + "name": "GitHub Actions Custom DTE", + "id": "github-dte", + "file": "nx-cloud/enterprise/dte/github-dte" + }, + { + "name": "Circle CI Custom DTE", + "id": "circle-ci-dte", + "file": "nx-cloud/enterprise/dte/circle-ci-dte" + }, + { + "name": "Azure Pipelines Custom DTE", + "id": "azure-dte", + "file": "nx-cloud/enterprise/dte/azure-dte" + }, + { + "name": "Bitbucket Pipelines Custom DTE", + "id": "bitbucket-dte", + "file": "nx-cloud/enterprise/dte/bitbucket-dte" + }, + { + "name": "GitLab Custom DTE", + "id": "gitlab-dte", + "file": "nx-cloud/enterprise/dte/gitlab-dte" + }, + { + "name": "Jenkins Custom DTE", + "id": "jenkins-dte", + "file": "nx-cloud/enterprise/dte/jenkins-dte" + } + ] } ] }, diff --git a/docs/nx-cloud/enterprise/dte/azure-dte.md b/docs/nx-cloud/enterprise/dte/azure-dte.md new file mode 100644 index 0000000000000..f4d7955fd0391 --- /dev/null +++ b/docs/nx-cloud/enterprise/dte/azure-dte.md @@ -0,0 +1,73 @@ +# Custom Distributed Task Execution on Azure Pipelines + +Using [Nx Agents](/ci/features/distribute-task-execution) is the easiest way to distribute task execution, but it your organization may not be able to use hosted Nx Agents. With an [enterprise license](https://nx.app/enterprise), you can set up distributed task execution on your own CI provider using the recipe below. + +## Run Custom Agents on Azure Pipelines + +Run agents directly on Azure Pipelines with the workflow below: + +```yaml {% fileName="azure-pipelines.yml" %} +trigger: + - main +pr: + - main + +variables: + CI: 'true' + NX_CLOUD_DISTRIBUTED_EXECUTION_AGENT_COUNT: 3 # expected number of agents + ${{ if eq(variables['Build.Reason'], 'PullRequest') }}: + NX_BRANCH: $(System.PullRequest.PullRequestNumber) + TARGET_BRANCH: $[replace(variables['System.PullRequest.TargetBranch'],'refs/heads/','origin/')] + BASE_SHA: $(git merge-base $(TARGET_BRANCH) HEAD) + ${{ if ne(variables['Build.Reason'], 'PullRequest') }}: + NX_BRANCH: $(Build.SourceBranchName) + BASE_SHA: $(git rev-parse HEAD~1) + HEAD_SHA: $(git rev-parse HEAD) + +jobs: + - job: agents + strategy: + parallel: 3 + displayName: Nx Cloud Agent + pool: + vmImage: 'ubuntu-latest' + steps: + - script: npm ci + - script: npx nx-cloud start-agent + + - job: main + displayName: Nx Cloud Main + pool: + vmImage: 'ubuntu-latest' + steps: + # Get last successfull commit from Azure Devops CLI + - displayName: 'Get last successful commit SHA' + condition: ne(variables['Build.Reason'], 'PullRequest') + env: + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + bash: | + LAST_SHA=$(az pipelines build list --branch $(Build.SourceBranchName) --definition-ids $(System.DefinitionId) --result succeeded --top 1 --query "[0].triggerInfo.\"ci.sourceSha\"") + if [ -z "$LAST_SHA" ] + then + echo "Last successful commit not found. Using fallback 'HEAD~1': $BASE_SHA" + else + echo "Last successful commit SHA: $LAST_SHA" + echo "##vso[task.setvariable variable=BASE_SHA]$LAST_SHA" + fi + + - script: git branch --track main origin/main + - script: npm ci + - script: npx nx-cloud start-ci-run --stop-agents-after="e2e-ci" + - script: npx nx-cloud record -- nx format:check --base=$(BASE_SHA) --head=$(HEAD_SHA) + - script: npx nx affected --base=$(BASE_SHA) --head=$(HEAD_SHA) -t lint,test,build,e2e-ci --parallel=2 --configuration=ci +``` + +This configuration is setting up two types of jobs - a main job and three agent jobs. + +The main job tells Nx Cloud to use DTE and then runs normal Nx commands as if this were a single pipeline set up. Once the commands are done, it notifies Nx Cloud to stop the agent jobs. + +The agent jobs set up the repo and then wait for Nx Cloud to assign them tasks. + +{% callout type="warning" title="Two Types of Parallelization" %} +The agent strategy of `parallel: 3` and the `nx affected --parallel=2` flag both parallelize tasks, but in different ways. The way this workflow is written, there will be 3 agents running tasks and each agent will try to run 2 tasks at once. If a particular CI run only has 2 tasks, only one agent will be used. +{% /callout %} diff --git a/docs/nx-cloud/enterprise/dte/bitbucket-dte.md b/docs/nx-cloud/enterprise/dte/bitbucket-dte.md new file mode 100644 index 0000000000000..a3ace765b4a7c --- /dev/null +++ b/docs/nx-cloud/enterprise/dte/bitbucket-dte.md @@ -0,0 +1,52 @@ +# Custom Distributed Task Execution on Bitbucket Pipelines + +Using [Nx Agents](/ci/features/distribute-task-execution) is the easiest way to distribute task execution, but it your organization may not be able to use hosted Nx Agents. With an [enterprise license](https://nx.app/enterprise), you can set up distributed task execution on your own CI provider using the recipe below. + +## Run Custom Agents on Bitbucket Pipelines + +Run agents directly on Bitbucket Pipelines with the workflow below: + +```yaml {% fileName="bitbucket-pipelines.yml" %} +image: node:20 + +clone: + depth: full + +definitions: + steps: + - step: &agent + name: Agent + script: + - export NX_BRANCH=$BITBUCKET_PR_ID + + - npm ci + - npx nx-cloud start-agent + +pipelines: + pull-requests: + '**': + - parallel: + - step: + name: CI + script: + - export NX_BRANCH=$BITBUCKET_PR_ID + - export NX_CLOUD_DISTRIBUTED_EXECUTION_AGENT_COUNT=3 + + - npm ci + - npx nx-cloud start-ci-run --stop-agents-after="e2e-ci" --agent-count=3 + - npx nx-cloud record -- nx format:check + - npx nx affected --target=lint,test,build,e2e-ci --parallel=2 + - step: *agent + - step: *agent + - step: *agent +``` + +This configuration is setting up two types of jobs - a main job and three agent jobs. + +The main job tells Nx Cloud to use DTE and then runs normal Nx commands as if this were a single pipeline set up. Once the commands are done, it notifies Nx Cloud to stop the agent jobs. + +The agent jobs set up the repo and then wait for Nx Cloud to assign them tasks. + +{% callout type="warning" title="Two Types of Parallelization" %} +The agents and the `--parallel` flag both parallelize tasks, but in different ways. The way this workflow is written, there will be 3 agents running tasks and each agent will try to run 2 tasks at once. If a particular CI run only has 2 tasks, only one agent will be used. +{% /callout %} diff --git a/docs/nx-cloud/enterprise/dte/circle-ci-dte.md b/docs/nx-cloud/enterprise/dte/circle-ci-dte.md new file mode 100644 index 0000000000000..c843835117b82 --- /dev/null +++ b/docs/nx-cloud/enterprise/dte/circle-ci-dte.md @@ -0,0 +1,61 @@ +# Custom Distributed Task Execution on Circle CI + +Using [Nx Agents](/ci/features/distribute-task-execution) is the easiest way to distribute task execution, but it your organization may not be able to use hosted Nx Agents. With an [enterprise license](https://nx.app/enterprise), you can set up distributed task execution on your own CI provider using the recipe below. + +## Run Custom Agents on Circle CI + +Run agents directly on Circle CI with the workflow below: + +```yaml {% fileName=".circleci/config.yml" %} +version: 2.1 +orbs: + nx: nrwl/nx@1.5.1 +jobs: + main: + docker: + - image: cimg/node:lts-browsers + environment: + NX_CLOUD_DISTRIBUTED_EXECUTION_AGENT_COUNT: 3 # expected number of agents + steps: + - checkout + - run: npm ci + - nx/set-shas + + # Tell Nx Cloud to use DTE and stop agents when the e2e-ci tasks are done + - run: npx nx-cloud start-ci-run --stop-agents-after=e2e-ci + # Send logs to Nx Cloud for any CLI command + - run: npx nx-cloud record -- nx format:check + # Lint, test, build and run e2e on agent jobs for everything affected by a change + - run: npx nx affected --base=$NX_BASE --head=$NX_HEAD -t lint,test,build,e2e-ci --parallel=2 --configuration=ci + agent: + docker: + - image: cimg/node:lts-browsers + parameters: + ordinal: + type: integer + steps: + - checkout + - run: npm ci + # Wait for instructions from Nx Cloud + - run: + command: npx nx-cloud start-agent + no_output_timeout: 60m +workflows: + build: + jobs: + - agent: + matrix: + parameters: + ordinal: [1, 2, 3] + - main +``` + +This configuration is setting up two types of jobs - a main job and three agent jobs. + +The main job tells Nx Cloud to use DTE and then runs normal Nx commands as if this were a single pipeline set up. Once the commands are done, it notifies Nx Cloud to stop the agent jobs. + +The agent jobs set up the repo and then wait for Nx Cloud to assign them tasks. + +{% callout type="warning" title="Two Types of Parallelization" %} +The `ordinal: [1, 2, 3]` line and the `--parallel` flag both parallelize tasks, but in different ways. The way this workflow is written, there will be 3 agents running tasks and each agent will try to run 2 tasks at once. If a particular CI run only has 2 tasks, only one agent will be used. +{% /callout %} diff --git a/docs/nx-cloud/enterprise/dte/github-dte.md b/docs/nx-cloud/enterprise/dte/github-dte.md new file mode 100644 index 0000000000000..00f4c7d678e6b --- /dev/null +++ b/docs/nx-cloud/enterprise/dte/github-dte.md @@ -0,0 +1,130 @@ +# Custom Distributed Task Execution on Github Actions + +Using [Nx Agents](/ci/features/distribute-task-execution) is the easiest way to distribute task execution, but it your organization may not be able to use hosted Nx Agents. With an [enterprise license](https://nx.app/enterprise), you can set up distributed task execution on your own CI provider using the recipe below. + +## Run Custom Agents on GitHub + +Our [reusable GitHub workflow](https://github.com/nrwl/ci) represents a good set of defaults that works for a large number of our users. However, reusable GitHub workflows come with their [limitations](https://docs.github.com/en/actions/using-workflows/reusing-workflows). + +If the reusable workflow above doesn't satisfy your needs you should create a custom workflow. If you were to rewrite the reusable workflow yourself, it would look something like this: + +```yaml {% fileName=".github/workflows/ci.yml" %} +name: CI +on: + push: + branches: + - main + pull_request: + +# Needed for nx-set-shas when run on the main branch +permissions: + actions: read + contents: read + +env: + NX_CLOUD_DISTRIBUTED_EXECUTION: true # this enables DTE + NX_CLOUD_DISTRIBUTED_EXECUTION_AGENT_COUNT: 3 # expected number of agents + NX_BRANCH: ${{ github.event.number || github.ref_name }} + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} # this is needed if our pipeline publishes to npm + +jobs: + main: + name: Nx Cloud - Main Job + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + name: Checkout [Pull Request] + if: ${{ github.event_name == 'pull_request' }} + with: + # By default, PRs will be checked-out based on the Merge Commit, but we want the actual branch HEAD. + ref: ${{ github.event.pull_request.head.sha }} + # We need to fetch all branches and commits so that Nx affected has a base to compare against. + fetch-depth: 0 + + - uses: actions/checkout@v4 + name: Checkout [Default Branch] + if: ${{ github.event_name != 'pull_request' }} + with: + # We need to fetch all branches and commits so that Nx affected has a base to compare against. + fetch-depth: 0 + + # Set node/npm/yarn versions using volta + - uses: volta-cli/action@v4 + with: + package-json-path: '${{ github.workspace }}/package.json' + + - name: Use the package manager cache if available + uses: actions/setup-node@v3 + with: + node-version: 20 + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Check out the default branch + run: git branch --track main origin/main + + - name: Initialize the Nx Cloud distributed CI run and stop agents when the build tasks are done + run: npx nx-cloud start-ci-run --stop-agents-after=e2e-ci + + - name: Run commands in parallel + run: | + # initialize an array to store process IDs (PIDs) + pids=() + + # function to run commands and store the PID + function run_command() { + local command=$1 + $command & # run the command in the background + pids+=($!) # store the PID of the background process + } + + # list of commands to be run on main has env flag NX_CLOUD_DISTRIBUTED_EXECUTION set to false + run_command "NX_CLOUD_DISTRIBUTED_EXECUTION=false npx nx-cloud record -- nx format:check" + + # list of commands to be run on agents + run_command "npx nx affected -t lint,test,build,e2e-ci --parallel=3" + + # wait for all background processes to finish + for pid in ${pids[*]}; do + if ! wait $pid; then + exit 1 # exit with an error status if any process fails + fi + done + + exit 0 # exits with success status if a all processes complete successfully + + agents: + name: Agent ${{ matrix.agent }} + runs-on: ubuntu-latest + strategy: + matrix: + # Add more agents here as your repository expands + agent: [1, 2, 3] + steps: + - name: Checkout + uses: actions/checkout@v4 + + # Set node/npm/yarn versions using volta + - uses: volta-cli/action@v4 + with: + package-json-path: '${{ github.workspace }}/package.json' + + - name: Use the package manager cache if available + uses: actions/setup-node@v3 + with: + node-version: 20 + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Start Nx Agent ${{ matrix.agent }} + run: npx nx-cloud start-agent + env: + NX_AGENT_NAME: ${{ matrix.agent }} +``` + +There are comments throughout the workflow to help you understand what is happening in each section. diff --git a/docs/nx-cloud/enterprise/dte/gitlab-dte.md b/docs/nx-cloud/enterprise/dte/gitlab-dte.md new file mode 100644 index 0000000000000..7589cb23d0f44 --- /dev/null +++ b/docs/nx-cloud/enterprise/dte/gitlab-dte.md @@ -0,0 +1,77 @@ +# Custom Distributed Task Execution on GitLab + +Using [Nx Agents](/ci/features/distribute-task-execution) is the easiest way to distribute task execution, but it your organization may not be able to use hosted Nx Agents. With an [enterprise license](https://nx.app/enterprise), you can set up distributed task execution on your own CI provider using the recipe below. + +## Run Custom Agents on GitLab + +Run agents directly on GitLab with the workflow below: + +```yaml {% fileName=".gitlab-ci.yml" %} +image: node:18 + +# Creating template for DTE agents +.dte-agent: + interruptible: true + cache: + key: + files: + - yarn.lock + paths: + - '.yarn-cache/' + script: + - yarn install --cache-folder .yarn-cache --prefer-offline --frozen-lockfile + - yarn nx-cloud start-agent + +# Creating template for a job running DTE (orchestrator) +.base-pipeline: + interruptible: true + only: + - main + - merge_requests + cache: + key: + files: + - yarn.lock + paths: + - '.yarn-cache/' + before_script: + - yarn install --cache-folder .yarn-cache --prefer-offline --frozen-lockfile + - NX_HEAD=$CI_COMMIT_SHA + - NX_BASE=${CI_MERGE_REQUEST_DIFF_BASE_SHA:-$CI_COMMIT_BEFORE_SHA} + - NX_CLOUD_DISTRIBUTED_EXECUTION_AGENT_COUNT=3 # expected number of agents + + artifacts: + expire_in: 5 days + paths: + - dist + +# Main job running DTE +nx-dte: + stage: affected + extends: .base-pipeline + script: + - yarn nx-cloud start-ci-run --stop-agents-after=e2e-ci + - yarn nx-cloud record -- nx format:check --base=$NX_BASE --head=$NX_HEAD + - yarn nx affected --base=$NX_BASE --head=$NX_HEAD -t lint,test,build,e2e-ci --parallel=2 + +# Create as many agents as you want +nx-dte-agent1: + extends: .dte-agent + stage: affected +nx-dte-agent2: + extends: .dte-agent + stage: affected +nx-dte-agent3: + extends: .dte-agent + stage: affected +``` + +This configuration is setting up two types of jobs - a main job and three agent jobs. + +The main job tells Nx Cloud to use DTE and then runs normal Nx commands as if this were a single pipeline set up. Once the commands are done, it notifies Nx Cloud to stop the agent jobs. + +The agent jobs set up the repo and then wait for Nx Cloud to assign them tasks. + +{% callout type="warning" title="Two Types of Parallelization" %} +The agents and the `--parallel` flag both parallelize tasks, but in different ways. The way this workflow is written, there will be 3 agents running tasks and each agent will try to run 2 tasks at once. If a particular CI run only has 2 tasks, only one agent will be used. +{% /callout %} diff --git a/docs/nx-cloud/enterprise/dte/jenkins-dte.md b/docs/nx-cloud/enterprise/dte/jenkins-dte.md new file mode 100644 index 0000000000000..ffe587aa92907 --- /dev/null +++ b/docs/nx-cloud/enterprise/dte/jenkins-dte.md @@ -0,0 +1,80 @@ +# Custom Distributed Task Execution on Jenkins + +Using [Nx Agents](/ci/features/distribute-task-execution) is the easiest way to distribute task execution, but it your organization may not be able to use hosted Nx Agents. With an [enterprise license](https://nx.app/enterprise), you can set up distributed task execution on your own CI provider using the recipe below. + +## Distribute Tasks Across Custom Agents on Jenkins + +Run agents directly on Jenkins with the workflow below: + +```groovy +pipeline { + agent none + environment { + NX_BRANCH = env.BRANCH_NAME.replace('PR-', '') + NX_CLOUD_DISTRIBUTED_EXECUTION_AGENT_COUNT = 3 + } + stages { + stage('Pipeline') { + parallel { + stage('Main') { + when { + branch 'main' + } + agent any + steps { + sh "npm ci" + sh "npx nx-cloud start-ci-run --stop-agents-after='e2e-ci'" + sh "npx nx-cloud record -- nx format:check" + sh "npx nx affected --base=HEAD~1 -t lint,test,build,e2e-ci --configuration=ci --parallel=2" + } + } + stage('PR') { + when { + not { branch 'main' } + } + agent any + steps { + sh "npm ci" + sh "npx nx-cloud start-ci-run --stop-agents-after='e2e-ci'" + sh "npx nx-cloud record -- nx format:check" + sh "npx nx affected --base origin/${env.CHANGE_TARGET} -t lint,test,build,e2e-ci --parallel=2 --configuration=ci" + } + } + + # Add as many agent you want + stage('Agent1') { + agent any + steps { + sh "npm ci" + sh "npx nx-cloud start-agent" + } + } + stage('Agent2') { + agent any + steps { + sh "npm ci" + sh "npx nx-cloud start-agent" + } + } + stage('Agent3') { + agent any + steps { + sh "npm ci" + sh "npx nx-cloud start-agent" + } + } + } + } + } +} +``` + +This configuration is setting up two types of jobs - a main job and three agent jobs. + +The main job tells Nx Cloud to use DTE and then runs normal Nx commands as if this were a single pipeline set up. Once the commands are done, it notifies Nx Cloud to stop the agent jobs. + +The agent jobs set up the repo and then wait for Nx Cloud to assign them tasks. + +{% callout type="warning" title="Two Types of Parallelization" %} +The agents and the `--parallel` flag both parallelize tasks, but in different ways. The way this workflow is written, there will be 3 agents running tasks and each agent will try to run 2 tasks at once. If a particular CI run only has 2 tasks, only one agent will be used. +{% /callout %} diff --git a/docs/nx-cloud/private/advanced-config.md b/docs/nx-cloud/enterprise/on-premise/advanced-config.md similarity index 100% rename from docs/nx-cloud/private/advanced-config.md rename to docs/nx-cloud/enterprise/on-premise/advanced-config.md diff --git a/docs/nx-cloud/private/ami-setup.md b/docs/nx-cloud/enterprise/on-premise/ami-setup.md similarity index 93% rename from docs/nx-cloud/private/ami-setup.md rename to docs/nx-cloud/enterprise/on-premise/ami-setup.md index 0a0cb937dd793..6035e6a002377 100644 --- a/docs/nx-cloud/private/ami-setup.md +++ b/docs/nx-cloud/enterprise/on-premise/ami-setup.md @@ -16,7 +16,7 @@ 7. "Launch instance" 8. Wait 10 minutes, then navigate to your instance's IP in the browser. You should see the Nx Cloud dashboard! -![Nx Cloud landing page](/nx-cloud/private/images/nx-cloud-landing.png) +![Nx Cloud landing page](/nx-cloud/enterprise/on-premise/images/nx-cloud-landing.png) ### Your Nx Cloud URL @@ -126,26 +126,26 @@ nxCloudAppURL: 'https://nx-cloud.on.my-domain.ca' # make sure no backslash is at # the filesystem secret: # set your initial admin password for logging into the app - # see here: https://nx.dev/ci/recipes/on-premise/auth-single-admin + # see here: https://nx.dev/ci/recipes/enterprise/on-premise/auth-single-admin adminPassword: 'correcthorsebatterystaple' # If you want to enable GitHub Login, just provide your client id & secret, we handle the rest - # see here: https://nx.dev/ci/recipes/on-premise/auth-github + # see here: https://nx.dev/ci/recipes/enterprise/on-premise/auth-github githubAuthClientId: 'my_client_id' githubAuthClientSecret: 'my_client_secret' # The same goes for GitLab authentication - # see here: https://nx.dev/ci/recipes/on-premise/auth-gitlab + # see here: https://nx.dev/ci/recipes/enterprise/on-premise/auth-gitlab # gitlabAppId: 'my_gitlab_app_id' # gitlabAppSecret: 'my_gitlab_app_secret' # Bitbucket too! If these are uncommented, BB auth is automatically enabled - # see here: https://nx.dev/ci/recipes/on-premise/auth-bitbucket + # see here: https://nx.dev/ci/recipes/enterprise/on-premise/auth-bitbucket # bitbucketAppId: 'bitbucket_app_id' # bitbucketAppSecret: 'bitbucket_app_secret' # SAML auth - # see here: https://nx.dev/ci/recipes/on-premise/auth-saml + # see here: https://nx.dev/ci/recipes/enterprise/on-premise/auth-saml # samlEntryPoint: 'your_saml_entry_point' # samlCert: 'saml_cert' ``` diff --git a/docs/nx-cloud/private/auth-bitbucket.md b/docs/nx-cloud/enterprise/on-premise/auth-bitbucket.md similarity index 77% rename from docs/nx-cloud/private/auth-bitbucket.md rename to docs/nx-cloud/enterprise/on-premise/auth-bitbucket.md index 37fbe7f3ec658..2a5db0659f507 100644 --- a/docs/nx-cloud/private/auth-bitbucket.md +++ b/docs/nx-cloud/enterprise/on-premise/auth-bitbucket.md @@ -8,15 +8,15 @@ Before creating your container, you'll need to create a BitBucket "OAuth consume From BitBucket, click on your profile picture and select your workspace: -![Step 1](/nx-cloud/private/images/bitbucket_1.png) +![Step 1](/nx-cloud/enterprise/on-premise/images/bitbucket_1.png) Then "Settings": -![Step 2](/nx-cloud/private/images/bitbucket_2.png) +![Step 2](/nx-cloud/enterprise/on-premise/images/bitbucket_2.png) Then "OAuth consumers": -![Step 3](/nx-cloud/private/images/bitbucket_3.png) +![Step 3](/nx-cloud/enterprise/on-premise/images/bitbucket_3.png) And create a new consumer. @@ -31,17 +31,17 @@ https://my.nx-enterprise.url:8080/auth-callback **Important:** Ensure there is **no backslash at the end of the "Callback URL"** (i.e. it matches the above pattern) -![Step 4](/nx-cloud/private/images/bitbucket_4.png) +![Step 4](/nx-cloud/enterprise/on-premise/images/bitbucket_4.png) Ensure you grant it the `account:read` and `account:email` scopes: -![Step 5](/nx-cloud/private/images/bitbucket_5.png) +![Step 5](/nx-cloud/enterprise/on-premise/images/bitbucket_5.png) Save your changes. Once you create, keep a note of the Key and the Secret: -![Step 6](/nx-cloud/private/images/bitbucket_6.png) +![Step 6](/nx-cloud/enterprise/on-premise/images/bitbucket_6.png) ## Connect your Nx Cloud installation to your new app diff --git a/docs/nx-cloud/private/auth-github.md b/docs/nx-cloud/enterprise/on-premise/auth-github.md similarity index 81% rename from docs/nx-cloud/private/auth-github.md rename to docs/nx-cloud/enterprise/on-premise/auth-github.md index 6ef39845f0dbf..921fb2eb01c88 100644 --- a/docs/nx-cloud/private/auth-github.md +++ b/docs/nx-cloud/enterprise/on-premise/auth-github.md @@ -6,19 +6,19 @@ First, you'll need to create a GitHub OAuth app for your organisation. From GitHub, click on your profile picture and chose "Settings": -![Step 1](/nx-cloud/private/images/github_auth_step_1.png) +![Step 1](/nx-cloud/enterprise/on-premise/images/github_auth_step_1.png) Then "Developer settings" from the left-hand menu: -![Step 2](/nx-cloud/private/images/github_auth_step_2.png) +![Step 2](/nx-cloud/enterprise/on-premise/images/github_auth_step_2.png) Then "OAuth Apps": -![Step 3](/nx-cloud/private/images/github_auth_step_3.png) +![Step 3](/nx-cloud/enterprise/on-premise/images/github_auth_step_3.png) And create a new OAuth app: -![Step 4](/nx-cloud/private/images/github_auth_step_4.png) +![Step 4](/nx-cloud/enterprise/on-premise/images/github_auth_step_4.png) Give it a name, and a homepage URL. The authorization callback is the important bit. It needs to be in this form: @@ -29,15 +29,15 @@ Give it a name, and a homepage URL. The authorization callback is the important https://my.nx-enterprise.url:8080/auth-callback ``` -![Step 5](/nx-cloud/private/images/github_auth_step_5.png) +![Step 5](/nx-cloud/enterprise/on-premise/images/github_auth_step_5.png) Once you create, keep a note of the Client ID: -![Step 6](/nx-cloud/private/images/github_auth_step_6.png) +![Step 6](/nx-cloud/enterprise/on-premise/images/github_auth_step_6.png) And then generate a new client secret, and save it somewhere secure (we'll use it in a bit): -![Step 7](/nx-cloud/private/images/github_auth_step_7.png) +![Step 7](/nx-cloud/enterprise/on-premise/images/github_auth_step_7.png) ## Configure Nx Cloud Installation diff --git a/docs/nx-cloud/private/auth-gitlab.md b/docs/nx-cloud/enterprise/on-premise/auth-gitlab.md similarity index 80% rename from docs/nx-cloud/private/auth-gitlab.md rename to docs/nx-cloud/enterprise/on-premise/auth-gitlab.md index d610458d81679..4d081f17f8321 100644 --- a/docs/nx-cloud/private/auth-gitlab.md +++ b/docs/nx-cloud/enterprise/on-premise/auth-gitlab.md @@ -6,11 +6,11 @@ Before creating your container, you'll need to create a GitLab app for your orga From GitLab, click on your profile picture and chose "Preferences": -![Step 1](/nx-cloud/private/images/gitlab_step_1.png) +![Step 1](/nx-cloud/enterprise/on-premise/images/gitlab_step_1.png) Then "Applications" from the left-hand menu: -![Step 2](/nx-cloud/private/images/gitlab_step_2.png) +![Step 2](/nx-cloud/enterprise/on-premise/images/gitlab_step_2.png) Give the app a name. The authorization callback is the important bit. It needs to be in this form: @@ -23,17 +23,17 @@ https://my.nx-enterprise.url:8080/auth-callback **Important:** Ensure there is **no backslash at the end of the "Redirect URI"** (i.e. it matches the above pattern) -![Step 3](/nx-cloud/private/images/gitlab_step_3.png) +![Step 3](/nx-cloud/enterprise/on-premise/images/gitlab_step_3.png) Ensure you grant it the "`read_user`" scope: -![Step 4](/nx-cloud/private/images/gitlab_step_4.png) +![Step 4](/nx-cloud/enterprise/on-premise/images/gitlab_step_4.png) Click "Save application". Once you create, keep a note of the Client ID and the Secret: -![Step 5](/nx-cloud/private/images/gitlab_step_5.png) +![Step 5](/nx-cloud/enterprise/on-premise/images/gitlab_step_5.png) ## Connect your Nx Cloud installation to your new app diff --git a/docs/nx-cloud/private/auth-saml-managed.md b/docs/nx-cloud/enterprise/on-premise/auth-saml-managed.md similarity index 72% rename from docs/nx-cloud/private/auth-saml-managed.md rename to docs/nx-cloud/enterprise/on-premise/auth-saml-managed.md index ae977058201f1..f6964fc2812db 100644 --- a/docs/nx-cloud/private/auth-saml-managed.md +++ b/docs/nx-cloud/enterprise/on-premise/auth-saml-managed.md @@ -7,13 +7,13 @@ You'll be entering it in the instructions below. 1. Create a new Okta App Integration: - ![Okta 1](/nx-cloud/private/images/saml/okta_1.png) + ![Okta 1](/nx-cloud/enterprise/on-premise/images/saml/okta_1.png) - ![Okta 2](/nx-cloud/private/images/saml/okta_2.png) + ![Okta 2](/nx-cloud/enterprise/on-premise/images/saml/okta_2.png) 2. Give it a name: - ![Okta 3](/nx-cloud/private/images/saml/okta_3.png) + ![Okta 3](/nx-cloud/enterprise/on-premise/images/saml/okta_3.png) 3. On the Next page, configure it as below: @@ -24,30 +24,30 @@ You'll be entering it in the instructions below. - If using the main-US cluster: `urn:auth0:nrwl:SAML-IDENTIFIER` - If using the EU cluster: `urn:auth0:nxcloud-eu:SAML-IDENTIFIER` - ![Okta 4](/nx-cloud/private/images/saml/okta_4_public.png) + ![Okta 4](/nx-cloud/enterprise/on-premise/images/saml/okta_4_public.png) 4. Scroll down to attribute statements and configure them as per below: - ![Okta 5](/nx-cloud/private/images/saml/okta_5.png) + ![Okta 5](/nx-cloud/enterprise/on-premise/images/saml/okta_5.png) 5. Click “Next”, and select the first option on the next screen. 6. Go to the assignments tab and assign the users that can login to the Nx Cloud WebApp: 1. **Note:** This just gives them permission to use the Nx Cloud web app with their own workspace. Users will still need to be invited manually through the web app to your main workspace. - ![Okta 6](/nx-cloud/private/images/saml/okta_6.png) + ![Okta 6](/nx-cloud/enterprise/on-premise/images/saml/okta_6.png) 7. Then in the Sign-On tab scroll down: - ![Okta 7](/nx-cloud/private/images/saml/okta_7.png) + ![Okta 7](/nx-cloud/enterprise/on-premise/images/saml/okta_7.png) 8. Scroll down and from the list of certificates, download the one with the “Active” status: - ![Okta 8](/nx-cloud/private/images/saml/okta_8.png) + ![Okta 8](/nx-cloud/enterprise/on-premise/images/saml/okta_8.png) 9. Then view the ldP metadata: - ![Okta 9](/nx-cloud/private/images/saml/okta_9.png) + ![Okta 9](/nx-cloud/enterprise/on-premise/images/saml/okta_9.png) 10. Then find the row similar to the below, and copy the highlighted URL (see screenshot as well): @@ -58,7 +58,7 @@ You'll be entering it in the instructions below. /> ``` - ![Okta 10](/nx-cloud/private/images/saml/okta_10.png) + ![Okta 10](/nx-cloud/enterprise/on-premise/images/saml/okta_10.png) 11. Send us via email: - your _public_ certificate downloaded in step 8 diff --git a/docs/nx-cloud/private/auth-saml.md b/docs/nx-cloud/enterprise/on-premise/auth-saml.md similarity index 69% rename from docs/nx-cloud/private/auth-saml.md rename to docs/nx-cloud/enterprise/on-premise/auth-saml.md index 4560b8602df8e..5db43887c1f86 100644 --- a/docs/nx-cloud/private/auth-saml.md +++ b/docs/nx-cloud/enterprise/on-premise/auth-saml.md @@ -12,44 +12,44 @@ if you are interested. 1. Create a new enterprise app - ![Step 1](/nx-cloud/private/images/saml/azure_1.png) + ![Step 1](/nx-cloud/enterprise/on-premise/images/saml/azure_1.png) - ![Step 2](/nx-cloud/private/images/saml/azure_2.png) + ![Step 2](/nx-cloud/enterprise/on-premise/images/saml/azure_2.png) 2. Choose “Create your own”: - ![Step 3](/nx-cloud/private/images/saml/azure_3.png) + ![Step 3](/nx-cloud/enterprise/on-premise/images/saml/azure_3.png) 3. Give it a name - ![Step 4](/nx-cloud/private/images/saml/azure_4.png) + ![Step 4](/nx-cloud/enterprise/on-premise/images/saml/azure_4.png) 4. Assign your users and/or groups to it: - ![Step 5](/nx-cloud/private/images/saml/azure_5.png) + ![Step 5](/nx-cloud/enterprise/on-premise/images/saml/azure_5.png) 5. Then set-up SSO - ![Step 6](/nx-cloud/private/images/saml/azure_6.png) + ![Step 6](/nx-cloud/enterprise/on-premise/images/saml/azure_6.png) 6. And choose SAML: - ![Step 7](/nx-cloud/private/images/saml/azure_7.png) + ![Step 7](/nx-cloud/enterprise/on-premise/images/saml/azure_7.png) 7. Add these configuration options 1. Configure the Identifier **exactly** as `nx-private-cloud` 2. For the **Reply URL**, it should point to your Private Cloud instance URL. Make sure it ends with `/auth-callback` - ![Step 8](/nx-cloud/private/images/saml/azure_8.png) + ![Step 8](/nx-cloud/enterprise/on-premise/images/saml/azure_8.png) 8. Scroll down and manage claims: - ![Step 9](/nx-cloud/private/images/saml/azure_9.png) + ![Step 9](/nx-cloud/enterprise/on-premise/images/saml/azure_9.png) 9. The first row should be the `email` claim, click to Edit it: - ![Step 10](/nx-cloud/private/images/saml/azure_10.png) + ![Step 10](/nx-cloud/enterprise/on-premise/images/saml/azure_10.png) 10. Configure it as per below @@ -57,18 +57,18 @@ if you are interested. 2. **“Name:”** needs to be “email” 3. See screenshot below. This is an important step, because Nx Cloud will expect the “email” property on each profile that logs in. - ![Step 11](/nx-cloud/private/images/saml/azure_11.png) + ![Step 11](/nx-cloud/enterprise/on-premise/images/saml/azure_11.png) 11. Download the certificate in **Base64**: - ![Step 12](/nx-cloud/private/images/saml/azure_12.png) + ![Step 12](/nx-cloud/enterprise/on-premise/images/saml/azure_12.png) 12. Extract the downloaded certificate value as a one-line string: 1. `awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' azure_cert_file.cer` 2. We’ll use this in a bit to initialize an environment variable 13. Copy the Login URL: - ![Step 13](/nx-cloud/private/images/saml/azure_13.png) + ![Step 13](/nx-cloud/enterprise/on-premise/images/saml/azure_13.png) 14. Then add these two env vars to your Nx Cloud cluster secrets (see [Helm config](#helm-config) below): 1. `SAML_CERT=` @@ -78,46 +78,46 @@ if you are interested. 1. Create a new Okta App Integration: - ![Okta 1](/nx-cloud/private/images/saml/okta_1.png) + ![Okta 1](/nx-cloud/enterprise/on-premise/images/saml/okta_1.png) - ![Okta 2](/nx-cloud/private/images/saml/okta_2.png) + ![Okta 2](/nx-cloud/enterprise/on-premise/images/saml/okta_2.png) 2. Give it a name: - ![Okta 3](/nx-cloud/private/images/saml/okta_3.png) + ![Okta 3](/nx-cloud/enterprise/on-premise/images/saml/okta_3.png) 3. On the Next page, configure it as below: 1. The Single Sign On URL needs to point to your Nx Cloud instance URL and ends with `/auth/saml/callback` 2. The Audience should be `nx-private-cloud` - ![Okta 4](/nx-cloud/private/images/saml/okta_4.png) + ![Okta 4](/nx-cloud/enterprise/on-premise/images/saml/okta_4.png) 4. Scroll down to attribute statements and configure them as per below: - ![Okta 5](/nx-cloud/private/images/saml/okta_5.png) + ![Okta 5](/nx-cloud/enterprise/on-premise/images/saml/okta_5.png) 5. Click “Next”, and select the first option on the next screen. 6. Go to the assignments tab and assign the users that can login to the Nx Cloud WebApp: 1. **Note:** This just gives them permission to use the Nx Cloud web app with their own workspace. Users will still need to be invited manually through the web app to your main workspace. - ![Okta 6](/nx-cloud/private/images/saml/okta_6.png) + ![Okta 6](/nx-cloud/enterprise/on-premise/images/saml/okta_6.png) 7. Then in the Sign-On tab scroll down: - ![Okta 7](/nx-cloud/private/images/saml/okta_7.png) + ![Okta 7](/nx-cloud/enterprise/on-premise/images/saml/okta_7.png) 8. Scroll down and from the list of certificates, download the one with the “Active” status: - ![Okta 8](/nx-cloud/private/images/saml/okta_8.png) + ![Okta 8](/nx-cloud/enterprise/on-premise/images/saml/okta_8.png) 9. Extract the downloaded certificate value as a one-line string: 1. `awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' okta.cert` 2. We will use this in a bit to initialize and environment variable 10. Then view the ldP metadata: - ![Okta 9](/nx-cloud/private/images/saml/okta_9.png) + ![Okta 9](/nx-cloud/enterprise/on-premise/images/saml/okta_9.png) 11. Then find the row similar to the below, and copy the highlighted URL (see screenshot as well): @@ -128,7 +128,7 @@ if you are interested. /> ``` - ![Okta 10](/nx-cloud/private/images/saml/okta_10.png) + ![Okta 10](/nx-cloud/enterprise/on-premise/images/saml/okta_10.png) 12. Then add these two env vars to your secrets (see [Helm config](#helm-config) below): 1. `SAML_CERT=` diff --git a/docs/nx-cloud/private/auth-single-admin.md b/docs/nx-cloud/enterprise/on-premise/auth-single-admin.md similarity index 85% rename from docs/nx-cloud/private/auth-single-admin.md rename to docs/nx-cloud/enterprise/on-premise/auth-single-admin.md index dbc28affc9e30..c47abe1d4fa98 100644 --- a/docs/nx-cloud/private/auth-single-admin.md +++ b/docs/nx-cloud/enterprise/on-premise/auth-single-admin.md @@ -33,17 +33,17 @@ than 1 admin to your workspace, to reduce the chance of losing access to it. For instructions on how to set up third-party auth providers, please refer to these guides: -- [GitHub Auth](/ci/recipes/on-premise/auth-github) -- [GitLab Auth](/ci/recipes/on-premise/auth-gitlab) -- [BitBucket Auth](/ci/recipes/on-premise/auth-bitbucket) -- [SAML Auth](/ci/recipes/on-premise/auth-saml) +- [GitHub Auth](/ci/recipes/enterprise/on-premise/auth-github) +- [GitLab Auth](/ci/recipes/enterprise/on-premise/auth-gitlab) +- [BitBucket Auth](/ci/recipes/enterprise/on-premise/auth-bitbucket) +- [SAML Auth](/ci/recipes/enterprise/on-premise/auth-saml) ## Inviting users Once that's done, you can either sign in with your admin user by using the form, or directly via the configured third-party authentication providers by clicking the "_Sign In with configured third-party provider_" button: -![Main user login](/nx-cloud/private/images/main-user-login.webp) +![Main user login](/nx-cloud/enterprise/on-premise/images/main-user-login.webp) You can then go to your organisation's settings and then to the members page and start inviting people based on their GitHub username. When you invite someone, Nx Cloud will generate a unique invite URL, which you can send to that person directly. @@ -61,8 +61,8 @@ can usually be found by clicking in the top-right corner. GitLab: -![GitLab username location](/nx-cloud/private/images/gitlab-username.png) +![GitLab username location](/nx-cloud/enterprise/on-premise/images/gitlab-username.png) GitHub: -![GitHub username location](/nx-cloud/private/images/github-username.png) +![GitHub username location](/nx-cloud/enterprise/on-premise/images/github-username.png) diff --git a/docs/nx-cloud/private/images/bitbucket_1.png b/docs/nx-cloud/enterprise/on-premise/images/bitbucket_1.png similarity index 100% rename from docs/nx-cloud/private/images/bitbucket_1.png rename to docs/nx-cloud/enterprise/on-premise/images/bitbucket_1.png diff --git a/docs/nx-cloud/private/images/bitbucket_2.png b/docs/nx-cloud/enterprise/on-premise/images/bitbucket_2.png similarity index 100% rename from docs/nx-cloud/private/images/bitbucket_2.png rename to docs/nx-cloud/enterprise/on-premise/images/bitbucket_2.png diff --git a/docs/nx-cloud/private/images/bitbucket_3.png b/docs/nx-cloud/enterprise/on-premise/images/bitbucket_3.png similarity index 100% rename from docs/nx-cloud/private/images/bitbucket_3.png rename to docs/nx-cloud/enterprise/on-premise/images/bitbucket_3.png diff --git a/docs/nx-cloud/private/images/bitbucket_4.png b/docs/nx-cloud/enterprise/on-premise/images/bitbucket_4.png similarity index 100% rename from docs/nx-cloud/private/images/bitbucket_4.png rename to docs/nx-cloud/enterprise/on-premise/images/bitbucket_4.png diff --git a/docs/nx-cloud/private/images/bitbucket_5.png b/docs/nx-cloud/enterprise/on-premise/images/bitbucket_5.png similarity index 100% rename from docs/nx-cloud/private/images/bitbucket_5.png rename to docs/nx-cloud/enterprise/on-premise/images/bitbucket_5.png diff --git a/docs/nx-cloud/private/images/bitbucket_6.png b/docs/nx-cloud/enterprise/on-premise/images/bitbucket_6.png similarity index 100% rename from docs/nx-cloud/private/images/bitbucket_6.png rename to docs/nx-cloud/enterprise/on-premise/images/bitbucket_6.png diff --git a/docs/nx-cloud/private/images/github-username.png b/docs/nx-cloud/enterprise/on-premise/images/github-username.png similarity index 100% rename from docs/nx-cloud/private/images/github-username.png rename to docs/nx-cloud/enterprise/on-premise/images/github-username.png diff --git a/docs/nx-cloud/private/images/github_auth_step_1.png b/docs/nx-cloud/enterprise/on-premise/images/github_auth_step_1.png similarity index 100% rename from docs/nx-cloud/private/images/github_auth_step_1.png rename to docs/nx-cloud/enterprise/on-premise/images/github_auth_step_1.png diff --git a/docs/nx-cloud/private/images/github_auth_step_2.png b/docs/nx-cloud/enterprise/on-premise/images/github_auth_step_2.png similarity index 100% rename from docs/nx-cloud/private/images/github_auth_step_2.png rename to docs/nx-cloud/enterprise/on-premise/images/github_auth_step_2.png diff --git a/docs/nx-cloud/private/images/github_auth_step_3.png b/docs/nx-cloud/enterprise/on-premise/images/github_auth_step_3.png similarity index 100% rename from docs/nx-cloud/private/images/github_auth_step_3.png rename to docs/nx-cloud/enterprise/on-premise/images/github_auth_step_3.png diff --git a/docs/nx-cloud/private/images/github_auth_step_4.png b/docs/nx-cloud/enterprise/on-premise/images/github_auth_step_4.png similarity index 100% rename from docs/nx-cloud/private/images/github_auth_step_4.png rename to docs/nx-cloud/enterprise/on-premise/images/github_auth_step_4.png diff --git a/docs/nx-cloud/private/images/github_auth_step_5.png b/docs/nx-cloud/enterprise/on-premise/images/github_auth_step_5.png similarity index 100% rename from docs/nx-cloud/private/images/github_auth_step_5.png rename to docs/nx-cloud/enterprise/on-premise/images/github_auth_step_5.png diff --git a/docs/nx-cloud/private/images/github_auth_step_6.png b/docs/nx-cloud/enterprise/on-premise/images/github_auth_step_6.png similarity index 100% rename from docs/nx-cloud/private/images/github_auth_step_6.png rename to docs/nx-cloud/enterprise/on-premise/images/github_auth_step_6.png diff --git a/docs/nx-cloud/private/images/github_auth_step_7.png b/docs/nx-cloud/enterprise/on-premise/images/github_auth_step_7.png similarity index 100% rename from docs/nx-cloud/private/images/github_auth_step_7.png rename to docs/nx-cloud/enterprise/on-premise/images/github_auth_step_7.png diff --git a/docs/nx-cloud/private/images/gitlab-username.png b/docs/nx-cloud/enterprise/on-premise/images/gitlab-username.png similarity index 100% rename from docs/nx-cloud/private/images/gitlab-username.png rename to docs/nx-cloud/enterprise/on-premise/images/gitlab-username.png diff --git a/docs/nx-cloud/private/images/gitlab_step_1.png b/docs/nx-cloud/enterprise/on-premise/images/gitlab_step_1.png similarity index 100% rename from docs/nx-cloud/private/images/gitlab_step_1.png rename to docs/nx-cloud/enterprise/on-premise/images/gitlab_step_1.png diff --git a/docs/nx-cloud/private/images/gitlab_step_2.png b/docs/nx-cloud/enterprise/on-premise/images/gitlab_step_2.png similarity index 100% rename from docs/nx-cloud/private/images/gitlab_step_2.png rename to docs/nx-cloud/enterprise/on-premise/images/gitlab_step_2.png diff --git a/docs/nx-cloud/private/images/gitlab_step_3.png b/docs/nx-cloud/enterprise/on-premise/images/gitlab_step_3.png similarity index 100% rename from docs/nx-cloud/private/images/gitlab_step_3.png rename to docs/nx-cloud/enterprise/on-premise/images/gitlab_step_3.png diff --git a/docs/nx-cloud/private/images/gitlab_step_4.png b/docs/nx-cloud/enterprise/on-premise/images/gitlab_step_4.png similarity index 100% rename from docs/nx-cloud/private/images/gitlab_step_4.png rename to docs/nx-cloud/enterprise/on-premise/images/gitlab_step_4.png diff --git a/docs/nx-cloud/private/images/gitlab_step_5.png b/docs/nx-cloud/enterprise/on-premise/images/gitlab_step_5.png similarity index 100% rename from docs/nx-cloud/private/images/gitlab_step_5.png rename to docs/nx-cloud/enterprise/on-premise/images/gitlab_step_5.png diff --git a/docs/nx-cloud/private/images/main-user-login.webp b/docs/nx-cloud/enterprise/on-premise/images/main-user-login.webp similarity index 100% rename from docs/nx-cloud/private/images/main-user-login.webp rename to docs/nx-cloud/enterprise/on-premise/images/main-user-login.webp diff --git a/docs/nx-cloud/private/images/nx-cloud-landing.png b/docs/nx-cloud/enterprise/on-premise/images/nx-cloud-landing.png similarity index 100% rename from docs/nx-cloud/private/images/nx-cloud-landing.png rename to docs/nx-cloud/enterprise/on-premise/images/nx-cloud-landing.png diff --git a/docs/nx-cloud/private/images/private-cloud-github-integration-add-webhook.png b/docs/nx-cloud/enterprise/on-premise/images/private-cloud-github-integration-add-webhook.png similarity index 100% rename from docs/nx-cloud/private/images/private-cloud-github-integration-add-webhook.png rename to docs/nx-cloud/enterprise/on-premise/images/private-cloud-github-integration-add-webhook.png diff --git a/docs/nx-cloud/private/images/private-cloud-github-integration-generate-token.png b/docs/nx-cloud/enterprise/on-premise/images/private-cloud-github-integration-generate-token.png similarity index 100% rename from docs/nx-cloud/private/images/private-cloud-github-integration-generate-token.png rename to docs/nx-cloud/enterprise/on-premise/images/private-cloud-github-integration-generate-token.png diff --git a/docs/nx-cloud/private/images/saml/azure_1.png b/docs/nx-cloud/enterprise/on-premise/images/saml/azure_1.png similarity index 100% rename from docs/nx-cloud/private/images/saml/azure_1.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/azure_1.png diff --git a/docs/nx-cloud/private/images/saml/azure_10.png b/docs/nx-cloud/enterprise/on-premise/images/saml/azure_10.png similarity index 100% rename from docs/nx-cloud/private/images/saml/azure_10.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/azure_10.png diff --git a/docs/nx-cloud/private/images/saml/azure_11.png b/docs/nx-cloud/enterprise/on-premise/images/saml/azure_11.png similarity index 100% rename from docs/nx-cloud/private/images/saml/azure_11.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/azure_11.png diff --git a/docs/nx-cloud/private/images/saml/azure_12.png b/docs/nx-cloud/enterprise/on-premise/images/saml/azure_12.png similarity index 100% rename from docs/nx-cloud/private/images/saml/azure_12.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/azure_12.png diff --git a/docs/nx-cloud/private/images/saml/azure_13.png b/docs/nx-cloud/enterprise/on-premise/images/saml/azure_13.png similarity index 100% rename from docs/nx-cloud/private/images/saml/azure_13.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/azure_13.png diff --git a/docs/nx-cloud/private/images/saml/azure_2.png b/docs/nx-cloud/enterprise/on-premise/images/saml/azure_2.png similarity index 100% rename from docs/nx-cloud/private/images/saml/azure_2.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/azure_2.png diff --git a/docs/nx-cloud/private/images/saml/azure_3.png b/docs/nx-cloud/enterprise/on-premise/images/saml/azure_3.png similarity index 100% rename from docs/nx-cloud/private/images/saml/azure_3.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/azure_3.png diff --git a/docs/nx-cloud/private/images/saml/azure_4.png b/docs/nx-cloud/enterprise/on-premise/images/saml/azure_4.png similarity index 100% rename from docs/nx-cloud/private/images/saml/azure_4.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/azure_4.png diff --git a/docs/nx-cloud/private/images/saml/azure_5.png b/docs/nx-cloud/enterprise/on-premise/images/saml/azure_5.png similarity index 100% rename from docs/nx-cloud/private/images/saml/azure_5.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/azure_5.png diff --git a/docs/nx-cloud/private/images/saml/azure_6.png b/docs/nx-cloud/enterprise/on-premise/images/saml/azure_6.png similarity index 100% rename from docs/nx-cloud/private/images/saml/azure_6.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/azure_6.png diff --git a/docs/nx-cloud/private/images/saml/azure_7.png b/docs/nx-cloud/enterprise/on-premise/images/saml/azure_7.png similarity index 100% rename from docs/nx-cloud/private/images/saml/azure_7.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/azure_7.png diff --git a/docs/nx-cloud/private/images/saml/azure_8.png b/docs/nx-cloud/enterprise/on-premise/images/saml/azure_8.png similarity index 100% rename from docs/nx-cloud/private/images/saml/azure_8.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/azure_8.png diff --git a/docs/nx-cloud/private/images/saml/azure_9.png b/docs/nx-cloud/enterprise/on-premise/images/saml/azure_9.png similarity index 100% rename from docs/nx-cloud/private/images/saml/azure_9.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/azure_9.png diff --git a/docs/nx-cloud/private/images/saml/okta_1.png b/docs/nx-cloud/enterprise/on-premise/images/saml/okta_1.png similarity index 100% rename from docs/nx-cloud/private/images/saml/okta_1.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/okta_1.png diff --git a/docs/nx-cloud/private/images/saml/okta_10.png b/docs/nx-cloud/enterprise/on-premise/images/saml/okta_10.png similarity index 100% rename from docs/nx-cloud/private/images/saml/okta_10.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/okta_10.png diff --git a/docs/nx-cloud/private/images/saml/okta_2.png b/docs/nx-cloud/enterprise/on-premise/images/saml/okta_2.png similarity index 100% rename from docs/nx-cloud/private/images/saml/okta_2.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/okta_2.png diff --git a/docs/nx-cloud/private/images/saml/okta_3.png b/docs/nx-cloud/enterprise/on-premise/images/saml/okta_3.png similarity index 100% rename from docs/nx-cloud/private/images/saml/okta_3.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/okta_3.png diff --git a/docs/nx-cloud/private/images/saml/okta_4.png b/docs/nx-cloud/enterprise/on-premise/images/saml/okta_4.png similarity index 100% rename from docs/nx-cloud/private/images/saml/okta_4.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/okta_4.png diff --git a/docs/nx-cloud/private/images/saml/okta_4_public.png b/docs/nx-cloud/enterprise/on-premise/images/saml/okta_4_public.png similarity index 100% rename from docs/nx-cloud/private/images/saml/okta_4_public.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/okta_4_public.png diff --git a/docs/nx-cloud/private/images/saml/okta_5.png b/docs/nx-cloud/enterprise/on-premise/images/saml/okta_5.png similarity index 100% rename from docs/nx-cloud/private/images/saml/okta_5.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/okta_5.png diff --git a/docs/nx-cloud/private/images/saml/okta_6.png b/docs/nx-cloud/enterprise/on-premise/images/saml/okta_6.png similarity index 100% rename from docs/nx-cloud/private/images/saml/okta_6.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/okta_6.png diff --git a/docs/nx-cloud/private/images/saml/okta_7.png b/docs/nx-cloud/enterprise/on-premise/images/saml/okta_7.png similarity index 100% rename from docs/nx-cloud/private/images/saml/okta_7.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/okta_7.png diff --git a/docs/nx-cloud/private/images/saml/okta_8.png b/docs/nx-cloud/enterprise/on-premise/images/saml/okta_8.png similarity index 100% rename from docs/nx-cloud/private/images/saml/okta_8.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/okta_8.png diff --git a/docs/nx-cloud/private/images/saml/okta_9.png b/docs/nx-cloud/enterprise/on-premise/images/saml/okta_9.png similarity index 100% rename from docs/nx-cloud/private/images/saml/okta_9.png rename to docs/nx-cloud/enterprise/on-premise/images/saml/okta_9.png diff --git a/docs/nx-cloud/private/images/webhook-trigger-events.png b/docs/nx-cloud/enterprise/on-premise/images/webhook-trigger-events.png similarity index 100% rename from docs/nx-cloud/private/images/webhook-trigger-events.png rename to docs/nx-cloud/enterprise/on-premise/images/webhook-trigger-events.png diff --git a/docs/nx-cloud/private/images/webhook-trigger-pull-requests.png b/docs/nx-cloud/enterprise/on-premise/images/webhook-trigger-pull-requests.png similarity index 100% rename from docs/nx-cloud/private/images/webhook-trigger-pull-requests.png rename to docs/nx-cloud/enterprise/on-premise/images/webhook-trigger-pull-requests.png diff --git a/docs/nx-cloud/private/nx-enterprise-on-prem.md b/docs/nx-cloud/features/nx-enterprise-on-prem.md similarity index 93% rename from docs/nx-cloud/private/nx-enterprise-on-prem.md rename to docs/nx-cloud/features/nx-enterprise-on-prem.md index bfbdc2e23959b..32cc76983b5f8 100644 --- a/docs/nx-cloud/private/nx-enterprise-on-prem.md +++ b/docs/nx-cloud/features/nx-enterprise-on-prem.md @@ -46,7 +46,7 @@ Once you let us know you'd like this option, depending on the agreed requirement If you would like to host Nx Cloud yourself, within your organization's infrastructure, the easiest way to set it up is as a self-contained VM. -Refer to our ["Self-contained VM" guide](/ci/recipes/on-premise/ami-setup) for instructions on running Nx Cloud on Amazon EC2. +Refer to our ["Self-contained VM" guide](/ci/recipes/enterprise/on-premise/ami-setup) for instructions on running Nx Cloud on Amazon EC2. ### Multi-node setup with Kubernetes @@ -57,4 +57,4 @@ We do offer, however, a multi-node Kubernetes setup, that is deployed via Helm. ## Resources - [Integration with your source control provider](/ci/recipes/source-control-integration) -- [On-Prem specific features](/ci/recipes/on-premise/auth-single-admin) +- [On-Prem specific features](/ci/recipes/enterprise/on-premise/auth-single-admin) diff --git a/docs/nx-cloud/intro/ci-with-nx.md b/docs/nx-cloud/intro/ci-with-nx.md index 26a2a5552ced7..f52e26e1a604c 100644 --- a/docs/nx-cloud/intro/ci-with-nx.md +++ b/docs/nx-cloud/intro/ci-with-nx.md @@ -20,13 +20,13 @@ npx nx connect {% cards cols="2" lgCols="4" mdCols="4" smCols="2" %} -{% link-card title="Circle CI with Nx" type="tutorial" url="/ci/intro/tutorials/circle" icon="circleci" /%} +{% link-card title="What is Nx Cloud?" type="video" url="https://youtu.be/4VI-q943J3o" icon="nxcloud" /%} -{% link-card title="GitHub Actions with Nx" type="tutorial" url="/ci/intro/tutorials/github-actions" icon="github" /%} +{% link-card title="E2E Test Auto-Splitting and Distribution" type="video" url="https://youtu.be/XLOUFZeqRpM" icon="nxagents" /%} -{% link-card title="E2E Test Auto-Splitting and Distribution" type="video" url="https://youtu.be/XLOUFZeqRpM" icon="nxcloud" /%} +{% link-card title="Circle CI with Nx" type="tutorial" url="/ci/intro/tutorials/circle" icon="circleci" /%} -{% link-card title="More On Youtube" type="video" url="https://www.youtube.com/@nxdevtools" icon="youtube" /%} +{% link-card title="GitHub Actions with Nx" type="tutorial" url="/ci/intro/tutorials/github-actions" icon="github" /%} {% /cards %} diff --git a/docs/nx-cloud/reference/images/agents.webp b/docs/nx-cloud/reference/images/agents.webp new file mode 100644 index 0000000000000..41fb147b73b9c Binary files /dev/null and b/docs/nx-cloud/reference/images/agents.webp differ diff --git a/docs/nx-cloud/reference/images/cipe_top.webp b/docs/nx-cloud/reference/images/cipe_top.webp new file mode 100644 index 0000000000000..8998b336ca452 Binary files /dev/null and b/docs/nx-cloud/reference/images/cipe_top.webp differ diff --git a/docs/nx-cloud/reference/release-notes.md b/docs/nx-cloud/reference/release-notes.md index cafc28a7cc48c..d3b439970f49a 100644 --- a/docs/nx-cloud/reference/release-notes.md +++ b/docs/nx-cloud/reference/release-notes.md @@ -1,5 +1,33 @@ # Enterprise Release Notes +### 2402.27.3 + +With this version you can take advantage of most features announced during our recent [launch week](https://nx.dev/launch-nx). + +##### Nx Agents + +This release contains everything needed to run [Nx Agents](https://nx.dev/ci/features/distribute-task-execution) on-prem. While the on-prem configuration is still experimental, we are actively running Nx Agents trials at the moment, and if you'd like to take part please reach out to your DPE. + +If you already running DTE, there are a few advantages to upgrading to Agents: + +- simplified CI config: you will need to maintain just a single, main CI job config. NxCloud will create needed CI agents for you as needed. +- [dynamic agent allocation based on PR size](https://nx.dev/ci/features/dynamic-agents): instead of always launching all your agents NxCloud will now launch different number of agents dynamically based on your PR size +- access to [Spot instances](https://aws.amazon.com/ec2/spot/): if you are running your clusters on any of the popular cloud providers (AWS, Google Cloud, Azure etc.), you can now use their Spot instances for running your CI job. This is possible due to NxCloud's distribution model, which allows work on a reclaimed node to be re-distributed to the remaining agents. + +We will shortly make available a new Helm chart that will allow you to deploy a separate Agents cluster to launch workflows: [https://github.com/nrwl/nx-cloud-helm](https://github.com/nrwl/nx-cloud-helm). + +![agents_screen](/nx-cloud/reference/images/agents.webp) + +##### Task Atomizer and task retries + +If you combine this release + upgrade to the latest Nx 18, you will have access to both the [task atomizer](https://nx.dev/ci/features/split-e2e-tasks) (which allows your e2e to be distributed among agents PER FILE, instead of previously per project) and the [flaky task retry functionality](https://nx.dev/ci/features/flaky-tasks). + +##### CIPE page improvements + +Along with all the UI changes to support agents (following their logs and track how tasks get distributed,details of which you'll find demoed on [this page](https://nx.dev/ci/features/distribute-task-execution)) this release also brings all the new improvements to the CI pipeline execution page, including the commit info panel at the top: + +![cipe_top_half_screen](/nx-cloud/reference/images/cipe_top.webp) + ### 2312.11.7.patch1 - re-enable path style access for s3 buckets diff --git a/docs/shared/getting-started/intro.md b/docs/shared/getting-started/intro.md index b0b20bb6e2461..12d35b77bc610 100644 --- a/docs/shared/getting-started/intro.md +++ b/docs/shared/getting-started/intro.md @@ -25,7 +25,7 @@ npx create-nx-workspace@latest {% link-card title="Nx in 10 minutes!" type="video" url="https://youtu.be/-_4WMl-Fn0w" icon="nx" /%} -{% link-card title="What is Nx Cloud?" type="video" url="https://youtu.be/NZF0ZJpgaJM" icon="nxcloud" /%} +{% link-card title="What is Nx Cloud?" type="video" url="https://youtu.be/4VI-q943J3o" icon="nxcloud" /%} {% link-card title="PNPM Monorepos with Nx" type="video" url="https://youtu.be/ngdoUQBvAjo" icon="pnpm" /%} diff --git a/docs/shared/mental-model/large-tasks.json b/docs/shared/mental-model/large-tasks.json index caaed2be5dba4..6a152da161ef3 100644 --- a/docs/shared/mental-model/large-tasks.json +++ b/docs/shared/mental-model/large-tasks.json @@ -25184,203 +25184,203 @@ "hash": "2fe6ceb807628d7cbafb7edc964ab091cbb51f50" }, { - "file": "docs/nx-cloud/private/images/admin_hidden_login.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/admin_hidden_login.png", "hash": "a2fbd4488b6b38f4c04101444b0a01cc33d27b33" }, { - "file": "docs/nx-cloud/private/images/bitbucket_1.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/bitbucket_1.png", "hash": "744c93850fe889fd0063041ea14920862efe1ef9" }, { - "file": "docs/nx-cloud/private/images/bitbucket_2.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/bitbucket_2.png", "hash": "febde873790a4701eea045bc921b2911ea4d9305" }, { - "file": "docs/nx-cloud/private/images/bitbucket_3.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/bitbucket_3.png", "hash": "c1628cebbd1cafa841a20679c36a431de119c507" }, { - "file": "docs/nx-cloud/private/images/bitbucket_4.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/bitbucket_4.png", "hash": "f6c7959083ef31dc93d0494df7b56fb1e506df8c" }, { - "file": "docs/nx-cloud/private/images/bitbucket_5.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/bitbucket_5.png", "hash": "ef04cc67127fb230aa6211a8bbb4ee01b28b8693" }, { - "file": "docs/nx-cloud/private/images/bitbucket_6.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/bitbucket_6.png", "hash": "5400b205c7eccfebaa571133cd57d3db8ca229a4" }, { - "file": "docs/nx-cloud/private/images/github_auth_step_1.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/github_auth_step_1.png", "hash": "aab0b76bf8ff0f310212e9b48c677f58b214fb50" }, { - "file": "docs/nx-cloud/private/images/github_auth_step_2.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/github_auth_step_2.png", "hash": "b692beb0af8fe62c9f24257da1d078c150168399" }, { - "file": "docs/nx-cloud/private/images/github_auth_step_3.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/github_auth_step_3.png", "hash": "ed380e172e65e22fef748dc49eadac5f1822227d" }, { - "file": "docs/nx-cloud/private/images/github_auth_step_4.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/github_auth_step_4.png", "hash": "a9e7efb684f638531859335d04015c1c2efb5f4c" }, { - "file": "docs/nx-cloud/private/images/github_auth_step_5.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/github_auth_step_5.png", "hash": "1bdb10946021e179e93f7d644f4eed1af472e98c" }, { - "file": "docs/nx-cloud/private/images/github_auth_step_6.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/github_auth_step_6.png", "hash": "b8e7912726397121efb1c7d7dbe4a351f722171f" }, { - "file": "docs/nx-cloud/private/images/github_auth_step_7.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/github_auth_step_7.png", "hash": "017f221fa731020e901da4903e02e330412bf184" }, { - "file": "docs/nx-cloud/private/images/github-username.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/github-username.png", "hash": "8075d6b794e44784525a5a70d3f545c8e117c604" }, { - "file": "docs/nx-cloud/private/images/gitlab_step_1.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/gitlab_step_1.png", "hash": "fef273c0dcc3ca6b26371cfcb85d3ba466bfb0e5" }, { - "file": "docs/nx-cloud/private/images/gitlab_step_2.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/gitlab_step_2.png", "hash": "a1726555864bfbc70b22673e67b17cc99e5bc96a" }, { - "file": "docs/nx-cloud/private/images/gitlab_step_3.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/gitlab_step_3.png", "hash": "308937ac1b03a1c290e7cf4093dcebe52f274ab4" }, { - "file": "docs/nx-cloud/private/images/gitlab_step_4.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/gitlab_step_4.png", "hash": "adb4473c0316f99103dfe5e6b20f331f913e7701" }, { - "file": "docs/nx-cloud/private/images/gitlab_step_5.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/gitlab_step_5.png", "hash": "5119326eec8e04bf93a0ec2e70970a9f6a1fbcbd" }, { - "file": "docs/nx-cloud/private/images/gitlab-username.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/gitlab-username.png", "hash": "b264bf3f64e066efaf92875a935ce02248b08bef" }, { - "file": "docs/nx-cloud/private/images/invite_members.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/invite_members.png", "hash": "2d38d859b8ff9f40f0dd8d3b943ccd139b5b37be" }, { - "file": "docs/nx-cloud/private/images/main_user_login.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/main_user_login.png", "hash": "7083d89f9687448db362542b850160bba0133eef" }, { - "file": "docs/nx-cloud/private/images/private-cloud-github-integration-add-webhook.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/private-cloud-github-integration-add-webhook.png", "hash": "3c8d90333938bd4c52bf831eb8cb37b888356073" }, { - "file": "docs/nx-cloud/private/images/private-cloud-github-integration-generate-token.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/private-cloud-github-integration-generate-token.png", "hash": "f330e3fc735f60d5e1b314339c2acd09ff7c0b7c" }, { - "file": "docs/nx-cloud/private/images/saml/azure_1.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/azure_1.png", "hash": "dc48d010ef8a5d86099f10318cdc0fc5da43a25b" }, { - "file": "docs/nx-cloud/private/images/saml/azure_10.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/azure_10.png", "hash": "9b683623751a05cc30efc85160197980c738288c" }, { - "file": "docs/nx-cloud/private/images/saml/azure_11.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/azure_11.png", "hash": "eb90517fa62d143ff6c02d63b5495d0177dd43c8" }, { - "file": "docs/nx-cloud/private/images/saml/azure_12.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/azure_12.png", "hash": "621fe56e81811675898269797e716304806a0f56" }, { - "file": "docs/nx-cloud/private/images/saml/azure_13.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/azure_13.png", "hash": "ee60bbb6f0095382c1e2787de137194ecae026b8" }, { - "file": "docs/nx-cloud/private/images/saml/azure_2.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/azure_2.png", "hash": "9b24d4ffe4d88480189f9e2456fc0337ed946436" }, { - "file": "docs/nx-cloud/private/images/saml/azure_3.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/azure_3.png", "hash": "ea1527b4343e1020eb7a246394c8397693ff771d" }, { - "file": "docs/nx-cloud/private/images/saml/azure_4.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/azure_4.png", "hash": "acd2537beeca2bea6c72099bd980404754a6c83b" }, { - "file": "docs/nx-cloud/private/images/saml/azure_5.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/azure_5.png", "hash": "ac2568a83ae5c4f98d00a5229e45997cf6e9cab8" }, { - "file": "docs/nx-cloud/private/images/saml/azure_6.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/azure_6.png", "hash": "137818b3c798cfc18149863a371ae22c2b4202e1" }, { - "file": "docs/nx-cloud/private/images/saml/azure_7.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/azure_7.png", "hash": "2dd4b088f296fd12f27a91ad0e3fa6f29b9881e3" }, { - "file": "docs/nx-cloud/private/images/saml/azure_8.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/azure_8.png", "hash": "026b01d3baced7835c07b88fd59415134f0398f1" }, { - "file": "docs/nx-cloud/private/images/saml/azure_9.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/azure_9.png", "hash": "6128887c5e23b457094664d3cd31703fa8a3a18c" }, { - "file": "docs/nx-cloud/private/images/saml/okta_1.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/okta_1.png", "hash": "cab14353a5025e89bc998e3950b056667dc0b631" }, { - "file": "docs/nx-cloud/private/images/saml/okta_10.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/okta_10.png", "hash": "47f51224de579a00c85dbbd1466c268f21f83922" }, { - "file": "docs/nx-cloud/private/images/saml/okta_2.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/okta_2.png", "hash": "ae6f2ee8e362317c693eecebdc989b5929c63832" }, { - "file": "docs/nx-cloud/private/images/saml/okta_3.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/okta_3.png", "hash": "7a0446a2c35b2f87e8a41de9fd484577478514f1" }, { - "file": "docs/nx-cloud/private/images/saml/okta_4.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/okta_4.png", "hash": "c2b4d622902ec71562014bd1eb4fadb296b3f921" }, { - "file": "docs/nx-cloud/private/images/saml/okta_5.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/okta_5.png", "hash": "b50338567a5f0c34833d46c6bc9382fe497e454d" }, { - "file": "docs/nx-cloud/private/images/saml/okta_6.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/okta_6.png", "hash": "65fa2b43bd0ebf19fe86978be61d0e24dd5ab336" }, { - "file": "docs/nx-cloud/private/images/saml/okta_7.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/okta_7.png", "hash": "b1e122c2cb6fa7b0df0a7dab97a816fec7619b90" }, { - "file": "docs/nx-cloud/private/images/saml/okta_8.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/okta_8.png", "hash": "361603f392c3bfe76572293360944cb557d450a4" }, { - "file": "docs/nx-cloud/private/images/saml/okta_9.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/saml/okta_9.png", "hash": "76cc172c20023b655cb35dbfb7ca3eb7a68fd3df" }, { - "file": "docs/nx-cloud/private/images/webhook-trigger-events.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/webhook-trigger-events.png", "hash": "f84c6c92dd42f4a16eb8fd796ec7203ac3d9d7d9" }, { - "file": "docs/nx-cloud/private/images/webhook-trigger-pull-requests.png", + "file": "docs/nx-cloud/enterprise/on-premise/images/webhook-trigger-pull-requests.png", "hash": "f917c7056c2b13fed490199a95f329d46fa3ae92" }, { diff --git a/docs/shared/recipes/nx-release/update-local-registry-setup.md b/docs/shared/recipes/nx-release/update-local-registry-setup.md new file mode 100644 index 0000000000000..338052e5cb40c --- /dev/null +++ b/docs/shared/recipes/nx-release/update-local-registry-setup.md @@ -0,0 +1,79 @@ +# Update Your Local Registry Setup to use Nx Release + +Nx will create a `tools/start-local-registry.ts` script for starting a local registry and publishing packages to it in preparation for running end to end tests. If you have an existing `tools/start-local-registry.ts` script from a previous version of Nx, you should update it to use Nx Release to publish packages to the local registry. This will ensure that newly generated libraries are published appropriately when running end to end tests. + +## The Previous Version + +The previous version of the `tools/start-local-registry.ts` script used publish targets on each project to publish the packages to the local registry. This is no longer necessary with Nx Release. You can identify the previous version by the `nx run-many` command that publishes the packages: + +```typescript +/** + * This script starts a local registry for e2e testing purposes. + * It is meant to be called in jest's globalSetup. + */ +import { startLocalRegistry } from '@nx/js/plugins/jest/local-registry'; +import { execFileSync } from 'child_process'; + +export default async () => { + // local registry target to run + const localRegistryTarget = '@demo-plugin-1800/source:local-registry'; + // storage folder for the local registry + const storage = './tmp/local-registry/storage'; + + global.stopLocalRegistry = await startLocalRegistry({ + localRegistryTarget, + storage, + verbose: false, + }); + const nx = require.resolve('nx'); + execFileSync( + nx, + ['run-many', '--targets', 'publish', '--ver', '0.0.0-e2e', '--tag', 'e2e'], + { env: process.env, stdio: 'inherit' } + ); +}; +``` + +If your script looks like this, you should update it. + +## The Updated Version + +The updated version of the `tools/start-local-registry.ts` script uses Nx Release to publish the packages to the local registry. This is done by running `releaseVersion` and `releasePublish` functions from `nx/release`. Your updated script should look like this: + +```typescript +/** + * This script starts a local registry for e2e testing purposes. + * It is meant to be called in jest's globalSetup. + */ +import { startLocalRegistry } from '@nx/js/plugins/jest/local-registry'; +import { execFileSync } from 'child_process'; +import { releasePublish, releaseVersion } from 'nx/release'; + +export default async () => { + // local registry target to run + const localRegistryTarget = '@demo-plugin-1800/source:local-registry'; + // storage folder for the local registry + const storage = './tmp/local-registry/storage'; + + global.stopLocalRegistry = await startLocalRegistry({ + localRegistryTarget, + storage, + verbose: false, + }); + + await releaseVersion({ + specifier: '0.0.0-e2e', + stageChanges: false, + gitCommit: false, + gitTag: false, + firstRelease: true, + generatorOptionsOverrides: { + skipLockFileUpdate: true, + }, + }); + await releasePublish({ + tag: 'e2e', + firstRelease: true, + }); +}; +``` diff --git a/docs/shared/recipes/plugins/project-graph-plugins.md b/docs/shared/recipes/plugins/project-graph-plugins.md index 1851a25e271ed..f974ca69323fc 100644 --- a/docs/shared/recipes/plugins/project-graph-plugins.md +++ b/docs/shared/recipes/plugins/project-graph-plugins.md @@ -222,7 +222,7 @@ As an example, the below `nx.json` file specifies a plugin called `my-plugin` an { "plugins": [ { - "name": "my-plugin", + "plugin": "my-plugin", "options": { "tagName": "plugin:my-plugin" } diff --git a/docs/shared/reference/sitemap.md b/docs/shared/reference/sitemap.md index f384b2ed38223..450f94ef4e177 100644 --- a/docs/shared/reference/sitemap.md +++ b/docs/shared/reference/sitemap.md @@ -183,6 +183,7 @@ - [Publish in CI/CD](/recipes/nx-release/publish-in-ci-cd) - [Automate GitHub Releases](/recipes/nx-release/automate-github-releases) - [Publish Rust Crates](/recipes/nx-release/publish-rust-crates) + - [Update Your Local Registry Setup to use Nx Release](/recipes/nx-release/update-local-registry-setup) - [Other](/recipes/other) - [Rescope Packages from @nrwl to @nx](/recipes/other/rescope) - [Showcase](/showcase) @@ -294,15 +295,23 @@ - [Enable GitHub PR Integration](/ci/recipes/source-control-integration/github) - [Enable Bitbucket Cloud PR Integration](/ci/recipes/source-control-integration/bitbucket-cloud) - [Enable GitLab MR Integration](/ci/recipes/source-control-integration/gitlab) - - [On-Premise](/ci/recipes/on-premise) - - [Authenticate with a Single Admin](/ci/recipes/on-premise/auth-single-admin) - - [Authenticate with GitHub](/ci/recipes/on-premise/auth-github) - - [On-Prem VM Setup](/ci/recipes/on-premise/ami-setup) - - [Authenticate with GitLab](/ci/recipes/on-premise/auth-gitlab) - - [Authenticate with BitBucket](/ci/recipes/on-premise/auth-bitbucket) - - [Authenticate via SAML](/ci/recipes/on-premise/auth-saml) - - [Authenticate via SAML on Managed Version](/ci/recipes/on-premise/auth-saml-managed) - - [Advanced Configuration](/ci/recipes/on-premise/advanced-config) + - [Enterprise](/ci/recipes/enterprise) + - [On-Premise](/ci/recipes/enterprise/on-premise) + - [Authenticate with a Single Admin](/ci/recipes/enterprise/on-premise/auth-single-admin) + - [Authenticate with GitHub](/ci/recipes/enterprise/on-premise/auth-github) + - [On-Prem VM Setup](/ci/recipes/enterprise/on-premise/ami-setup) + - [Authenticate with GitLab](/ci/recipes/enterprise/on-premise/auth-gitlab) + - [Authenticate with BitBucket](/ci/recipes/enterprise/on-premise/auth-bitbucket) + - [Authenticate via SAML](/ci/recipes/enterprise/on-premise/auth-saml) + - [Authenticate via SAML on Managed Version](/ci/recipes/enterprise/on-premise/auth-saml-managed) + - [Advanced Configuration](/ci/recipes/enterprise/on-premise/advanced-config) + - [Custom Distributed Task Execution](/ci/recipes/enterprise/dte) + - [GitHub Actions Custom DTE](/ci/recipes/enterprise/dte/github-dte) + - [Circle CI Custom DTE](/ci/recipes/enterprise/dte/circle-ci-dte) + - [Azure Pipelines Custom DTE](/ci/recipes/enterprise/dte/azure-dte) + - [Bitbucket Pipelines Custom DTE](/ci/recipes/enterprise/dte/bitbucket-dte) + - [GitLab Custom DTE](/ci/recipes/enterprise/dte/gitlab-dte) + - [Jenkins Custom DTE](/ci/recipes/enterprise/dte/jenkins-dte) - [Troubleshooting](/ci/recipes/troubleshooting) - [CI Execution Failed](/ci/recipes/troubleshooting/ci-execution-failed) - [Other](/ci/recipes/other) diff --git a/e2e/esbuild/src/esbuild.test.ts b/e2e/esbuild/src/esbuild.test.ts index 70989bbf85ffc..5ed6b47f3e740 100644 --- a/e2e/esbuild/src/esbuild.test.ts +++ b/e2e/esbuild/src/esbuild.test.ts @@ -10,12 +10,10 @@ import { readJson, runCLI, runCommand, - runCommandUntil, tmpProjPath, uniq, updateFile, updateJson, - waitUntil, } from '@nx/e2e/utils'; import { join } from 'path'; @@ -44,6 +42,7 @@ describe('EsBuild Plugin', () => { expect(packageJson).toEqual({ name: `@proj/${myPkg}`, version: '0.0.1', + private: true, type: 'commonjs', main: './index.cjs', dependencies: {}, diff --git a/e2e/eslint/src/linter.test.ts b/e2e/eslint/src/linter.test.ts index 9d7d9405ee752..5654460696ef9 100644 --- a/e2e/eslint/src/linter.test.ts +++ b/e2e/eslint/src/linter.test.ts @@ -497,6 +497,7 @@ describe('Linter', () => { }, "main": "./src/index.js", "name": "@proj/${mylib}", + "private": true, "type": "commonjs", "typings": "./src/index.d.ts", "version": "0.0.1", diff --git a/e2e/next-extensions/src/next-component-tests.test.ts b/e2e/next-extensions/src/next-component-tests.test.ts index d36326c1968ae..e25a328a8aa34 100644 --- a/e2e/next-extensions/src/next-component-tests.test.ts +++ b/e2e/next-extensions/src/next-component-tests.test.ts @@ -90,6 +90,14 @@ describe('NextJs Component Testing', () => { ); } }); + + it('should test a NextJs server component that uses router', async () => { + const lib = uniq('next-lib'); + createLibWithCtCypress(lib); + if (runE2ETests()) { + expect(runCLI(`component-test ${lib}`)).toContain('All specs passed!'); + } + }, 600_000); }); function addBabelSupport(path: string) { @@ -203,6 +211,49 @@ export default Button; `generate @nx/next:cypress-component-configuration --project=${libName} --generate-tests --no-interactive` ); } + +function createLibWithCtCypress(libName: string) { + runCLI( + `generate @nx/next:lib ${libName} --no-interactive --projectNameAndRootFormat=as-provided` + ); + + runCLI( + `generate @nx/next:cypress-component-configuration --project=${libName} --no-interactive` + ); + + updateFile(`${libName}/src/lib/hello-server.tsx`, () => { + return `import { useRouter } from 'next/router'; + + export function HelloServer() { + useRouter(); + + return

Hello Server

; + } + `; + }); + // Add cypress component test + createFile( + `${libName}/src/lib/hello-server.cy.tsx`, + `import * as Router from 'next/router'; + import { HelloServer } from './hello-server'; + + describe('HelloServer', () => { + context('stubbing out \`useRouter\` hook', () => { + let router; + beforeEach(() => { + router = cy.stub(); + + cy.stub(Router, 'useRouter').returns(router); + }); + it('should work', () => { + cy.mount(); + }); + }); + }); + + ` + ); +} function addTailwindToLib(libName: string) { createFile(`libs/${libName}/src/lib/styles.css`, ``); runCLI( diff --git a/e2e/nx-misc/src/extras.test.ts b/e2e/nx-misc/src/extras.test.ts index 21b9db9c1634e..b6850e40373d9 100644 --- a/e2e/nx-misc/src/extras.test.ts +++ b/e2e/nx-misc/src/extras.test.ts @@ -153,6 +153,21 @@ describe('Extra Nx Misc Tests', () => { expect(result).toContain('--var1=a'); }, 120000); + it('should pass unknown options', async () => { + updateJson(join('libs', mylib, 'project.json'), (config) => { + config.targets.echo = { + command: 'echo', + options: { + var1: 'a', + }, + }; + return config; + }); + + const result = runCLI(`run ${mylib}:echo`, { silent: true }); + expect(result).toContain('--var1 a'); + }, 120000); + it('should interpolate provided arguments', async () => { const echoTarget = uniq('echo'); updateJson(join('libs', mylib, 'project.json'), (config) => { diff --git a/e2e/plugin/src/nx-plugin.test.ts b/e2e/plugin/src/nx-plugin.test.ts index 6b17ca7500487..51a258c564415 100644 --- a/e2e/plugin/src/nx-plugin.test.ts +++ b/e2e/plugin/src/nx-plugin.test.ts @@ -16,11 +16,11 @@ import { } from '@nx/e2e/utils'; import type { PackageJson } from 'nx/src/utils/package-json'; +import { join } from 'path'; import { ASYNC_GENERATOR_EXECUTOR_CONTENTS, NX_PLUGIN_V2_CONTENTS, } from './nx-plugin.fixtures'; -import { join } from 'path'; describe('Nx Plugin', () => { let workspaceName: string; @@ -50,6 +50,7 @@ describe('Nx Plugin', () => { expect(project).toMatchObject({ tags: [], }); + runCLI(`e2e ${plugin}-e2e`); }, 90000); diff --git a/e2e/release/src/pre-version-command.test.ts b/e2e/release/src/pre-version-command.test.ts new file mode 100644 index 0000000000000..cada8beda6ae8 --- /dev/null +++ b/e2e/release/src/pre-version-command.test.ts @@ -0,0 +1,117 @@ +import { + cleanupProject, + newProject, + runCLI, + uniq, + updateJson, +} from '@nx/e2e/utils'; + +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}') + // 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()) + .join('\n') + ); + }, + test(val: string) { + return val != null && typeof val === 'string'; + }, +}); + +describe('nx release pre-version command', () => { + let pkg1: string; + + beforeAll(() => { + newProject({ + unsetProjectNameAndRootFormat: false, + packages: ['@nx/js'], + }); + + pkg1 = uniq('my-pkg-1'); + runCLI( + `generate @nx/js:library ${pkg1} --publishable --importPath=${pkg1}` + ); + }); + afterAll(() => cleanupProject()); + + it('should run pre-version command before versioning step', async () => { + updateJson(`nx.json`, (json) => { + delete json.release; + return json; + }); + const result1 = runCLI('release patch -d --first-release', { + silenceError: true, + }); + + // command should fail because @nx/js:library configures the packageRoot to be dist/{project-name}, which doesn't exist yet + expect(result1).toContain( + `NX The project "${pkg1}" does not have a package.json available at dist/${pkg1}/package.json.` + ); + + updateJson(`nx.json`, (json) => { + json.release = { + version: { + preVersionCommand: 'nx run-many -t build', + }, + }; + return json; + }); + + // command should succeed because the pre-version command will build the package + const result2 = runCLI('release patch -d --first-release'); + + expect(result2).toContain('NX Executing pre-version command'); + + const result3 = runCLI('release patch -d --first-release --verbose'); + + expect(result3).toContain('NX Executing pre-version command'); + expect(result3).toContain('Executing the following pre-version command:'); + expect(result3).toContain('nx run-many -t build'); + expect(result3).toContain(`NX Running target build for project ${pkg1}:`); + + updateJson(`nx.json`, (json) => { + json.release = { + version: { + preVersionCommand: 'echo "error" && exit 1', + }, + }; + return json; + }); + + // command should fail because the pre-version command will fail + const result4 = runCLI('release patch -d --first-release', { + silenceError: true, + }); + expect(result4).toContain( + 'NX The pre-version command failed. Retry with --verbose to see the full output of the pre-version command.' + ); + expect(result4).toContain('echo "error" && exit 1'); + + const result5 = runCLI('release patch -d --first-release --verbose', { + silenceError: true, + }); + expect(result5).toContain( + 'NX The pre-version command failed. See the full output above.' + ); + expect(result4).toContain('echo "error" && exit 1'); + }); +}); diff --git a/e2e/release/src/private-js-packages.test.ts b/e2e/release/src/private-js-packages.test.ts index 46f46dcf76d15..f11be2e8473b0 100644 --- a/e2e/release/src/private-js-packages.test.ts +++ b/e2e/release/src/private-js-packages.test.ts @@ -92,7 +92,12 @@ describe('nx release - private JS packages', () => { }); afterAll(() => cleanupProject()); - it('should skip private packages and log a warning', async () => { + it('should skip private packages and log a warning when private packages are explicitly configured', async () => { + updateJson('nx.json', (json) => { + json.release.projects = [publicPkg1, publicPkg2, privatePkg]; + return json; + }); + runCLI(`release version 999.9.9`); // This is the verdaccio instance that the e2e tests themselves are working from @@ -222,4 +227,92 @@ describe('nx release - private JS packages', () => { /npm ERR! code E404/ ); }, 500000); + + it('should skip private packages and not log a warning when no projects config exists', async () => { + updateJson('nx.json', (json) => { + delete json.release.projects; + return json; + }); + + runCLI(`release version 999.9.10`); + + // This is the verdaccio instance that the e2e tests themselves are working from + const e2eRegistryUrl = execSync('npm config get registry') + .toString() + .trim(); + + // Thanks to the custom serializer above, the publish output should be deterministic + const publishOutput = runCLI(`release publish`); + expect(publishOutput).toMatchInlineSnapshot(` + + NX Running target nx-release-publish for 2 projects: + + - {public-project-name} + - {public-project-name} + + + + > nx run {public-project-name}:nx-release-publish + + + 📦 @proj/{public-project-name}@999.9.10 + === Tarball Contents === + + XXB index.js + XXXB package.json + XXB project.json + === Tarball Details === + name: @proj/{public-project-name} + version: 999.9.10 + filename: proj-{public-project-name}-999.9.10.tgz + package size: XXXB + unpacked size: XXXB + shasum: {SHASUM} + integrity: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + total files: 3 + + Published to http://localhost:4873 with tag "latest" + + > nx run {public-project-name}:nx-release-publish + + + 📦 @proj/{public-project-name}@999.9.10 + === Tarball Contents === + + XXB index.js + XXXB package.json + XXB project.json + === Tarball Details === + name: @proj/{public-project-name} + version: 999.9.10 + filename: proj-{public-project-name}-999.9.10.tgz + package size: XXXB + unpacked size: XXXB + shasum: {SHASUM} + integrity: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + total files: 3 + + Published to http://localhost:4873 with tag "latest" + + + + NX Successfully ran target nx-release-publish for 2 projects + + + + `); + + // The two public packages should have been published + expect( + execSync(`npm view @proj/${publicPkg1} version`).toString().trim() + ).toEqual('999.9.10'); + expect( + execSync(`npm view @proj/${publicPkg2} version`).toString().trim() + ).toEqual('999.9.10'); + + // The private package should have never been published + expect(() => execSync(`npm view @proj/${privatePkg} version`)).toThrowError( + /npm ERR! code E404/ + ); + }, 500000); }); diff --git a/e2e/workspace-create/src/create-nx-plugin.test.ts b/e2e/workspace-create/src/create-nx-plugin.test.ts index d54ddbc71ff11..dc51b5fa62756 100644 --- a/e2e/workspace-create/src/create-nx-plugin.test.ts +++ b/e2e/workspace-create/src/create-nx-plugin.test.ts @@ -1,11 +1,11 @@ import { checkFilesExist, + cleanupProject, getSelectedPackageManager, packageManagerLockFile, runCLI, - uniq, runCreatePlugin, - cleanupProject, + uniq, } from '@nx/e2e/utils'; describe('create-nx-plugin', () => { diff --git a/graph/client-e2e/project.json b/graph/client-e2e/project.json index 3df348232d39f..358bd058f230e 100644 --- a/graph/client-e2e/project.json +++ b/graph/client-e2e/project.json @@ -47,7 +47,7 @@ "parallel": false } }, - "e2e": { + "e2e-disabled-jason-re-enable-this": { "executor": "nx:run-commands", "outputs": [], "options": { diff --git a/graph/client/src/app/routes.tsx b/graph/client/src/app/routes.tsx index 5f9b99851245e..2fc24977988ac 100644 --- a/graph/client/src/app/routes.tsx +++ b/graph/client/src/app/routes.tsx @@ -5,12 +5,15 @@ import { Shell } from './shell'; /* eslint-disable @nx/enforce-module-boundaries */ // nx-ignore-next-line import { ProjectGraphClientResponse } from 'nx/src/command-line/graph/graph'; +// nx-ignore-next-line +import type { ProjectGraphProjectNode } from 'nx/src/config/project-graph'; import { getEnvironmentConfig, getProjectGraphDataService, } from '@nx/graph/shared'; import { TasksSidebarErrorBoundary } from './feature-tasks/tasks-sidebar-error-boundary'; import { ProjectDetailsPage } from '@nx/graph/project-details'; +import { ErrorBoundary } from './ui-components/error-boundary'; const { appConfig } = getEnvironmentConfig(); const projectGraphDataService = getProjectGraphDataService(); @@ -71,7 +74,11 @@ const sourceMapsLoader = async (selectedWorkspaceId: string) => { const projectDetailsLoader = async ( selectedWorkspaceId: string, projectName: string -) => { +): Promise<{ + hash: string; + project: ProjectGraphProjectNode; + sourceMap: Record; +}> => { const workspaceData = await workspaceDataLoader(selectedWorkspaceId); const sourceMaps = await sourceMapsLoader(selectedWorkspaceId); @@ -152,6 +159,7 @@ const childRoutes: RouteObject[] = [ export const devRoutes: RouteObject[] = [ { path: '/', + errorElement: , children: [ { index: true, @@ -181,7 +189,7 @@ export const devRoutes: RouteObject[] = [ path: ':selectedWorkspaceId/project-details/:projectName', id: 'selectedProjectDetails', element: , - loader: async ({ request, params }) => { + loader: async ({ params }) => { const projectName = params.projectName; return projectDetailsLoader(params.selectedWorkspaceId, projectName); }, @@ -194,7 +202,7 @@ export const releaseRoutes: RouteObject[] = [ { path: '/', id: 'selectedWorkspace', - loader: async ({ request, params }) => { + loader: async () => { const selectedWorkspaceId = appConfig.defaultWorkspaceId; return workspaceDataLoader(selectedWorkspaceId); }, @@ -213,12 +221,14 @@ export const releaseRoutes: RouteObject[] = [ }, ...childRoutes, ], + errorElement: , }, { path: 'project-details/:projectName', id: 'selectedProjectDetails', element: , - loader: async ({ request, params }) => { + errorElement: , + loader: async ({ params }) => { const projectName = params.projectName; return projectDetailsLoader(appConfig.defaultWorkspaceId, projectName); }, diff --git a/graph/client/src/app/shell.tsx b/graph/client/src/app/shell.tsx index ecfa074d0260b..a670617bf57a8 100644 --- a/graph/client/src/app/shell.tsx +++ b/graph/client/src/app/shell.tsx @@ -6,9 +6,14 @@ import { import classNames from 'classnames'; import { DebuggerPanel } from './ui-components/debugger-panel'; import { getGraphService } from './machines/graph.service'; -import { Outlet, useNavigate, useParams } from 'react-router-dom'; +import { + Outlet, + useNavigate, + useNavigation, + useParams, +} from 'react-router-dom'; import { getSystemTheme, Theme, ThemePanel } from '@nx/graph/ui-theme'; -import { Dropdown } from '@nx/graph/ui-components'; +import { Dropdown, Spinner } from '@nx/graph/ui-components'; import { useCurrentPath } from './hooks/use-current-path'; import { ExperimentalFeature } from './ui-components/experimental-feature'; import { RankdirPanel } from './feature-projects/panels/rankdir-panel'; @@ -36,8 +41,9 @@ export function Shell(): JSX.Element { } const navigate = useNavigate(); + const { state: navigationState } = useNavigation(); const currentPath = useCurrentPath(); - const { selectedWorkspaceId, selectedTaskId } = useParams(); + const { selectedWorkspaceId } = useParams(); const currentRoute = currentPath.currentPath; const topLevelRoute = currentRoute.startsWith('/tasks') @@ -165,17 +171,23 @@ export function Shell(): JSX.Element { > ) : null} - {!nodesVisible ? ( + {!nodesVisible || navigationState === 'loading' ? (
- -

- Please select a{' '} - {currentRoute.startsWith('/tasks') ? 'task' : 'project'} in the - sidebar. -

+ {navigationState === 'loading' ? ( + + ) : ( + <> + +

+ Please select a{' '} + {currentRoute.startsWith('/tasks') ? 'task' : 'project'} in + the sidebar. +

+ + )}
) : null} diff --git a/graph/client/src/app/ui-components/error-boundary.tsx b/graph/client/src/app/ui-components/error-boundary.tsx new file mode 100644 index 0000000000000..561a95a691be5 --- /dev/null +++ b/graph/client/src/app/ui-components/error-boundary.tsx @@ -0,0 +1,27 @@ +import { useEnvironmentConfig } from '@nx/graph/shared'; +import { ProjectDetailsHeader } from 'graph/project-details/src/lib/project-details-header'; +import { useRouteError } from 'react-router-dom'; + +export function ErrorBoundary() { + let error = useRouteError()?.toString(); + console.error(error); + const environment = useEnvironmentConfig()?.environment; + + let message = 'Disconnected from graph server. '; + if (environment === 'nx-console') { + message += 'Please refresh the page.'; + } else { + message += 'Please rerun your command and refresh the page.'; + } + + return ( +
+ +

Error

+
+

{message}

+

Error message: {error}

+
+
+ ); +} diff --git a/graph/project-details/src/lib/project-details-header.tsx b/graph/project-details/src/lib/project-details-header.tsx new file mode 100644 index 0000000000000..c167c662baf97 --- /dev/null +++ b/graph/project-details/src/lib/project-details-header.tsx @@ -0,0 +1,25 @@ +import { Link } from 'react-router-dom'; +import { useRouteConstructor } from '@nx/graph/shared'; +import { ThemePanel } from '@nx/graph/ui-theme'; + +export function ProjectDetailsHeader() { + const routeConstructor = useRouteConstructor(); + return ( +
+
+ + + Nx + + + + +
+
+ ); +} diff --git a/graph/project-details/src/lib/project-details-page.tsx b/graph/project-details/src/lib/project-details-page.tsx index 3d90800b9184f..c6e85a8992d86 100644 --- a/graph/project-details/src/lib/project-details-page.tsx +++ b/graph/project-details/src/lib/project-details-page.tsx @@ -2,7 +2,6 @@ // nx-ignore-next-line import { ProjectGraphProjectNode } from '@nx/devkit'; import { - Link, ScrollRestoration, useParams, useRouteLoaderData, @@ -13,9 +12,8 @@ import { getProjectGraphDataService, useEnvironmentConfig, useIntervalWhen, - useRouteConstructor, } from '@nx/graph/shared'; -import { ThemePanel } from '@nx/graph/ui-theme'; +import { ProjectDetailsHeader } from './project-details-header'; export function ProjectDetailsPage() { const { project, sourceMap, hash } = useRouteLoaderData( @@ -46,28 +44,11 @@ export function ProjectDetailsPage() { watch ); - const routeConstructor = useRouteConstructor(); - return (
{environment !== 'nx-console' ? ( -
-
- - - Nx - - - - -
-
+ ) : (
)} diff --git a/graph/ui-components/src/index.ts b/graph/ui-components/src/index.ts index 09e0853c0eeb9..82bc51d1ec3fe 100644 --- a/graph/ui-components/src/index.ts +++ b/graph/ui-components/src/index.ts @@ -1,3 +1,4 @@ export * from './lib/debounced-text-input'; export * from './lib/tag'; export * from './lib/dropdown'; +export * from './lib/spinner'; diff --git a/graph/ui-components/src/lib/spinner.stories.tsx b/graph/ui-components/src/lib/spinner.stories.tsx new file mode 100644 index 0000000000000..c7d7036e05a88 --- /dev/null +++ b/graph/ui-components/src/lib/spinner.stories.tsx @@ -0,0 +1,16 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Spinner } from './spinner'; + +const meta: Meta = { + component: Spinner, + title: 'Shared/Spinner', +}; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + args: { + className: '', + }, +}; diff --git a/graph/ui-components/src/lib/spinner.tsx b/graph/ui-components/src/lib/spinner.tsx new file mode 100644 index 0000000000000..500a5190cc05b --- /dev/null +++ b/graph/ui-components/src/lib/spinner.tsx @@ -0,0 +1,31 @@ +/** + * Spinner component from https://tailwindcss.com/docs/animation#spin + */ + +import React from 'react'; + +export type SpinnerProps = React.SVGProps; + +export function Spinner({ className, ...rest }: SpinnerProps) { + return ( + + + + + ); +} diff --git a/graph/ui-project-details/src/lib/target-configuration-details/target-configuration-details.tsx b/graph/ui-project-details/src/lib/target-configuration-details/target-configuration-details.tsx index c2554e87f7482..6d987cd30f2fe 100644 --- a/graph/ui-project-details/src/lib/target-configuration-details/target-configuration-details.tsx +++ b/graph/ui-project-details/src/lib/target-configuration-details/target-configuration-details.tsx @@ -4,9 +4,7 @@ import { ChevronDownIcon, ChevronUpIcon, EyeIcon, - InformationCircleIcon, PlayIcon, - QuestionMarkCircleIcon, } from '@heroicons/react/24/outline'; // nx-ignore-next-line @@ -283,7 +281,7 @@ export const TargetConfigurationDetails = forwardRef( )} -

+

{executorLink ? ( = [ }, { title: 'Auth (Basic)', - path: '/ci/recipes/on-premise/auth-single-admin', + path: '/ci/recipes/enterprise/on-premise/auth-single-admin', }, { title: 'GitHub Auth', - path: '/ci/recipes/on-premise/auth-github', + path: '/ci/recipes/enterprise/on-premise/auth-github', }, { title: 'GitLab Auth', - path: '/ci/recipes/on-premise/auth-gitlab', + path: '/ci/recipes/enterprise/on-premise/auth-gitlab', }, { title: 'Setting up a dedicated Nx Cloud VM', - path: '/ci/recipes/on-premise/ami-setup', + path: '/ci/recipes/enterprise/on-premise/ami-setup', }, { title: 'BitBucket Auth', - path: '/ci/recipes/on-premise/auth-bitbucket', + path: '/ci/recipes/enterprise/on-premise/auth-bitbucket', }, { title: 'SAML Auth', - path: '/ci/recipes/on-premise/auth-saml', + path: '/ci/recipes/enterprise/on-premise/auth-saml', }, { title: 'Advanced Configuration', - path: '/ci/recipes/on-premise/advanced-config', + path: '/ci/recipes/enterprise/on-premise/advanced-config', }, { title: 'Configuring the Cloud Runner / Nx CLI', diff --git a/nx-dev/nx-dev/next-sitemap.config.js b/nx-dev/nx-dev/next-sitemap.config.js index 0a2caa2fe5a17..2815b1a32e313 100644 --- a/nx-dev/nx-dev/next-sitemap.config.js +++ b/nx-dev/nx-dev/next-sitemap.config.js @@ -1,4 +1,4 @@ -const path = require('node:path'); +const path = require('path'); module.exports = { siteUrl: process.env.SITE_URL || 'https://nx.dev', diff --git a/nx-dev/nx-dev/next.config.js b/nx-dev/nx-dev/next.config.js index d02801b7a13c4..2880cb7382d74 100644 --- a/nx-dev/nx-dev/next.config.js +++ b/nx-dev/nx-dev/next.config.js @@ -3,8 +3,6 @@ const { withNx } = require('@nx/next/plugins/with-nx'); const redirectRules = require('./redirect-rules'); module.exports = withNx({ - // This is technically invalid, but we need to update our Vercel setting it order to change this. - distDir: '../../dist/nx-dev/nx-dev/.next', // For both client and server env: { VERCEL: process.env.VERCEL, diff --git a/nx-dev/nx-dev/project.json b/nx-dev/nx-dev/project.json index 28b9fa0cc365d..5c6685b8c6fcd 100644 --- a/nx-dev/nx-dev/project.json +++ b/nx-dev/nx-dev/project.json @@ -4,26 +4,15 @@ "sourceRoot": "nx-dev/nx-dev", "projectType": "application", "targets": { - "next-build": { - "dependsOn": ["copy-docs"] - }, - "next-dev": { - "dependsOn": ["copy-docs"], - "options": { - "args": "--port 4200" - } - }, - "next-start": { - "options": { - "args": "--port 4200" - } - }, "build": { - "dependsOn": ["next-build"], + "dependsOn": [ + { + "target": "build-base" + } + ], "executor": "nx:run-commands", "options": { "commands": [ - "ls -lsa dist/nx-dev/nx-dev/.next", "nx run nx-dev:sitemap", "ts-node -P ./scripts/tsconfig.scripts.json ./scripts/documentation/internal-link-checker.ts" ], @@ -35,13 +24,14 @@ "{workspaceRoot}/scripts/tsconfig.scripts.json", "{workspaceRoot}/scripts/documentation/internal-link-checker.ts" ], - "outputs": [ - "{workspaceRoot}/dist/nx-dev/nx-dev/.next", - "{workspaceRoot}/dist/nx-dev/nx-dev/.next/!(cache)" - ] + "outputs": ["{workspaceRoot}/dist/nx-dev/nx-dev"] }, "sitemap": { - "command": "pnpm next-sitemap --config ./nx-dev/nx-dev/next-sitemap.config.js" + "executor": "nx:run-commands", + "outputs": ["{workspaceRoot}/dist/nx-dev/nx-dev/public"], + "options": { + "command": "pnpm next-sitemap --config ./nx-dev/nx-dev/next-sitemap.config.js" + } }, "sync-documentation": { "executor": "nx:run-commands", @@ -57,6 +47,21 @@ "command": "ts-node -P ./scripts/tsconfig.scripts.json ./scripts/documentation/open-graph/generate-images.ts" } }, + "build-base": { + "executor": "@nx/next:build", + "dependsOn": ["copy-docs"], + "outputs": ["{options.outputPath}"], + "options": { + "root": "nx-dev/nx-dev", + "outputPath": "dist/nx-dev/nx-dev" + }, + "configurations": { + "development": { + "outputPath": "nx-dev/nx-dev" + }, + "production": {} + } + }, "copy-docs": { "inputs": ["{workspaceRoot}/docs/**/*"], "outputs": ["{projectRoot}/public/documentation"], @@ -70,11 +75,30 @@ "options": { "commands": [ "nx watch --projects=docs -- nx run nx-dev:copy-docs", - "nx run nx-dev:next-dev" + "nx run nx-dev:serve" ], "parallel": true } }, + "serve": { + "executor": "@nx/next:server", + "dependsOn": ["copy-docs"], + "options": { + "buildTarget": "nx-dev:build-base", + "dev": true + }, + "configurations": { + "production": { + "buildTarget": "nx-dev:build-base:production", + "dev": false + }, + "development": { + "buildTarget": "nx-dev:build-base:development", + "dev": true + } + }, + "defaultConfiguration": "development" + }, "deploy-build": { "executor": "nx:run-commands", "outputs": ["{projectRoot}/public/documentation"], @@ -105,6 +129,12 @@ "parallel": false } }, + "export": { + "executor": "@nx/next:export", + "options": { + "buildTarget": "nx-dev:build:production" + } + }, "lint": {}, "test": {} }, diff --git a/nx-dev/nx-dev/redirect-rules.js b/nx-dev/nx-dev/redirect-rules.js index da6050e6110b4..d41261dd78bdc 100644 --- a/nx-dev/nx-dev/redirect-rules.js +++ b/nx-dev/nx-dev/redirect-rules.js @@ -426,22 +426,41 @@ const nxCloudUrls = { '/core-features/distribute-task-execution': '/nx-cloud/features/distribute-task-execution', '/concepts/affected': '/ci/features/affected', - '/nx-cloud/private-cloud': '/ci/recipes/on-premise', + '/nx-cloud/private-cloud': '/ci/recipes/enterprise/on-premise', '/nx-cloud/private-cloud/get-started': '/ci/features/on-premise', '/nx-cloud/private-cloud/auth-single-admin': - '/nx-cloud/recipes/on-premise/auth-single-admin', + '/nx-cloud/recipes/enterprise/on-premise/auth-single-admin', '/nx-cloud/private-cloud/auth-github': - '/nx-cloud/recipes/on-premise/auth-github', - '/nx-cloud/private-cloud/ami-setup': '/ci/recipes/on-premise/ami-setup', + '/nx-cloud/recipes/enterprise/on-premise/auth-github', + '/nx-cloud/private-cloud/ami-setup': + '/ci/recipes/enterprise/on-premise/ami-setup', '/nx-cloud/private-cloud/auth-gitlab': - '/nx-cloud/recipes/on-premise/auth-gitlab', + '/nx-cloud/recipes/enterprise/on-premise/auth-gitlab', '/nx-cloud/private-cloud/auth-bitbucket': - '/nx-cloud/recipes/on-premise/auth-bitbucket', - '/nx-cloud/private-cloud/auth-saml': '/ci/recipes/on-premise/auth-saml', + '/nx-cloud/recipes/enterprise/on-premise/auth-bitbucket', + '/nx-cloud/private-cloud/auth-saml': + '/ci/recipes/enterprise/on-premise/auth-saml', '/nx-cloud/private-cloud/auth-saml-managed': - '/nx-cloud/recipes/on-premise/auth-saml-managed', + '/nx-cloud/recipes/enterprise/on-premise/auth-saml-managed', '/nx-cloud/private-cloud/advanced-config': - '/nx-cloud/recipes/on-premise/advanced-config', + '/nx-cloud/recipes/enterprise/on-premise/advanced-config', + '/ci/recipes/on-premise': '/ci/recipes/enterprise/on-premise', + '/ci/recipes/on-premise/auth-single-admin': + '/ci/recipes/enterprise/on-premise/auth-single-admin', + '/ci/recipes/on-premise/auth-github': + '/ci/recipes/enterprise/on-premise/auth-github', + '/ci/recipes/on-premise/ami-setup': + '/ci/recipes/enterprise/on-premise/ami-setup', + '/ci/recipes/on-premise/auth-gitlab': + '/ci/recipes/enterprise/on-premise/auth-gitlab', + '/ci/recipes/on-premise/auth-bitbucket': + '/ci/recipes/enterprise/on-premise/auth-bitbucket', + '/ci/recipes/on-premise/auth-saml': + '/ci/recipes/enterprise/on-premise/auth-saml', + '/ci/recipes/on-premise/auth-saml-managed': + '/ci/recipes/enterprise/on-premise/auth-saml-managed', + '/ci/recipes/on-premise/advanced-config': + '/ci/recipes/enterprise/on-premise/advanced-config', '/concepts/dte': '/ci/concepts/parallelization-distribution', '/nx-cloud/concepts/dte': '/ci/concepts/parallelization-distribution', '/nx-cloud/intro/nx-cloud-workflows': '/ci/features/nx-cloud-workflows', diff --git a/nx-dev/ui-fence/src/lib/fence.tsx b/nx-dev/ui-fence/src/lib/fence.tsx index 35e2cf78a2eec..92e9892c6341f 100644 --- a/nx-dev/ui-fence/src/lib/fence.tsx +++ b/nx-dev/ui-fence/src/lib/fence.tsx @@ -1,10 +1,9 @@ import { ClipboardDocumentCheckIcon, ClipboardDocumentIcon, - InformationCircleIcon, SparklesIcon, } from '@heroicons/react/24/outline'; -import { ReactNode, JSX, useEffect, useState } from 'react'; +import { JSX, ReactNode, useEffect, useState } from 'react'; // @ts-ignore import { CopyToClipboard } from 'react-copy-to-clipboard'; // @ts-ignore @@ -29,31 +28,20 @@ function CodeWrapper(options: { fileName: string; command: string; path: string; - isMessageBelow: boolean; language: string; children: string; // intentionally typed as such }): ({ children }: { children: ReactNode }) => JSX.Element { return ({ children }: { children: ReactNode }) => options.language === 'shell' ? ( - + ) : options.command ? ( ) : ( - + ); } @@ -138,6 +126,7 @@ export function Fence({ position: 'absolute', }; } + const highlightOptions = Object.keys(lineGroups).map((lineNumberKey) => ({ label: lineNumberKey, value: lineNumberKey, @@ -163,11 +152,11 @@ export function Fence({ t && clearTimeout(t); }; }, [copied]); - const showRescopeMessage = - (!skipRescope && children.includes('@nx/')) || command.includes('@nx/'); + function highlightChange(item: { label: string; value: string }) { onLineGroupSelectionChange?.(item.value); } + return (

@@ -217,24 +206,10 @@ export function Fence({ fileName, command, path, - isMessageBelow: showRescopeMessage, language, children, })} /> - {showRescopeMessage && ( - - - )}
); diff --git a/nx-dev/ui-fence/src/lib/fences/code-output.tsx b/nx-dev/ui-fence/src/lib/fences/code-output.tsx index 9dbeb29286db7..df5246b80affa 100644 --- a/nx-dev/ui-fence/src/lib/fences/code-output.tsx +++ b/nx-dev/ui-fence/src/lib/fences/code-output.tsx @@ -1,22 +1,14 @@ -import { cx } from '@nx/nx-dev/ui-primitives'; import { JSX, ReactNode } from 'react'; export function CodeOutput({ content, fileName, - isMessageBelow, }: { content: ReactNode; fileName: string; - isMessageBelow: boolean; }): JSX.Element { return ( -
+
{!!fileName && (
{fileName} diff --git a/nx-dev/ui-fence/src/lib/fences/terminal-output.tsx b/nx-dev/ui-fence/src/lib/fences/terminal-output.tsx index eebb77b97adef..34d366ac877ed 100644 --- a/nx-dev/ui-fence/src/lib/fences/terminal-output.tsx +++ b/nx-dev/ui-fence/src/lib/fences/terminal-output.tsx @@ -4,17 +4,15 @@ import { TerminalShellWrapper } from './terminal-shell'; export function TerminalOutput({ content, command, - isMessageBelow, path, }: { content: ReactNode | null; command: string; - isMessageBelow: boolean; path: string; }): JSX.Element { const commandLines = command.split('\n').filter(Boolean); return ( - +
{commandLines.map((line, index) => { diff --git a/nx-dev/ui-fence/src/lib/fences/terminal-shell.tsx b/nx-dev/ui-fence/src/lib/fences/terminal-shell.tsx index 9ebd1121ebf0c..c8685ba353ccd 100644 --- a/nx-dev/ui-fence/src/lib/fences/terminal-shell.tsx +++ b/nx-dev/ui-fence/src/lib/fences/terminal-shell.tsx @@ -1,20 +1,12 @@ -import { cx } from '@nx/nx-dev/ui-primitives'; import { JSX, ReactNode } from 'react'; export function TerminalShellWrapper({ - isMessageBelow, children, }: { - isMessageBelow: boolean; children: ReactNode; }): JSX.Element { return ( -
+
diff --git a/nx-dev/ui-markdoc/src/lib/icons.tsx b/nx-dev/ui-markdoc/src/lib/icons.tsx index 90881bfc3dd3f..9c6ab4623d463 100644 --- a/nx-dev/ui-markdoc/src/lib/icons.tsx +++ b/nx-dev/ui-markdoc/src/lib/icons.tsx @@ -159,6 +159,22 @@ export const frameworkIcons: Record< ), }, + nxagents: { + image: ( + + + + ), + }, nxcloud: { image: ( +
diff --git a/nx.json b/nx.json index c84790c1b8220..95b62d2497dff 100644 --- a/nx.json +++ b/nx.json @@ -1,8 +1,5 @@ { "$schema": "packages/nx/schemas/nx-schema.json", - "affected": { - "defaultBase": "master" - }, "namedInputs": { "default": ["{projectRoot}/**/*", "sharedGlobals"], "production": [ @@ -210,27 +207,11 @@ } } }, - "plugins": [ - "@monodon/rust", - { - "plugin": "@nx/next/plugin", - "options": { - "buildTargetName": "next-build", - "devTargetName": "next-dev", - "startTargetName": "next-start" - } - }, - { - "plugin": "@nx/playwright/plugin", - "options": { - "targetName": "pw-e2e", - "ciTargetName": "e2e-ci" - } - } - ], + "plugins": ["@monodon/rust"], "nxCloudAccessToken": "YmZiOWQyNzctOThiZC00MjYwLWI3YTAtZDA3MDg4YWY1YTExfHJlYWQ=", "nxCloudUrl": "https://staging.nx.app", "parallel": 1, "cacheDirectory": "/tmp/nx-cache", - "bust": 5 + "bust": 5, + "defaultBase": "master" } diff --git a/package.json b/package.json index d7c1b32aec815..2a65de049b26e 100644 --- a/package.json +++ b/package.json @@ -65,21 +65,21 @@ "@ngrx/store": "17.0.1", "@nuxt/kit": "^3.10.0", "@nuxt/schema": "^3.10.0", - "@nx/angular": "18.1.0-beta.1", - "@nx/cypress": "18.1.0-beta.1", - "@nx/devkit": "18.1.0-beta.1", - "@nx/esbuild": "18.1.0-beta.1", - "@nx/eslint": "18.1.0-beta.1", - "@nx/eslint-plugin": "18.1.0-beta.1", - "@nx/jest": "18.1.0-beta.1", - "@nx/js": "18.1.0-beta.1", - "@nx/next": "18.1.0-beta.1", - "@nx/playwright": "18.1.0-beta.1", - "@nx/react": "18.1.0-beta.1", - "@nx/storybook": "18.1.0-beta.1", - "@nx/vite": "18.1.0-beta.1", - "@nx/web": "18.1.0-beta.1", - "@nx/webpack": "18.1.0-beta.1", + "@nx/angular": "18.1.0-beta.3", + "@nx/cypress": "18.1.0-beta.3", + "@nx/devkit": "18.1.0-beta.3", + "@nx/esbuild": "18.1.0-beta.3", + "@nx/eslint": "18.1.0-beta.3", + "@nx/eslint-plugin": "18.1.0-beta.3", + "@nx/jest": "18.1.0-beta.3", + "@nx/js": "18.1.0-beta.3", + "@nx/next": "18.1.0-beta.3", + "@nx/playwright": "18.1.0-beta.3", + "@nx/react": "18.1.0-beta.3", + "@nx/storybook": "18.1.0-beta.3", + "@nx/vite": "18.1.0-beta.3", + "@nx/web": "18.1.0-beta.3", + "@nx/webpack": "18.1.0-beta.3", "@phenomnomnominal/tsquery": "~5.0.1", "@playwright/test": "^1.36.1", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7", @@ -155,7 +155,7 @@ "convert-source-map": "^2.0.0", "copy-webpack-plugin": "^10.2.4", "css-minimizer-webpack-plugin": "^5.0.0", - "cypress": "^13.0.0", + "cypress": "^13.6.6", "cytoscape": "^3.18.2", "cytoscape-dagre": "^2.4.0", "cytoscape-popper": "^2.0.0", @@ -232,7 +232,7 @@ "node-fetch": "^2.6.7", "npm-package-arg": "11.0.1", "nuxt": "^3.10.0", - "nx": "18.1.0-beta.1", + "nx": "18.1.0-beta.3", "octokit": "^2.0.14", "open": "^8.4.0", "openai": "~4.3.1", @@ -290,7 +290,7 @@ "use-sync-external-store": "^1.2.0", "verdaccio": "^5.0.4", "vite": "5.0.8", - "vitest": "^1.3.1", + "vitest": "1.3.1", "webpack": "5.88.0", "webpack-dev-server": "^4.9.3", "webpack-merge": "^5.8.0", diff --git a/packages/angular/package.json b/packages/angular/package.json index c222f898f4117..0fe46cac8d586 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -58,8 +58,6 @@ "webpack": "^5.80.0", "webpack-merge": "^5.8.0", "@nx/devkit": "file:../devkit", - "@nx/cypress": "file:../cypress", - "@nx/jest": "file:../jest", "@nx/js": "file:../js", "@nx/eslint": "file:../eslint", "@nx/webpack": "file:../webpack", @@ -69,11 +67,11 @@ }, "peerDependencies": { "@angular-devkit/build-angular": ">= 15.0.0 < 18.0.0", + "@angular-devkit/core": ">= 15.0.0 < 18.0.0", "@angular-devkit/schematics": ">= 15.0.0 < 18.0.0", "@schematics/angular": ">= 15.0.0 < 18.0.0", - "@angular-devkit/core": ">= 15.0.0 < 18.0.0", - "rxjs": "^6.5.3 || ^7.5.0", - "esbuild": "^0.19.2" + "esbuild": "^0.19.2", + "rxjs": "^6.5.3 || ^7.5.0" }, "peerDependenciesMeta": { "esbuild": { diff --git a/packages/angular/src/generators/application/lib/add-e2e.ts b/packages/angular/src/generators/application/lib/add-e2e.ts index 5ce0352dd0153..dc32d3a512b6a 100644 --- a/packages/angular/src/generators/application/lib/add-e2e.ts +++ b/packages/angular/src/generators/application/lib/add-e2e.ts @@ -1,4 +1,3 @@ -import { configurationGenerator } from '@nx/cypress'; import type { Tree } from '@nx/devkit'; import { addDependenciesToPackageJson, @@ -6,9 +5,9 @@ import { ensurePackage, getPackageManagerCommand, joinPathFragments, + readNxJson, readProjectConfiguration, updateProjectConfiguration, - readNxJson, } from '@nx/devkit'; import { nxVersion } from '../../../utils/versions'; import { getInstalledAngularVersionInfo } from '../../utils/version-utils'; @@ -22,6 +21,9 @@ export async function addE2e(tree: Tree, options: NormalizedSchema) { nxJson.useInferencePlugins !== false; if (options.e2eTestRunner === 'cypress') { + const { configurationGenerator } = ensurePackage< + typeof import('@nx/cypress') + >('@nx/cypress', nxVersion); // TODO: This can call `@nx/web:static-config` generator when ready addFileServerTarget(tree, options, 'serve-static'); addProjectConfiguration(tree, options.e2eProjectName, { @@ -44,11 +46,9 @@ export async function addE2e(tree: Tree, options: NormalizedSchema) { addPlugin, }); } else if (options.e2eTestRunner === 'playwright') { - const { configurationGenerator: playwrightConfigurationGenerator } = - ensurePackage( - '@nx/playwright', - nxVersion - ); + const { configurationGenerator } = ensurePackage< + typeof import('@nx/playwright') + >('@nx/playwright', nxVersion); addProjectConfiguration(tree, options.e2eProjectName, { projectType: 'application', root: options.e2eProjectRoot, @@ -56,7 +56,7 @@ export async function addE2e(tree: Tree, options: NormalizedSchema) { targets: {}, implicitDependencies: [options.name], }); - await playwrightConfigurationGenerator(tree, { + await configurationGenerator(tree, { project: options.e2eProjectName, skipFormat: true, skipPackageJson: options.skipPackageJson, diff --git a/packages/angular/src/generators/component-test/component-test.ts b/packages/angular/src/generators/component-test/component-test.ts index 8629f7acf350c..bfe567fe1282a 100644 --- a/packages/angular/src/generators/component-test/component-test.ts +++ b/packages/angular/src/generators/component-test/component-test.ts @@ -1,11 +1,12 @@ -import { assertMinimumCypressVersion } from '@nx/cypress/src/utils/cypress-version'; import { + ensurePackage, formatFiles, generateFiles, joinPathFragments, readProjectConfiguration, Tree, } from '@nx/devkit'; +import { nxVersion } from '../../utils/versions'; import { getArgsDefaultValue, getComponentProps, @@ -16,6 +17,10 @@ export async function componentTestGenerator( tree: Tree, options: ComponentTestSchema ) { + ensurePackage('@nx/cypress', nxVersion); + const { assertMinimumCypressVersion } = await import( + '@nx/cypress/src/utils/cypress-version' + ); assertMinimumCypressVersion(10); const { root } = readProjectConfiguration(tree, options.project); const componentDirPath = joinPathFragments(root, options.componentDir); diff --git a/packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.ts b/packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.ts index d9ea765869061..2e02c8d622df8 100644 --- a/packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.ts +++ b/packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.ts @@ -1,15 +1,7 @@ -import { componentConfigurationGenerator as baseCyCTConfig } from '@nx/cypress'; -import { NxComponentTestingOptions } from '@nx/cypress/plugins/cypress-preset'; -import { - addDefaultCTConfig, - addMountDefinition, - getProjectCypressConfigPath, -} from '@nx/cypress/src/utils/config'; -import { - findBuildConfig, - FoundTarget, -} from '@nx/cypress/src/utils/find-target-options'; +import type { NxComponentTestingOptions } from '@nx/cypress/plugins/cypress-preset'; +import type { FoundTarget } from '@nx/cypress/src/utils/find-target-options'; import { + ensurePackage, formatFiles, joinPathFragments, ProjectConfiguration, @@ -18,6 +10,7 @@ import { updateProjectConfiguration, } from '@nx/devkit'; import { relative } from 'path'; +import { nxVersion } from '../../utils/versions'; import { componentTestGenerator } from '../component-test/component-test'; import { getComponentsInfo, @@ -46,6 +39,9 @@ export async function cypressComponentConfigurationInternal( options: CypressComponentConfigSchema ) { const projectConfig = readProjectConfiguration(tree, options.project); + const { componentConfigurationGenerator: baseCyCTConfig } = ensurePackage< + typeof import('@nx/cypress') + >('@nx/cypress', nxVersion); const installTask = await baseCyCTConfig(tree, { project: options.project, skipFormat: true, @@ -78,6 +74,7 @@ async function addFiles( 'support', 'component.ts' ); + const { addMountDefinition } = await import('@nx/cypress/src/utils/config'); const updatedCmpContents = await addMountDefinition( tree.read(componentFile, 'utf-8') ); @@ -129,6 +126,9 @@ async function configureCypressCT( let found: FoundTarget = { target: options.buildTarget, config: undefined }; if (!options.buildTarget) { + const { findBuildConfig } = await import( + '@nx/cypress/src/utils/find-target-options' + ); found = await findBuildConfig(tree, { project: options.project, buildTarget: options.buildTarget, @@ -158,6 +158,9 @@ async function configureCypressCT( ctConfigOptions.buildTarget = found.target; } + const { addDefaultCTConfig, getProjectCypressConfigPath } = await import( + '@nx/cypress/src/utils/config' + ); const cypressConfigPath = getProjectCypressConfigPath( tree, projectConfig.root diff --git a/packages/angular/src/generators/ng-add/migrators/projects/e2e.migrator.ts b/packages/angular/src/generators/ng-add/migrators/projects/e2e.migrator.ts index 15aad5844476f..d49317a7f24d6 100644 --- a/packages/angular/src/generators/ng-add/migrators/projects/e2e.migrator.ts +++ b/packages/angular/src/generators/ng-add/migrators/projects/e2e.migrator.ts @@ -1,6 +1,3 @@ -import { configurationGenerator } from '@nx/cypress'; -import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset'; -import { installedCypressVersion } from '@nx/cypress/src/utils/cypress-version'; import type { ProjectConfiguration, TargetConfiguration, @@ -8,6 +5,7 @@ import type { } from '@nx/devkit'; import { addProjectConfiguration, + ensurePackage, joinPathFragments, offsetFromRoot, readJson, @@ -21,19 +19,15 @@ import { } from '@nx/devkit'; import { Linter, lintProjectGenerator } from '@nx/eslint'; import { getRootTsConfigPathInTree, insertImport } from '@nx/js'; +import { ensureTypescript } from '@nx/js/src/utils/typescript/ensure-typescript'; import { basename, relative } from 'path'; import type { Node, ObjectLiteralExpression, PropertyAssignment, } from 'typescript'; -import { - isObjectLiteralExpression, - isPropertyAssignment, - isStringLiteralLike, - isTemplateExpression, - SyntaxKind, -} from 'typescript'; +import { FileChangeRecorder } from '../../../../utils/file-change-recorder'; +import { nxVersion } from '../../../../utils/versions'; import type { GeneratorOptions } from '../../schema'; import type { Logger, @@ -41,9 +35,7 @@ import type { Target, ValidationResult, } from '../../utilities'; -import { FileChangeRecorder } from '../../../../utils/file-change-recorder'; import { ProjectMigrator } from './project.migrator'; -import { ensureTypescript } from '@nx/js/src/utils/typescript/ensure-typescript'; type SupportedTargets = 'e2e'; const supportedTargets: Record = { @@ -81,7 +73,7 @@ export class E2eMigrator extends ProjectMigrator { private appName: string; private isProjectUsingEsLint: boolean; private cypressInstalledVersion: number; - private cypressPreset: ReturnType; + private cypressPreset: Record; constructor( tree: Tree, @@ -269,6 +261,10 @@ export class E2eMigrator extends ProjectMigrator { newSourceRoot, }; } else if (this.isCypressE2eProject()) { + ensurePackage('@nx/cypress', nxVersion); + const { + installedCypressVersion, + } = require('@nx/cypress/src/utils/cypress-version'); this.cypressInstalledVersion = installedCypressVersion(); this.project = { ...this.project, @@ -347,6 +343,7 @@ export class E2eMigrator extends ProjectMigrator { const addPlugin = process.env.NX_ADD_PLUGINS !== 'false' && nxJson.useInferencePlugins !== false; + const { configurationGenerator } = await import('@nx/cypress'); await configurationGenerator(this.tree, { project: this.project.name, linter: this.isProjectUsingEsLint ? Linter.EsLint : Linter.None, @@ -556,8 +553,9 @@ export class E2eMigrator extends ProjectMigrator { } private updateCypress10ConfigFile(configFilePath: string): void { - ensureTypescript(); + const { isPropertyAssignment } = ensureTypescript(); const { tsquery } = require('@phenomnomnominal/tsquery'); + const { nxE2EPreset } = require('@nx/cypress/plugins/cypress-preset'); this.cypressPreset = nxE2EPreset(configFilePath); const fileContent = this.tree.read(configFilePath, 'utf-8'); @@ -614,6 +612,8 @@ export class E2eMigrator extends ProjectMigrator { return; } + const { isObjectLiteralExpression, isPropertyAssignment } = + ensureTypescript(); if (!isObjectLiteralExpression(componentNode.initializer)) { this.logger.warn( 'The automatic migration only supports having an object literal in the "component" option of the Cypress configuration. ' + @@ -656,6 +656,8 @@ export class E2eMigrator extends ProjectMigrator { },`; recorder.insertRight(defineConfigNode.getStart() + 1, e2eAssignment); } else { + const { isObjectLiteralExpression, isPropertyAssignment } = + ensureTypescript(); if (!isObjectLiteralExpression(e2eNode.initializer)) { this.logger.warn( 'The automatic migration only supports having an object literal in the "e2e" option of the Cypress configuration. ' + @@ -810,6 +812,12 @@ export class E2eMigrator extends ProjectMigrator { node: Node, properties: string[] ): boolean { + const { + isPropertyAssignment, + isStringLiteralLike, + isTemplateExpression, + SyntaxKind, + } = ensureTypescript(); if (!isPropertyAssignment(node)) { // TODO(leo): handle more scenarios (spread assignments, etc) return false; diff --git a/packages/angular/src/generators/setup-mf/lib/add-cypress-workaround.ts b/packages/angular/src/generators/setup-mf/lib/add-cypress-workaround.ts index 8d7b7560b5c76..adabc95e96822 100644 --- a/packages/angular/src/generators/setup-mf/lib/add-cypress-workaround.ts +++ b/packages/angular/src/generators/setup-mf/lib/add-cypress-workaround.ts @@ -2,7 +2,6 @@ // as Angular attempt to figure out how to fix HMR when styles.js // is attached to the index.html with type=module -import { CYPRESS_CONFIG_FILE_NAME_PATTERN } from '@nx/cypress/src/utils/config'; import type { ProjectConfiguration, Tree } from '@nx/devkit'; import { glob, @@ -32,13 +31,23 @@ export function addCypressOnErrorWorkaround(tree: Tree, schema: Schema) { return; } - if ( - e2eProject.targets?.e2e?.executor !== '@nx/cypress:cypress' && - !glob(tree, [`${e2eProject.root}/${CYPRESS_CONFIG_FILE_NAME_PATTERN}`]) - .length - ) { - // Not a cypress e2e project, skip - return; + if (e2eProject.targets?.e2e?.executor !== '@nx/cypress:cypress') { + try { + // don't ensure package is installed, if it's not installed, we don't need to add the workaround + const { + CYPRESS_CONFIG_FILE_NAME_PATTERN, + } = require('@nx/cypress/src/utils/config'); + if ( + !glob(tree, [`${e2eProject.root}/${CYPRESS_CONFIG_FILE_NAME_PATTERN}`]) + .length + ) { + // Not a cypress e2e project, skip + return; + } + } catch { + // assume cypress is not installed + return; + } } const commandToAdd = `Cypress.on('uncaught:exception', err => { diff --git a/packages/angular/src/generators/storybook-configuration/lib/generate-stories.ts b/packages/angular/src/generators/storybook-configuration/lib/generate-stories.ts index 8cef53eb73ca8..97b42004b25e6 100644 --- a/packages/angular/src/generators/storybook-configuration/lib/generate-stories.ts +++ b/packages/angular/src/generators/storybook-configuration/lib/generate-stories.ts @@ -1,6 +1,6 @@ -import { getE2eProjectName } from '@nx/cypress/src/utils/project-name'; import type { Tree } from '@nx/devkit'; -import { readProjectConfiguration } from '@nx/devkit'; +import { ensurePackage, readProjectConfiguration } from '@nx/devkit'; +import { nxVersion } from '../../../utils/versions'; import { angularStoriesGenerator } from '../../stories/stories'; import type { StorybookConfigurationOptions } from '../schema'; @@ -9,6 +9,10 @@ export async function generateStories( options: StorybookConfigurationOptions ) { const project = readProjectConfiguration(tree, options.project); + ensurePackage('@nx/cypress', nxVersion); + const { getE2eProjectName } = await import( + '@nx/cypress/src/utils/project-name' + ); const e2eProjectName = getE2eProjectName( options.project, project.root, diff --git a/packages/angular/src/generators/utils/add-jest.ts b/packages/angular/src/generators/utils/add-jest.ts index 2f7a81f820bdb..5261bdf375e03 100644 --- a/packages/angular/src/generators/utils/add-jest.ts +++ b/packages/angular/src/generators/utils/add-jest.ts @@ -1,6 +1,5 @@ -import { joinPathFragments, type Tree } from '@nx/devkit'; -import { configurationGenerator } from '@nx/jest'; -import { jestPresetAngularVersion } from '../../utils/versions'; +import { ensurePackage, joinPathFragments, type Tree } from '@nx/devkit'; +import { jestPresetAngularVersion, nxVersion } from '../../utils/versions'; import { addDependenciesToPackageJsonIfDontExist } from './version-utils'; export type AddJestOptions = { @@ -24,6 +23,10 @@ export async function addJest( ); } + const { configurationGenerator } = ensurePackage( + '@nx/jest', + nxVersion + ); await configurationGenerator(tree, { project: options.name, setupFile: 'angular', diff --git a/packages/cypress/src/generators/component-configuration/component-configuration.ts b/packages/cypress/src/generators/component-configuration/component-configuration.ts index 3dac12bad71e7..6d4078c297992 100644 --- a/packages/cypress/src/generators/component-configuration/component-configuration.ts +++ b/packages/cypress/src/generators/component-configuration/component-configuration.ts @@ -97,6 +97,7 @@ function normalizeOptions( return { addPlugin, ...options, + framework: options.framework ?? null, directory: options.directory ?? 'cypress', }; } diff --git a/packages/cypress/src/generators/component-configuration/files/__directory__/support/component-index.html b/packages/cypress/src/generators/component-configuration/files/__directory__/support/component-index.html index c23249f03407b..5d75dee47d659 100644 --- a/packages/cypress/src/generators/component-configuration/files/__directory__/support/component-index.html +++ b/packages/cypress/src/generators/component-configuration/files/__directory__/support/component-index.html @@ -5,7 +5,10 @@ <%= project %> Components App - + <% if(framework === 'next') { %> + +
+ <% } %>
diff --git a/packages/cypress/src/generators/component-configuration/schema.d.ts b/packages/cypress/src/generators/component-configuration/schema.d.ts index bd9aef559c8b2..791aabaa7cc92 100644 --- a/packages/cypress/src/generators/component-configuration/schema.d.ts +++ b/packages/cypress/src/generators/component-configuration/schema.d.ts @@ -10,4 +10,5 @@ export interface CypressComponentConfigurationSchema { * @internal */ addExplicitTargets?: boolean; + framework?: 'next'; } diff --git a/packages/cypress/src/generators/configuration/configuration.ts b/packages/cypress/src/generators/configuration/configuration.ts index 999cb5faca921..80049da8e52c9 100644 --- a/packages/cypress/src/generators/configuration/configuration.ts +++ b/packages/cypress/src/generators/configuration/configuration.ts @@ -125,7 +125,8 @@ function ensureDependencies(tree: Tree, options: NormalizedSchema) { } function normalizeOptions(tree: Tree, options: CypressE2EConfigSchema) { - const projectConfig = readProjectConfiguration(tree, options.project); + const projectConfig: ProjectConfiguration | undefined = + readProjectConfiguration(tree, options.project); if (projectConfig?.targets?.e2e) { throw new Error(`Project ${options.project} already has an e2e target. Rename or remove the existing e2e target.`); @@ -134,7 +135,7 @@ Rename or remove the existing e2e target.`); if ( !options.baseUrl && !options.devServerTarget && - !projectConfig.targets.serve + !projectConfig?.targets?.serve ) { throw new Error(`The project ${options.project} does not have a 'serve' target. In this case you need to provide a devServerTarget,':[:]', or a baseUrl option`); @@ -144,7 +145,7 @@ In this case you need to provide a devServerTarget,':[: const devServerTarget = options.devServerTarget ?? - (projectConfig.targets.serve ? `${options.project}:serve` : undefined); + (projectConfig?.targets?.serve ? `${options.project}:serve` : undefined); if (!options.baseUrl && !devServerTarget) { throw new Error('Either baseUrl or devServerTarget must be provided'); diff --git a/packages/cypress/src/utils/config.ts b/packages/cypress/src/utils/config.ts index 7f96fed552eed..43862c659c058 100644 --- a/packages/cypress/src/utils/config.ts +++ b/packages/cypress/src/utils/config.ts @@ -1,4 +1,4 @@ -import { glob, type Tree } from '@nx/devkit'; +import { glob, joinPathFragments, type Tree } from '@nx/devkit'; import type { InterfaceDeclaration, MethodSignature, @@ -168,7 +168,7 @@ export function getProjectCypressConfigPath( projectRoot: string ): string { const cypressConfigPaths = glob(tree, [ - `${projectRoot}/${CYPRESS_CONFIG_FILE_NAME_PATTERN}`, + joinPathFragments(projectRoot, CYPRESS_CONFIG_FILE_NAME_PATTERN), ]); if (cypressConfigPaths.length === 0) { throw new Error(`Could not find a cypress config file in ${projectRoot}.`); diff --git a/packages/devkit/src/utils/replace-project-configuration-with-plugin.spec.ts b/packages/devkit/src/utils/replace-project-configuration-with-plugin.spec.ts index 5875d42899e6f..cc06d8b5c80a4 100644 --- a/packages/devkit/src/utils/replace-project-configuration-with-plugin.spec.ts +++ b/packages/devkit/src/utils/replace-project-configuration-with-plugin.spec.ts @@ -1,10 +1,10 @@ -import { Tree } from 'nx/src/generators/tree'; -import { CreateNodes } from 'nx/src/utils/nx-plugin'; -import { createTreeWithEmptyWorkspace } from 'nx/src/generators/testing-utils/create-tree-with-empty-workspace'; import { addProjectConfiguration, + CreateNodes, readProjectConfiguration, -} from 'nx/src/generators/utils/project-configuration'; + Tree, +} from 'nx/src/devkit-exports'; +import { createTreeWithEmptyWorkspace } from 'nx/src/generators/testing-utils/create-tree-with-empty-workspace'; import { replaceProjectConfigurationsWithPlugin } from './replace-project-configuration-with-plugin'; diff --git a/packages/devkit/src/utils/replace-project-configuration-with-plugin.ts b/packages/devkit/src/utils/replace-project-configuration-with-plugin.ts index 217d3ce28c89d..6ee2949253b19 100644 --- a/packages/devkit/src/utils/replace-project-configuration-with-plugin.ts +++ b/packages/devkit/src/utils/replace-project-configuration-with-plugin.ts @@ -1,9 +1,9 @@ import type { + Tree, + CreateNodes, ProjectConfiguration, TargetConfiguration, -} from 'nx/src/config/workspace-json-project-json'; -import type { Tree } from 'nx/src/generators/tree'; -import type { CreateNodes } from 'nx/src/utils/nx-plugin'; +} from 'nx/src/devkit-exports'; import { requireNx } from '../../nx'; const { readNxJson, diff --git a/packages/devkit/src/utils/update-package-scripts.spec.ts b/packages/devkit/src/utils/update-package-scripts.spec.ts index 42b190c9de29c..317cc5db24e90 100644 --- a/packages/devkit/src/utils/update-package-scripts.spec.ts +++ b/packages/devkit/src/utils/update-package-scripts.spec.ts @@ -235,30 +235,131 @@ describe('updatePackageScripts', () => { ); }); - it('should exclude all package.json scripts when none are excluded', async () => { - tree.write('next.config.js', ''); + it('should set "includedScripts" to an empty array when running "nx init"', async () => { + const originalEnvVarValue = process.env.NX_RUNNING_NX_INIT; + process.env.NX_RUNNING_NX_INIT = 'true'; + + tree.write('vite.config.ts', ''); writeJson(tree, 'package.json', { name: 'app1', scripts: { - build: 'next build', + build: 'vite build', + serve: 'vite', + test: 'vitest', + coverage: 'vitest run --coverage', + foo: 'echo "foo"', }, }); await updatePackageScripts(tree, [ - '**/next.config.{js,cjs,mjs}', + '**/{vite,vitest}.config.{js,ts,mjs,mts,cjs,cts}', () => ({ projects: { app1: { targets: { - build: { command: 'next build' }, + build: { command: 'vite build' }, + serve: { command: 'vite serve' }, + test: { command: 'vitest run' }, }, }, }, }), ]); - const { nx } = readJson(tree, 'package.json'); - expect(nx).toStrictEqual({ includedScripts: [] }); + const packageJson = readJson(tree, 'package.json'); + expect(packageJson.scripts).toStrictEqual({ + build: 'nx build', + serve: 'vite', + test: 'vitest', + coverage: 'nx test --coverage', + foo: 'echo "foo"', + }); + expect(packageJson.nx.includedScripts).toStrictEqual([]); + + process.env.NX_RUNNING_NX_INIT = originalEnvVarValue; + }); + + it('should set "includedScripts" to all scripts except the ones matching inferred target names when "includedScripts" is not set', async () => { + tree.write('vite.config.ts', ''); + writeJson(tree, 'package.json', { + name: 'app1', + scripts: { + build: 'vite build', + serve: 'vite', + test: 'vitest', + coverage: 'vitest run --coverage', + foo: 'echo "foo"', + }, + }); + + await updatePackageScripts(tree, [ + '**/{vite,vitest}.config.{js,ts,mjs,mts,cjs,cts}', + () => ({ + projects: { + app1: { + targets: { + build: { command: 'vite build' }, + serve: { command: 'vite serve' }, + test: { command: 'vitest run' }, + }, + }, + }, + }), + ]); + + const packageJson = readJson(tree, 'package.json'); + expect(packageJson.scripts).toStrictEqual({ + build: 'nx build', + serve: 'vite', + test: 'vitest', + coverage: 'nx test --coverage', + foo: 'echo "foo"', + }); + // "build": excluded because a script (itself) was replaced with a target "build" + // "serve" not excluded even though it matches the name of an inferred target because no script was replaced with a target "serve" + // "test" excluded even though it was not replaced because another script was replaced with a target "test" + // "coverage" not excluded even though it was replaced because it does not match a target + // "foo" not excluded because it does not match a target + expect(packageJson.nx.includedScripts).toStrictEqual([ + 'serve', + 'coverage', + 'foo', + ]); + }); + + it('should not set "nx.includedScripts" when no script matched an inferred target', async () => { + tree.write('vite.config.ts', ''); + writeJson(tree, 'package.json', { + name: 'app1', + scripts: { + serve: 'vite', + coverage: 'vitest run --coverage', + foo: 'echo "foo"', + }, + }); + + await updatePackageScripts(tree, [ + '**/{vite,vitest}.config.{js,ts,mjs,mts,cjs,cts}', + () => ({ + projects: { + app1: { + targets: { + build: { command: 'vite build' }, + serve: { command: 'vite serve' }, + test: { command: 'vitest run' }, + }, + }, + }, + }), + ]); + + const packageJson = readJson(tree, 'package.json'); + expect(packageJson.scripts).toStrictEqual({ + serve: 'vite', + coverage: 'nx test --coverage', + foo: 'echo "foo"', + }); + expect(packageJson.nx).toBeUndefined(); }); it('should exclude replaced package.json scripts from nx if they are initially included', async () => { @@ -288,6 +389,6 @@ describe('updatePackageScripts', () => { ]); const { nx } = readJson(tree, 'package.json'); - expect(nx).toStrictEqual({ includedScripts: ['foo'] }); + expect(nx.includedScripts).toStrictEqual(['foo']); }); }); diff --git a/packages/devkit/src/utils/update-package-scripts.ts b/packages/devkit/src/utils/update-package-scripts.ts index 8d57a598cd66f..6896f56d69d35 100644 --- a/packages/devkit/src/utils/update-package-scripts.ts +++ b/packages/devkit/src/utils/update-package-scripts.ts @@ -1,10 +1,10 @@ -import type { NxJsonConfiguration } from 'nx/src/config/nx-json'; -import type { Tree } from 'nx/src/generators/tree'; import type { CreateNodes, CreateNodesFunction, CreateNodesResult, -} from 'nx/src/utils/nx-plugin'; + NxJsonConfiguration, + Tree, +} from 'nx/src/devkit-exports'; import type { PackageJson } from 'nx/src/utils/package-json'; import { basename, dirname } from 'path'; import * as yargs from 'yargs-parser'; @@ -60,10 +60,7 @@ async function processProject( return; } - // exclude package.json scripts from nx - packageJson.nx ??= {}; - packageJson.nx.includedScripts ??= []; - + const replacedTargets = new Set(); for (const targetCommand of targetCommands) { const { command, target, configuration } = targetCommand; const targetCommandRegex = new RegExp( @@ -80,7 +77,7 @@ async function processProject( ? `$1nx ${target} --configuration=${configuration}$3` : `$1nx ${target}$3` ); - excludeScriptFromPackageJson(packageJson, scriptName); + replacedTargets.add(target); } else { /** * Parse script and command to handle the following: @@ -157,6 +154,7 @@ async function processProject( : `$1nx ${target}$4` ) ); + replacedTargets.add(target); } else { // there are different args or the script has extra args, replace with the command leaving the args packageJson.scripts[scriptName] = packageJson.scripts[ @@ -170,14 +168,34 @@ async function processProject( : `$1nx ${target}$3` ) ); + replacedTargets.add(target); } - - excludeScriptFromPackageJson(packageJson, scriptName); } } } } + if (process.env.NX_RUNNING_NX_INIT === 'true') { + // running `nx init` so we want to exclude everything by default + packageJson.nx ??= {}; + packageJson.nx.includedScripts = []; + } else if (replacedTargets.size) { + /** + * Running `nx add`. In this case we want to: + * - if `includedScripts` is already set: exclude scripts that match inferred targets that were used to replace a script + * - if `includedScripts` is not set: set `includedScripts` with all scripts except the ones that match an inferred target that was used to replace a script + */ + const includedScripts = + packageJson.nx?.includedScripts ?? Object.keys(packageJson.scripts); + const filteredScripts = includedScripts.filter( + (s) => !replacedTargets.has(s) + ); + if (filteredScripts.length !== includedScripts.length) { + packageJson.nx ??= {}; + packageJson.nx.includedScripts = filteredScripts; + } + } + writeJson(tree, packageJsonPath, packageJson); } @@ -228,15 +246,6 @@ function getInferredTargetCommands(result: CreateNodesResult): TargetCommand[] { return targetCommands; } -function excludeScriptFromPackageJson( - packageJson: PackageJson, - scriptName: string -) { - packageJson.nx.includedScripts = packageJson.nx.includedScripts.filter( - (s) => s !== scriptName - ); -} - function getProjectRootFromConfigFile(file: string): string { let projectRoot = dirname(file); if (basename(projectRoot) === '.storybook') { diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 752402cd8eb3b..092da91bf96cc 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -24,7 +24,7 @@ }, "homepage": "https://nx.dev", "peerDependencies": { - "@typescript-eslint/parser": "^6.13.2", + "@typescript-eslint/parser": "^6.13.2 || ^7.0.0", "eslint-config-prettier": "^9.0.0" }, "peerDependenciesMeta": { diff --git a/packages/js/src/generators/library/library.spec.ts b/packages/js/src/generators/library/library.spec.ts index 51e23626e2907..41488f28d620e 100644 --- a/packages/js/src/generators/library/library.spec.ts +++ b/packages/js/src/generators/library/library.spec.ts @@ -1,5 +1,7 @@ import { + getPackageManagerCommand, getProjects, + output, readJson, readProjectConfiguration, Tree, @@ -40,6 +42,7 @@ describe('lib', () => { }); expect(readJson(tree, '/my-lib/package.json')).toEqual({ name: '@proj/my-lib', + private: true, version: '0.0.1', type: 'commonjs', scripts: { @@ -1013,7 +1016,7 @@ describe('lib', () => { }); }); - it('should generate the publish target', async () => { + it('should update the nx-release-publish target to specify dist/{projectRoot} as the package root', async () => { await libraryGenerator(tree, { ...defaultOptions, name: 'my-lib', @@ -1024,24 +1027,356 @@ describe('lib', () => { }); const config = readProjectConfiguration(tree, 'my-lib'); - expect(config.targets.publish).toEqual({ - command: - 'node tools/scripts/publish.mjs my-lib {args.ver} {args.tag}', - dependsOn: ['build'], + expect(config.targets['nx-release-publish']).toEqual({ + options: { + packageRoot: 'dist/{projectRoot}', + }, }); }); - it('should generate publish script', async () => { - await libraryGenerator(tree, { - ...defaultOptions, - name: 'my-lib', - publishable: true, - importPath: '@proj/my-lib', - bundler: 'tsc', - projectNameAndRootFormat: 'as-provided', + describe('nx release config', () => { + it('should not change preVersionCommand if it already exists', async () => { + updateJson(tree, 'nx.json', (json) => { + json.release = { + version: { + preVersionCommand: 'echo "hello world"', + }, + }; + return json; + }); + + await libraryGenerator(tree, { + ...defaultOptions, + name: 'my-lib', + publishable: true, + importPath: '@proj/my-lib', + bundler: 'tsc', + projectNameAndRootFormat: 'as-provided', + }); + + 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; + }); + + await libraryGenerator(tree, { + ...defaultOptions, + name: 'my-lib', + publishable: true, + importPath: '@proj/my-lib', + bundler: 'tsc', + projectNameAndRootFormat: 'as-provided', + }); + + 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; + }); + + await libraryGenerator(tree, { + ...defaultOptions, + name: 'my-lib', + publishable: true, + importPath: '@proj/my-lib', + bundler: 'tsc', + projectNameAndRootFormat: 'as-provided', + }); + + 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; + }); + + await libraryGenerator(tree, { + ...defaultOptions, + name: 'my-lib', + publishable: true, + importPath: '@proj/my-lib', + bundler: 'tsc', + projectNameAndRootFormat: 'as-provided', + }); + + 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; + }); + + await libraryGenerator(tree, { + ...defaultOptions, + name: 'my-lib', + publishable: true, + importPath: '@proj/my-lib', + bundler: 'tsc', + projectNameAndRootFormat: 'as-provided', + }); + + const nxJson = readJson(tree, 'nx.json'); + expect(nxJson.release).toEqual({ + projects: ['something-else', 'my-lib'], + version: { + preVersionCommand: `${ + getPackageManagerCommand().dlx + } nx run-many -t build`, + }, + }); }); - expect(tree.exists('tools/scripts/publish.mjs')).toBeTruthy(); + 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; + }); + + await libraryGenerator(tree, { + ...defaultOptions, + name: 'my-lib', + publishable: true, + importPath: '@proj/my-lib', + bundler: 'tsc', + projectNameAndRootFormat: 'as-provided', + tags: 'one,two', + }); + + 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; + }); + + await libraryGenerator(tree, { + ...defaultOptions, + name: 'my-lib', + publishable: true, + importPath: '@proj/my-lib', + bundler: 'tsc', + projectNameAndRootFormat: 'as-provided', + directory: 'packages/my-lib', + }); + + 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; + }); + + await libraryGenerator(tree, { + ...defaultOptions, + name: 'my-lib', + publishable: true, + importPath: '@proj/my-lib', + bundler: 'tsc', + projectNameAndRootFormat: 'as-provided', + }); + + 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; + }); + + await libraryGenerator(tree, { + ...defaultOptions, + name: 'my-lib', + publishable: true, + importPath: '@proj/my-lib', + bundler: 'tsc', + projectNameAndRootFormat: 'as-provided', + }); + + 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; + }); + + await libraryGenerator(tree, { + ...defaultOptions, + name: 'my-lib', + publishable: true, + importPath: '@proj/my-lib', + bundler: 'tsc', + projectNameAndRootFormat: 'as-provided', + }); + + 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; + }); + + await libraryGenerator(tree, { + ...defaultOptions, + name: 'my-lib', + publishable: true, + importPath: '@proj/my-lib', + bundler: 'tsc', + projectNameAndRootFormat: 'as-provided', + }); + + 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(); + }); }); }); diff --git a/packages/js/src/generators/library/library.ts b/packages/js/src/generators/library/library.ts index a8066f739d767..48d1311087fde 100644 --- a/packages/js/src/generators/library/library.ts +++ b/packages/js/src/generators/library/library.ts @@ -5,10 +5,13 @@ import { formatFiles, generateFiles, GeneratorCallback, + getPackageManagerCommand, joinPathFragments, names, offsetFromRoot, + output, ProjectConfiguration, + ProjectGraphProjectNode, readNxJson, readProjectConfiguration, runTasksInSerial, @@ -22,15 +25,19 @@ import { type ProjectNameAndRootOptions, } from '@nx/devkit/src/generators/project-name-and-root-utils'; -import { - addTsConfigPath, - getRelativePathToRootTsConfig, -} from '../../utils/typescript/ts-config'; +import { addBuildTargetDefaults } from '@nx/devkit/src/generators/add-build-target-defaults'; +import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-command'; +import { findMatchingProjects } from 'nx/src/utils/find-matching-projects'; +import { type PackageJson } from 'nx/src/utils/package-json'; import { join } from 'path'; -import { addMinimalPublishScript } from '../../utils/minimal-publish-script'; import { Bundler, LibraryGeneratorSchema } from '../../utils/schema'; import { addSwcConfig } from '../../utils/swc/add-swc-config'; import { addSwcDependencies } from '../../utils/swc/add-swc-dependencies'; +import { tsConfigBaseOptions } from '../../utils/typescript/create-ts-config'; +import { + addTsConfigPath, + getRelativePathToRootTsConfig, +} from '../../utils/typescript/ts-config'; import { esbuildVersion, nxVersion, @@ -39,11 +46,9 @@ import { typesNodeVersion, } from '../../utils/versions'; import jsInitGenerator from '../init/init'; -import { type PackageJson } from 'nx/src/utils/package-json'; import setupVerdaccio from '../setup-verdaccio/generator'; -import { tsConfigBaseOptions } from '../../utils/typescript/create-ts-config'; -import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-command'; -import { addBuildTargetDefaults } from '@nx/devkit/src/generators/add-build-target-defaults'; + +const defaultOutputDirectory = 'dist'; export async function libraryGenerator( tree: Tree, @@ -74,7 +79,7 @@ export async function libraryGeneratorInternal( createFiles(tree, options); - addProject(tree, options); + await addProject(tree, options); if (!options.skipPackageJson) { tasks.push(addProjectDependencies(tree, options)); @@ -166,6 +171,12 @@ export async function libraryGeneratorInternal( await formatFiles(tree); } + if (options.publishable) { + tasks.push(() => { + logNxReleaseDocsInfo(); + }); + } + tasks.push(() => { logShowProjectCommand(options.name); }); @@ -182,7 +193,7 @@ export interface NormalizedSchema extends LibraryGeneratorSchema { importPath?: string; } -function addProject(tree: Tree, options: NormalizedSchema) { +async function addProject(tree: Tree, options: NormalizedSchema) { const projectConfiguration: ProjectConfiguration = { root: options.projectRoot, sourceRoot: joinPathFragments(options.projectRoot, 'src'), @@ -240,12 +251,27 @@ function addProject(tree: Tree, options: NormalizedSchema) { } if (options.publishable) { - const publishScriptPath = addMinimalPublishScript(tree); + const packageRoot = join(defaultOutputDirectory, '{projectRoot}'); - projectConfiguration.targets.publish = { - command: `node ${publishScriptPath} ${options.name} {args.ver} {args.tag}`, - dependsOn: ['build'], + 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); } } @@ -498,6 +524,9 @@ function createFiles(tree: Tree, options: NormalizedSchema) { if (json.private && (options.publishable || options.rootProject)) { delete json.private; } + if (!options.publishable && !options.rootProject) { + json.private = true; + } return { ...json, dependencies: { @@ -508,12 +537,16 @@ function createFiles(tree: Tree, options: NormalizedSchema) { }; }); } else { - writeJson(tree, packageJsonPath, { + const packageJson: PackageJson = { name: options.importPath, version: '0.0.1', dependencies: determineDependencies(options), ...determineEntryFields(options), - }); + }; + if (!options.publishable && !options.rootProject) { + packageJson.private = true; + } + writeJson(tree, packageJsonPath, packageJson); } if (options.config === 'npm-scripts') { @@ -633,7 +666,7 @@ async function normalizeOptions( } } - // This is to preserve old behaviour, buildable: false + // This is to preserve old behavior, buildable: false if (options.publishable === false && options.buildable === false) { options.bundler = 'none'; } @@ -761,7 +794,7 @@ function getBuildExecutor(bundler: Bundler) { } function getOutputPath(options: NormalizedSchema) { - const parts = ['dist']; + const parts = [defaultOutputDirectory]; if (options.projectRoot === '.') { parts.push(options.name); } else { @@ -866,4 +899,118 @@ function determineEntryFields( } } +function projectsConfigMatchesProject( + projectsConfig: string | string[] | undefined, + project: ProjectGraphProjectNode +): boolean { + if (!projectsConfig) { + return false; + } + + if (typeof projectsConfig === 'string') { + projectsConfig = [projectsConfig]; + } + + const graph: Record = { + [project.name]: project, + }; + + const matchingProjects = findMatchingProjects(projectsConfig, graph); + + return matchingProjects.includes(project.name); +} + +async function addProjectToNxReleaseConfig( + tree: Tree, + options: NormalizedSchema, + 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.`, + }); +} + export default libraryGenerator; diff --git a/packages/js/src/generators/library/schema.json b/packages/js/src/generators/library/schema.json index f6cd27ec2e801..bc0122457709d 100644 --- a/packages/js/src/generators/library/schema.json +++ b/packages/js/src/generators/library/schema.json @@ -89,7 +89,7 @@ "publishable": { "type": "boolean", "default": false, - "description": "Generate a publishable library.", + "description": "Configure the library ready for use with `nx release` (https://nx.dev/core-features/manage-releases).", "x-priority": "important" }, "importPath": { diff --git a/packages/js/src/generators/release-version/schema.json b/packages/js/src/generators/release-version/schema.json index aab95e9e3d036..c63faae9bd3f6 100644 --- a/packages/js/src/generators/release-version/schema.json +++ b/packages/js/src/generators/release-version/schema.json @@ -49,6 +49,18 @@ "type": "object", "description": "Additional metadata to pass to the current version resolver.", "default": {} + }, + "skipLockFileUpdate": { + "type": "boolean", + "description": "Whether to skip updating the lock file after updating the version." + }, + "installArgs": { + "type": "string", + "description": "Additional arguments to pass to the package manager when updating the lock file with an install command." + }, + "installIgnoreScripts": { + "type": "boolean", + "description": "Whether to ignore install lifecycle scripts when updating the lock file with an install command." } }, "required": ["projects", "projectGraph", "releaseGroup"] diff --git a/packages/js/src/utils/add-local-registry-scripts.ts b/packages/js/src/utils/add-local-registry-scripts.ts index 947e11caadb52..e85ca2d937f83 100644 --- a/packages/js/src/utils/add-local-registry-scripts.ts +++ b/packages/js/src/utils/add-local-registry-scripts.ts @@ -1,4 +1,4 @@ -import { ProjectConfiguration, readJson, type Tree } from '@nx/devkit'; +import { output, ProjectConfiguration, readJson, type Tree } from '@nx/devkit'; const startLocalRegistryScript = (localRegistryTarget: string) => ` /** @@ -7,6 +7,7 @@ const startLocalRegistryScript = (localRegistryTarget: string) => ` */ import { startLocalRegistry } from '@nx/js/plugins/jest/local-registry'; import { execFileSync } from 'child_process'; +import { releasePublish, releaseVersion } from 'nx/release'; export default async () => { // local registry target to run @@ -19,12 +20,21 @@ export default async () => { storage, verbose: false, }); - const nx = require.resolve('nx'); - execFileSync( - nx, - ['run-many', '--targets', 'publish', '--ver', '0.0.0-e2e', '--tag', 'e2e'], - { env: process.env, stdio: 'inherit' } - ); + + await releaseVersion({ + specifier: '0.0.0-e2e', + stageChanges: false, + gitCommit: false, + gitTag: false, + firstRelease: true, + generatorOptionsOverrides: { + skipLockFileUpdate: true + } + }); + await releasePublish({ + tag: 'e2e', + firstRelease: true + }); }; `; @@ -49,12 +59,23 @@ export function addLocalRegistryScripts(tree: Tree) { tree, 'project.json' ); + const localRegistryTarget = `${projectConfiguration.name}:local-registry`; if (!tree.exists(startLocalRegistryPath)) { tree.write( startLocalRegistryPath, startLocalRegistryScript(localRegistryTarget) ); + } else { + const existingStartLocalRegistryScript = tree + .read(startLocalRegistryPath) + .toString(); + if (!existingStartLocalRegistryScript.includes('nx/release')) { + output.warn({ + title: + 'Your `start-local-registry.ts` script may be outdated. To ensure that newly generated packages are published appropriately when running end to end tests, update this script to use Nx Release. See https://nx.dev/recipes/nx-release/update-local-registry-setup for details.', + }); + } } if (!tree.exists(stopLocalRegistryPath)) { tree.write(stopLocalRegistryPath, stopLocalRegistryScript); diff --git a/packages/js/src/utils/minimal-publish-script.ts b/packages/js/src/utils/minimal-publish-script.ts deleted file mode 100644 index 9715810ca4110..0000000000000 --- a/packages/js/src/utils/minimal-publish-script.ts +++ /dev/null @@ -1,75 +0,0 @@ -import type { Tree } from '@nx/devkit'; - -const publishScriptContent = ` -/** - * This is a minimal script to publish your package to "npm". - * This is meant to be used as-is or customize as you see fit. - * - * This script is executed on "dist/path/to/library" as "cwd" by default. - * - * You might need to authenticate with NPM before running this script. - */ - -import { execSync } from 'child_process'; -import { readFileSync, writeFileSync } from 'fs'; - -import devkit from '@nx/devkit'; -const { readCachedProjectGraph } = devkit; - -function invariant(condition, message) { - if (!condition) { - console.error(message); - process.exit(1); - } -} - -// Executing publish script: node path/to/publish.mjs {name} --version {version} --tag {tag} -// Default "tag" to "next" so we won't publish the "latest" tag by accident. -const [, , name, version, tag = 'next'] = process.argv; - -// A simple SemVer validation to validate the version -const validVersion = /^\\d+\\.\\d+\\.\\d+(-\\w+\\.\\d+)?/; -invariant( - version && validVersion.test(version), - \`No version provided or version did not match Semantic Versioning, expected: #.#.#-tag.# or #.#.#, got \${version}.\` -); - - -const graph = readCachedProjectGraph(); -const project = graph.nodes[name]; - -invariant( - project, - \`Could not find project "\${name}" in the workspace. Is the project.json configured correctly?\` -); - -const outputPath = project.data?.targets?.build?.options?.outputPath; -invariant( - outputPath, - \`Could not find "build.options.outputPath" of project "\${name}". Is project.json configured correctly?\` -); - -process.chdir(outputPath); - -// Updating the version in "package.json" before publishing -try { - const json = JSON.parse(readFileSync(\`package.json\`).toString()); - json.version = version; - writeFileSync(\`package.json\`, JSON.stringify(json, null, 2)); -} catch (e) { - console.error(\`Error reading package.json file from library build output.\`); -} - -// Execute "npm publish" to publish -execSync(\`npm publish --access public --tag \${tag}\`); -`; - -export function addMinimalPublishScript(tree: Tree) { - const publishScriptPath = 'tools/scripts/publish.mjs'; - - if (!tree.exists(publishScriptPath)) { - tree.write(publishScriptPath, publishScriptContent); - } - - return publishScriptPath; -} diff --git a/packages/next/src/generators/cypress-component-configuration/cypress-component-configuration.ts b/packages/next/src/generators/cypress-component-configuration/cypress-component-configuration.ts index 7bfe488db7775..4afa3938994d1 100644 --- a/packages/next/src/generators/cypress-component-configuration/cypress-component-configuration.ts +++ b/packages/next/src/generators/cypress-component-configuration/cypress-component-configuration.ts @@ -39,6 +39,7 @@ export async function cypressComponentConfigurationInternal( await baseCyCtConfig(tree, { project: options.project, skipFormat: true, + framework: 'next', jsx: true, addPlugin: options.addPlugin, }) diff --git a/packages/nx/schemas/nx-schema.json b/packages/nx/schemas/nx-schema.json index 26273a6f0e0c2..11b74df06c136 100644 --- a/packages/nx/schemas/nx-schema.json +++ b/packages/nx/schemas/nx-schema.json @@ -157,11 +157,16 @@ "$ref": "#/definitions/NxReleaseVersionConfiguration" }, { - "anyOf": [ + "allOf": [ { "not": { "required": ["git"] } + }, + { + "not": { + "required": ["preVersionCommand"] + } } ] } @@ -576,6 +581,10 @@ }, "git": { "$ref": "#/definitions/NxReleaseGitConfiguration" + }, + "preVersionCommand": { + "type": "string", + "description": "A command to run after validation of nx release configuration, but before versioning begins. Used for preparing build artifacts. If --dry-run is passed, the command is still executed, but with the NX_DRY_RUN environment variable set to 'true'." } } }, diff --git a/packages/nx/schemas/project-schema.json b/packages/nx/schemas/project-schema.json index ece8fde307032..969ddbf126dd2 100644 --- a/packages/nx/schemas/project-schema.json +++ b/packages/nx/schemas/project-schema.json @@ -127,6 +127,26 @@ "items": { "type": "string" } + }, + "release": { + "type": "object", + "description": "Configuration for the nx release commands.", + "properties": { + "version": { + "type": "object", + "description": "Configuration for the nx release version command.", + "properties": { + "generator": { + "type": "string", + "description": "The version generator to use. Defaults to @nx/js:release-version." + }, + "generatorOptions": { + "type": "object", + "description": "Options for the version generator." + } + } + } + } } }, "definitions": { diff --git a/packages/nx/src/command-line/init/init-v2.ts b/packages/nx/src/command-line/init/init-v2.ts index 1c3ca1d0d2fa6..cc859a3864b50 100644 --- a/packages/nx/src/command-line/init/init-v2.ts +++ b/packages/nx/src/command-line/init/init-v2.ts @@ -31,6 +31,7 @@ export interface InitArgs { } export async function initHandler(options: InitArgs): Promise { + process.env.NX_RUNNING_NX_INIT = 'true'; const version = process.env.NX_VERSION ?? (prerelease(nxVersion) ? 'next' : 'latest'); if (process.env.NX_VERSION) { @@ -112,7 +113,7 @@ export async function initHandler(options: InitArgs): Promise { if (!detectPluginsResponse.updatePackageScripts) { const rootPackageJsonPath = join(repoRoot, 'package.json'); const json = readJsonFile(rootPackageJsonPath); - json.nx = {}; + json.nx = { includedScripts: [] }; writeJsonFile(rootPackageJsonPath, json); } diff --git a/packages/nx/src/command-line/release/changelog.ts b/packages/nx/src/command-line/release/changelog.ts index f6956da297265..43bcd2f6c870f 100644 --- a/packages/nx/src/command-line/release/changelog.ts +++ b/packages/nx/src/command-line/release/changelog.ts @@ -14,6 +14,7 @@ import { } from '../../config/project-graph'; import { FsTree, Tree } from '../../generators/tree'; import { registerTsProject } from '../../plugins/js/utils/register'; +import { createProjectFileMapUsingProjectGraph } from '../../project-graph/file-map-utils'; import { createProjectGraphAsync } from '../../project-graph/project-graph'; import { interpolate } from '../../tasks-runner/utils'; import { isCI } from '../../utils/is-ci'; @@ -94,6 +95,7 @@ export async function releaseChangelog( // Apply default configuration to any optional user configuration const { error: configError, nxReleaseConfig } = await createNxReleaseConfig( projectGraph, + await createProjectFileMapUsingProjectGraph(projectGraph), nxJson.release ); if (configError) { diff --git a/packages/nx/src/command-line/release/command-object.ts b/packages/nx/src/command-line/release/command-object.ts index 18c734b3a7de1..6302d7543b458 100644 --- a/packages/nx/src/command-line/release/command-object.ts +++ b/packages/nx/src/command-line/release/command-object.ts @@ -34,6 +34,7 @@ export type VersionOptions = NxReleaseArgs & specifier?: string; preid?: string; stageChanges?: boolean; + generatorOptionsOverrides?: Record; }; export type ChangelogOptions = NxReleaseArgs & diff --git a/packages/nx/src/command-line/release/config/config.spec.ts b/packages/nx/src/command-line/release/config/config.spec.ts index d2f4504efbda1..925b3dc379841 100644 --- a/packages/nx/src/command-line/release/config/config.spec.ts +++ b/packages/nx/src/command-line/release/config/config.spec.ts @@ -1,10 +1,33 @@ -import { type ProjectGraph } from '../../../devkit-exports'; +import { ProjectFileMap, ProjectGraph } from '../../../config/project-graph'; +import { TempFs } from '../../../internal-testing-utils/temp-fs'; import { createNxReleaseConfig } from './config'; describe('createNxReleaseConfig()', () => { let projectGraph: ProjectGraph; + let projectFileMap: ProjectFileMap; + let tempFs: TempFs; - beforeEach(() => { + beforeEach(async () => { + tempFs = new TempFs('nx-release-config-test'); + await tempFs.createFiles({ + 'package.json': JSON.stringify({ + name: 'root', + version: '0.0.0', + private: true, + }), + 'libs/lib-a/package.json': JSON.stringify({ + name: 'lib-a', + version: '0.0.0', + }), + 'libs/lib-b/package.json': JSON.stringify({ + name: 'lib-b', + version: '0.0.0', + }), + 'packages/nx/package.json': JSON.stringify({ + name: 'nx', + version: '0.0.0', + }), + }); projectGraph = { nodes: { 'lib-a': { @@ -37,16 +60,54 @@ describe('createNxReleaseConfig()', () => { }, } as any, }, + root: { + name: 'root', + type: 'lib', + data: { + root: '.', + targets: { + 'nx-release-publish': {}, + }, + } as any, + }, }, dependencies: {}, }; + + projectFileMap = { + 'lib-a': [ + { + file: 'libs/lib-a/package.json', + hash: 'abc', + }, + ], + 'lib-b': [ + { + file: 'libs/lib-b/package.json', + hash: 'abc', + }, + ], + nx: [ + { + file: 'packages/nx/package.json', + hash: 'abc', + }, + ], + root: [ + { + file: 'package.json', + hash: 'abc', + }, + ], + }; }); describe('zero/empty user config', () => { it('should create appropriate default NxReleaseConfig data from zero/empty user config', async () => { // zero user config - expect(await createNxReleaseConfig(projectGraph, undefined)) - .toMatchInlineSnapshot(` + expect( + await createNxReleaseConfig(projectGraph, projectFileMap, undefined) + ).toMatchInlineSnapshot(` { "error": null, "nxReleaseConfig": { @@ -115,13 +176,14 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } `); // empty user config - expect(await createNxReleaseConfig(projectGraph, {})) + expect(await createNxReleaseConfig(projectGraph, projectFileMap, {})) .toMatchInlineSnapshot(` { "error": null, @@ -191,6 +253,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -198,7 +261,7 @@ describe('createNxReleaseConfig()', () => { // empty groups expect( - await createNxReleaseConfig(projectGraph, { + await createNxReleaseConfig(projectGraph, projectFileMap, { groups: {}, }) ).toMatchInlineSnapshot(` @@ -270,6 +333,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -295,8 +359,324 @@ describe('createNxReleaseConfig()', () => { } as any, }; - expect(await createNxReleaseConfig(projectGraph, undefined)) - .toMatchInlineSnapshot(` + projectFileMap['app-1'] = [ + { + file: 'apps/app-1/package.json', + hash: 'abc', + }, + ]; + + projectFileMap['e2e-1'] = [ + { + file: 'apps/e2e-1/package.json', + hash: 'abc', + }, + ]; + + expect( + await createNxReleaseConfig(projectGraph, projectFileMap, undefined) + ).toMatchInlineSnapshot(` + { + "error": null, + "nxReleaseConfig": { + "changelog": { + "automaticFromRef": false, + "git": { + "commit": true, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": true, + "tagArgs": "", + "tagMessage": "", + }, + "projectChangelogs": false, + "workspaceChangelog": { + "createRelease": false, + "entryWhenNoChanges": "This was a version bump only, there were no code changes.", + "file": "{workspaceRoot}/CHANGELOG.md", + "renderOptions": { + "authors": true, + "commitReferences": true, + "versionTitleDate": true, + }, + "renderer": "nx/release/changelog-renderer", + }, + }, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "groups": { + "__default__": { + "changelog": false, + "projects": [ + "lib-a", + "lib-b", + "nx", + ], + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + }, + }, + }, + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": true, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "preVersionCommand": "", + }, + }, + } + `); + }); + + it('should filter out projects without package.json', async () => { + projectGraph.nodes['lib-c'] = { + name: 'lib-c', + type: 'lib', + data: { + root: 'libs/lib-c', + targets: {}, + } as any, + }; + + projectFileMap['lib-c'] = [ + { + file: 'libs/lib-c/cargo.toml', + hash: 'abc', + }, + ]; + + expect( + await createNxReleaseConfig(projectGraph, projectFileMap, undefined) + ).toMatchInlineSnapshot(` + { + "error": null, + "nxReleaseConfig": { + "changelog": { + "automaticFromRef": false, + "git": { + "commit": true, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": true, + "tagArgs": "", + "tagMessage": "", + }, + "projectChangelogs": false, + "workspaceChangelog": { + "createRelease": false, + "entryWhenNoChanges": "This was a version bump only, there were no code changes.", + "file": "{workspaceRoot}/CHANGELOG.md", + "renderOptions": { + "authors": true, + "commitReferences": true, + "versionTitleDate": true, + }, + "renderer": "nx/release/changelog-renderer", + }, + }, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "groups": { + "__default__": { + "changelog": false, + "projects": [ + "lib-a", + "lib-b", + "nx", + ], + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + }, + }, + }, + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": true, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "preVersionCommand": "", + }, + }, + } + `); + }); + + it('should filter out projects that are private', async () => { + projectGraph.nodes['root'] = { + name: 'root', + type: 'lib', + data: { + root: '.', + targets: {}, + } as any, + }; + + projectFileMap['root'] = [ + { + file: 'package.json', + hash: 'abc', + }, + ]; + + tempFs.writeFile( + 'package.json', + JSON.stringify({ name: 'root', version: '0.0.0', private: true }) + ); + tempFs.writeFile( + 'libs/lib-a/package.json', + JSON.stringify({ name: 'lib-a', version: '0.0.0', private: true }) + ); + + expect( + await createNxReleaseConfig(projectGraph, projectFileMap, undefined) + ).toMatchInlineSnapshot(` + { + "error": null, + "nxReleaseConfig": { + "changelog": { + "automaticFromRef": false, + "git": { + "commit": true, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": true, + "tagArgs": "", + "tagMessage": "", + }, + "projectChangelogs": false, + "workspaceChangelog": { + "createRelease": false, + "entryWhenNoChanges": "This was a version bump only, there were no code changes.", + "file": "{workspaceRoot}/CHANGELOG.md", + "renderOptions": { + "authors": true, + "commitReferences": true, + "versionTitleDate": true, + }, + "renderer": "nx/release/changelog-renderer", + }, + }, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "groups": { + "__default__": { + "changelog": false, + "projects": [ + "lib-b", + "nx", + ], + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + }, + }, + }, + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": true, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "preVersionCommand": "", + }, + }, + } + `); + }); + + it('should not filter out the root project if it is not private', async () => { + projectGraph.nodes['root'] = { + name: 'root', + type: 'lib', + data: { + root: '.', + targets: {}, + } as any, + }; + + projectFileMap['root'] = [ + { + file: 'package.json', + hash: 'abc', + }, + ]; + + tempFs.writeFile( + 'package.json', + JSON.stringify({ + name: 'root', + version: '0.0.0', + }) + ); + + expect( + await createNxReleaseConfig(projectGraph, projectFileMap, undefined) + ).toMatchInlineSnapshot(` { "error": null, "nxReleaseConfig": { @@ -340,6 +720,7 @@ describe('createNxReleaseConfig()', () => { "lib-a", "lib-b", "nx", + "root", ], "projectsRelationship": "fixed", "releaseTagPattern": "v{version}", @@ -365,6 +746,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -374,7 +756,7 @@ describe('createNxReleaseConfig()', () => { describe('user specified groups', () => { it('should ignore any projects not matched to user specified groups', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { groups: { 'group-1': { projects: ['lib-a'], // intentionally no lib-b, so it should be ignored @@ -448,6 +830,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -455,7 +838,7 @@ describe('createNxReleaseConfig()', () => { }); it('should convert any projects patterns into actual project names in the final config', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { groups: { 'group-1': { projects: ['lib-*'], // should match both lib-a and lib-b @@ -530,6 +913,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -537,7 +921,7 @@ describe('createNxReleaseConfig()', () => { }); it('should respect user overrides for "version" config at the group level', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { groups: { 'group-1': { projects: ['lib-a'], @@ -628,6 +1012,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -635,7 +1020,7 @@ describe('createNxReleaseConfig()', () => { }); it('should allow using true for group level changelog as an equivalent of an empty object (i.e. use the defaults)', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { groups: { 'group-1': { projects: ['lib-a'], @@ -720,6 +1105,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -727,7 +1113,7 @@ describe('createNxReleaseConfig()', () => { }); it('should disable workspaceChangelog if there are multiple groups', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { groups: { 'group-1': { projects: ['lib-a'], @@ -830,6 +1216,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -837,7 +1224,7 @@ describe('createNxReleaseConfig()', () => { }); it('should disable workspaceChangelog if the single group has an independent projects relationship', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { groups: { 'group-1': { projects: ['lib-a', 'lib-b'], @@ -915,6 +1302,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -924,7 +1312,7 @@ describe('createNxReleaseConfig()', () => { describe('user config -> top level version', () => { it('should respect modifying version at the top level and it should be inherited by the implicit default group', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { version: { // only modifying options, use default generator generatorOptions: { @@ -1005,6 +1393,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -1012,7 +1401,7 @@ describe('createNxReleaseConfig()', () => { }); it('should respect enabling git operations on the version command via the top level', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { git: { commit: true, commitArgs: '--no-verify', @@ -1087,6 +1476,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -1094,7 +1484,7 @@ describe('createNxReleaseConfig()', () => { }); it('should respect enabling git operations for the version command directly', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { version: { git: { commit: true, @@ -1172,6 +1562,89 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", + }, + }, + } + `); + }); + + it('should allow configuration of preVersionCommand', async () => { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { + version: { + preVersionCommand: 'nx run-many -t build', + }, + }); + expect(res).toMatchInlineSnapshot(` + { + "error": null, + "nxReleaseConfig": { + "changelog": { + "automaticFromRef": false, + "git": { + "commit": true, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": true, + "tagArgs": "", + "tagMessage": "", + }, + "projectChangelogs": false, + "workspaceChangelog": { + "createRelease": false, + "entryWhenNoChanges": "This was a version bump only, there were no code changes.", + "file": "{workspaceRoot}/CHANGELOG.md", + "renderOptions": { + "authors": true, + "commitReferences": true, + "versionTitleDate": true, + }, + "renderer": "nx/release/changelog-renderer", + }, + }, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "groups": { + "__default__": { + "changelog": false, + "projects": [ + "lib-a", + "lib-b", + "nx", + ], + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + }, + }, + }, + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": true, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "preVersionCommand": "nx run-many -t build", }, }, } @@ -1181,7 +1654,7 @@ describe('createNxReleaseConfig()', () => { describe('user config -> top level projects', () => { it('should return an error when both "projects" and "groups" are specified', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { projects: ['lib-a'], groups: { 'group-1': { @@ -1201,7 +1674,7 @@ describe('createNxReleaseConfig()', () => { }); it('should influence the projects configured for the implicit default group', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { projects: ['lib-a'], }); expect(res).toMatchInlineSnapshot(` @@ -1271,6 +1744,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -1280,7 +1754,7 @@ describe('createNxReleaseConfig()', () => { describe('user config -> top level releaseTagPattern', () => { it('should respect modifying releaseTagPattern at the top level and it should be inherited by the implicit default group', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { releaseTagPattern: '{projectName}__{version}', }); expect(res).toMatchInlineSnapshot(` @@ -1352,6 +1826,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -1359,7 +1834,7 @@ describe('createNxReleaseConfig()', () => { }); it('should respect top level releaseTagPatterns for fixed groups without explicit settings of their own', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { releaseTagPattern: '{version}', groups: { npm: { @@ -1454,6 +1929,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -1463,7 +1939,7 @@ describe('createNxReleaseConfig()', () => { describe('user config -> top level changelog', () => { it('should respect disabling all changelogs at the top level', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { changelog: { projectChangelogs: false, workspaceChangelog: false, @@ -1528,6 +2004,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -1535,7 +2012,7 @@ describe('createNxReleaseConfig()', () => { }); it('should respect any adjustments to default changelog config at the top level and apply as defaults at the group level', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { changelog: { workspaceChangelog: { // override single field in user config @@ -1640,6 +2117,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -1647,7 +2125,7 @@ describe('createNxReleaseConfig()', () => { }); it('should allow using true for workspaceChangelog and projectChangelogs as an equivalent of an empty object (i.e. use the defaults)', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { changelog: { projectChangelogs: true, workspaceChangelog: true, @@ -1742,6 +2220,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -1749,7 +2228,7 @@ describe('createNxReleaseConfig()', () => { }); it('should respect disabling git at the top level (thus disabling the default of true for changelog', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { git: { commit: false, tag: false, @@ -1824,6 +2303,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -1833,7 +2313,7 @@ describe('createNxReleaseConfig()', () => { describe('user config -> top level and group level changelog combined', () => { it('should respect any adjustments to default changelog config at the top level and group level in the final config, CASE 1', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { changelog: { projectChangelogs: { // overriding field at the root should be inherited by all groups that do not set their own override @@ -1978,6 +2458,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -1985,7 +2466,7 @@ describe('createNxReleaseConfig()', () => { }); it('should respect any adjustments to default changelog config at the top level and group level in the final config, CASE 2', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { groups: { foo: { projects: 'lib-a', @@ -2090,6 +2571,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -2097,7 +2579,7 @@ describe('createNxReleaseConfig()', () => { }); it('should return an error if no projects can be resolved for a group', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { groups: { 'group-1': { projects: ['lib-does-not-exist'], @@ -2120,7 +2602,7 @@ describe('createNxReleaseConfig()', () => { describe('user config -> mixed top level and granular git', () => { it('should return an error with version config and top level config', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { git: { commit: true, tag: false, @@ -2145,7 +2627,7 @@ describe('createNxReleaseConfig()', () => { }); it('should return an error with changelog config and top level config', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { git: { commit: true, tag: false, @@ -2170,7 +2652,7 @@ describe('createNxReleaseConfig()', () => { }); it('should return an error with version and changelog config and top level config', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { git: { commit: true, tag: false, @@ -2203,7 +2685,7 @@ describe('createNxReleaseConfig()', () => { describe('release group config errors', () => { it('should return an error if a project matches multiple groups', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { groups: { 'group-1': { projects: ['lib-a'], @@ -2227,7 +2709,7 @@ describe('createNxReleaseConfig()', () => { }); it('should return an error if no projects can be resolved for a group', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { groups: { 'group-1': { projects: ['lib-does-not-exist'], @@ -2248,7 +2730,7 @@ describe('createNxReleaseConfig()', () => { }); it("should return an error if a group's releaseTagPattern has no {version} placeholder", async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { groups: { 'group-1': { projects: '*', @@ -2270,7 +2752,7 @@ describe('createNxReleaseConfig()', () => { }); it("should return an error if a group's releaseTagPattern has more than one {version} placeholder", async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { groups: { 'group-1': { projects: '*', @@ -2294,7 +2776,7 @@ describe('createNxReleaseConfig()', () => { describe('projectsRelationship at the root', () => { it('should respect the user specified projectsRelationship value and apply it to any groups that do not specify their own value', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { projectsRelationship: 'independent', groups: { 'group-1': { @@ -2378,6 +2860,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -2385,7 +2868,7 @@ describe('createNxReleaseConfig()', () => { }); it('should override workspaceChangelog default if projectsRelationship is independent', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { projectsRelationship: 'independent', projects: ['lib-a', 'lib-b'], }); @@ -2448,6 +2931,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -2457,7 +2941,7 @@ describe('createNxReleaseConfig()', () => { describe('version.conventionalCommits shorthand', () => { it('should be implicitly false and not interfere with its long-form equivalent generatorOptions when not explicitly set', async () => { - const res1 = await createNxReleaseConfig(projectGraph, { + const res1 = await createNxReleaseConfig(projectGraph, projectFileMap, { version: { generatorOptions: { currentVersionResolver: 'git-tag', @@ -2540,12 +3024,13 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } `); - const res2 = await createNxReleaseConfig(projectGraph, { + const res2 = await createNxReleaseConfig(projectGraph, projectFileMap, { version: { generatorOptions: { currentVersionResolver: 'registry', @@ -2628,6 +3113,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -2635,7 +3121,7 @@ describe('createNxReleaseConfig()', () => { }); it('should update appropriate default values for generatorOptions when applied at the root', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { version: { conventionalCommits: true, }, @@ -2715,6 +3201,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -2722,7 +3209,7 @@ describe('createNxReleaseConfig()', () => { }); it('should be possible to override at the group level and produce the appropriate default generatorOptions', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { version: { conventionalCommits: true, }, @@ -2805,6 +3292,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -2812,7 +3300,7 @@ describe('createNxReleaseConfig()', () => { }); it('should not error if the shorthand is combined with unrelated generatorOptions', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { version: { conventionalCommits: true, generatorOptions: { @@ -2897,6 +3385,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -2904,7 +3393,7 @@ describe('createNxReleaseConfig()', () => { }); it('should error if the shorthand is combined with related generatorOptions', async () => { - const res1 = await createNxReleaseConfig(projectGraph, { + const res1 = await createNxReleaseConfig(projectGraph, projectFileMap, { version: { conventionalCommits: true, generatorOptions: { @@ -2922,7 +3411,7 @@ describe('createNxReleaseConfig()', () => { } `); - const res2 = await createNxReleaseConfig(projectGraph, { + const res2 = await createNxReleaseConfig(projectGraph, projectFileMap, { version: { conventionalCommits: true, generatorOptions: { diff --git a/packages/nx/src/command-line/release/config/config.ts b/packages/nx/src/command-line/release/config/config.ts index 64dd16738e24c..77a8c273ca909 100644 --- a/packages/nx/src/command-line/release/config/config.ts +++ b/packages/nx/src/command-line/release/config/config.ts @@ -11,9 +11,14 @@ * defaults and user overrides, as well as handling common errors, up front to produce a single, consistent, * and easy to consume config object for all the `nx release` command implementations. */ +import { join } from 'path'; import { NxJsonConfiguration } from '../../../config/nx-json'; -import { output, type ProjectGraph } from '../../../devkit-exports'; +import { ProjectFileMap, ProjectGraph } from '../../../config/project-graph'; +import { readJsonFile } from '../../../utils/fileutils'; import { findMatchingProjects } from '../../../utils/find-matching-projects'; +import { output } from '../../../utils/output'; +import { PackageJson } from '../../../utils/package-json'; +import { workspaceRoot } from '../../../utils/workspace-root'; import { resolveNxJsonConfigErrorMessage } from '../utils/resolve-nx-json-error-message'; type DeepRequired = Required<{ @@ -80,6 +85,7 @@ export interface CreateNxReleaseConfigError { // Apply default configuration to any optional user configuration and handle known errors export async function createNxReleaseConfig( projectGraph: ProjectGraph, + projectFileMap: ProjectFileMap, userConfig: NxJsonConfiguration['release'] = {} ): Promise<{ error: null | CreateNxReleaseConfigError; @@ -163,6 +169,7 @@ export async function createNxReleaseConfig( conventionalCommits: userConfig.version?.conventionalCommits || false, generator: '@nx/js:release-version', generatorOptions: defaultGeneratorOptions, + preVersionCommand: userConfig.version?.preVersionCommand || '', }, changelog: { git: changelogGitDefaults, @@ -279,21 +286,23 @@ export async function createNxReleaseConfig( > ); - // git configuration is not supported at the group level, only the root/command level - const rootVersionWithoutGit = { ...rootVersionConfig }; - delete rootVersionWithoutGit.git; + // these options are not supported at the group level, only the root/command level + const rootVersionWithoutGlobalOptions = { ...rootVersionConfig }; + delete rootVersionWithoutGlobalOptions.git; + delete rootVersionWithoutGlobalOptions.preVersionCommand; // Apply conventionalCommits shorthand to the final group defaults if explicitly configured in the original user config if (userConfig.version?.conventionalCommits === true) { - rootVersionWithoutGit.generatorOptions = { - ...rootVersionWithoutGit.generatorOptions, + rootVersionWithoutGlobalOptions.generatorOptions = { + ...rootVersionWithoutGlobalOptions.generatorOptions, currentVersionResolver: 'git-tag', specifierSource: 'conventional-commits', }; } if (userConfig.version?.conventionalCommits === false) { - delete rootVersionWithoutGit.generatorOptions.currentVersionResolver; - delete rootVersionWithoutGit.generatorOptions.specifierSource; + delete rootVersionWithoutGlobalOptions.generatorOptions + .currentVersionResolver; + delete rootVersionWithoutGlobalOptions.generatorOptions.specifierSource; } const groups: NxReleaseConfig['groups'] = @@ -312,10 +321,8 @@ export async function createNxReleaseConfig( ensureArray(userConfig.projects), projectGraph.nodes ) - : // default to all library projects in the workspace - findMatchingProjects(['*'], projectGraph.nodes).filter( - (project) => projectGraph.nodes[project].type === 'lib' - ), + : await getDefaultProjects(projectGraph, projectFileMap), + /** * For properties which are overriding config at the root, we use the root level config as the * default values to merge with so that the group that matches a specific project will always @@ -323,7 +330,7 @@ export async function createNxReleaseConfig( */ version: deepMergeDefaults( [GROUP_DEFAULTS.version], - rootVersionWithoutGit + rootVersionWithoutGlobalOptions ), // If the user has set something custom for releaseTagPattern at the top level, respect it for the implicit default group releaseTagPattern: @@ -409,7 +416,7 @@ export async function createNxReleaseConfig( projects: matchingProjects, version: deepMergeDefaults( // First apply any group level defaults, then apply actual root level config, then group level config - [GROUP_DEFAULTS.version, rootVersionWithoutGit], + [GROUP_DEFAULTS.version, rootVersionWithoutGlobalOptions], releaseGroup.version ), // If the user has set any changelog config at all, including at the root level, then use one set of defaults, otherwise default to false for the whole feature @@ -694,3 +701,41 @@ function hasInvalidGitConfig( !!userConfig.git && !!(userConfig.version?.git || userConfig.changelog?.git) ); } + +async function getDefaultProjects( + projectGraph: ProjectGraph, + projectFileMap: ProjectFileMap +): Promise { + // default to all library projects in the workspace with a package.json file + return findMatchingProjects(['*'], projectGraph.nodes).filter( + (project) => + projectGraph.nodes[project].type === 'lib' && + // Exclude all projects with "private": true in their package.json because this is + // a common indicator that a project is not intended for release. + // Users can override this behavior by explicitly defining the projects they want to release. + isProjectPublic(project, projectGraph, projectFileMap) + ); +} + +function isProjectPublic( + project: string, + projectGraph: ProjectGraph, + projectFileMap: ProjectFileMap +): boolean { + const projectNode = projectGraph.nodes[project]; + const packageJsonPath = join(projectNode.data.root, 'package.json'); + + if (!projectFileMap[project]?.find((f) => f.file === packageJsonPath)) { + return false; + } + + try { + const fullPackageJsonPath = join(workspaceRoot, packageJsonPath); + const packageJson = readJsonFile(fullPackageJsonPath); + return !(packageJson.private === true); + } catch (e) { + // do nothing and assume that the project is not public if there is a parsing issue + // this will result in it being excluded from the default projects list + return false; + } +} diff --git a/packages/nx/src/command-line/release/config/filter-release-groups.spec.ts b/packages/nx/src/command-line/release/config/filter-release-groups.spec.ts index cf6b842a31904..c513f09af6de6 100644 --- a/packages/nx/src/command-line/release/config/filter-release-groups.spec.ts +++ b/packages/nx/src/command-line/release/config/filter-release-groups.spec.ts @@ -37,6 +37,7 @@ describe('filterReleaseGroups()', () => { tagMessage: '', tagArgs: '', }, + preVersionCommand: '', }, releaseTagPattern: '', git: { diff --git a/packages/nx/src/command-line/release/publish.ts b/packages/nx/src/command-line/release/publish.ts index 77d174767ba35..c12e3ae9fddc5 100644 --- a/packages/nx/src/command-line/release/publish.ts +++ b/packages/nx/src/command-line/release/publish.ts @@ -3,13 +3,14 @@ import { ProjectGraph, ProjectGraphProjectNode, } from '../../config/project-graph'; -import { output } from '../../devkit-exports'; +import { createProjectFileMapUsingProjectGraph } from '../../project-graph/file-map-utils'; import { createProjectGraphAsync } from '../../project-graph/project-graph'; import { runCommand } from '../../tasks-runner/run-command'; import { createOverrides, readGraphFileFromGraphArg, } from '../../utils/command-line-utils'; +import { output } from '../../utils/output'; import { handleErrors } from '../../utils/params'; import { projectHasTarget } from '../../utils/project-graph-utils'; import { generateGraph } from '../graph/graph'; @@ -51,6 +52,7 @@ export async function releasePublish( // Apply default configuration to any optional user configuration const { error: configError, nxReleaseConfig } = await createNxReleaseConfig( projectGraph, + await createProjectFileMapUsingProjectGraph(projectGraph), nxJson.release ); if (configError) { diff --git a/packages/nx/src/command-line/release/release.ts b/packages/nx/src/command-line/release/release.ts index e7ebd75ba8904..061781b5491f8 100644 --- a/packages/nx/src/command-line/release/release.ts +++ b/packages/nx/src/command-line/release/release.ts @@ -1,7 +1,8 @@ import { prompt } from 'enquirer'; import { readNxJson } from '../../config/nx-json'; -import { output } from '../../devkit-exports'; +import { createProjectFileMapUsingProjectGraph } from '../../project-graph/file-map-utils'; import { createProjectGraphAsync } from '../../project-graph/project-graph'; +import { output } from '../../utils/output'; import { handleErrors } from '../../utils/params'; import { releaseChangelog, shouldCreateGitHubRelease } from './changelog'; import { ReleaseOptions, VersionOptions } from './command-object'; @@ -55,6 +56,7 @@ export async function release( // Apply default configuration to any optional user configuration const { error: configError, nxReleaseConfig } = await createNxReleaseConfig( projectGraph, + await createProjectFileMapUsingProjectGraph(projectGraph), nxJson.release ); if (configError) { diff --git a/packages/nx/src/command-line/release/utils/git.ts b/packages/nx/src/command-line/release/utils/git.ts index 208c3d1431bca..f49e8fb1e8735 100644 --- a/packages/nx/src/command-line/release/utils/git.ts +++ b/packages/nx/src/command-line/release/utils/git.ts @@ -151,7 +151,29 @@ export async function gitAdd({ logFn?: (...messages: string[]) => void; }): Promise { logFn = logFn || console.log; - const commandArgs = ['add', ...changedFiles]; + + let ignoredFiles: string[] = []; + let filesToAdd: string[] = []; + for (const f of changedFiles) { + const isFileIgnored = await isIgnored(f); + if (isFileIgnored) { + ignoredFiles.push(f); + } else { + filesToAdd.push(f); + } + } + + if (verbose && ignoredFiles.length) { + logFn(`Will not add the following files because they are ignored by git:`); + ignoredFiles.forEach((f) => logFn(f)); + } + + if (!filesToAdd.length) { + logFn('\nNo files to stage. Skipping git add.'); + return; + } + + const commandArgs = ['add', ...filesToAdd]; const message = dryRun ? `Would stage files in git with the following command, but --dry-run was set:` : `Staging files in git with the following command:`; @@ -165,6 +187,16 @@ export async function gitAdd({ return execCommand('git', commandArgs); } +async function isIgnored(filePath: string): Promise { + try { + // This command will error if the file is not ignored + await execCommand('git', ['check-ignore', filePath]); + return true; + } catch { + return false; + } +} + export async function gitCommit({ messages, additionalArgs, diff --git a/packages/nx/src/command-line/release/version.ts b/packages/nx/src/command-line/release/version.ts index 4f70fff6d63f4..80c2a4a299110 100644 --- a/packages/nx/src/command-line/release/version.ts +++ b/packages/nx/src/command-line/release/version.ts @@ -1,24 +1,23 @@ import * as chalk from 'chalk'; +import { execSync } from 'node:child_process'; import { readFileSync } from 'node:fs'; import { relative } from 'node:path'; import { Generator } from '../../config/misc-interfaces'; -import { readNxJson } from '../../config/nx-json'; +import { NxJsonConfiguration, readNxJson } from '../../config/nx-json'; import { ProjectGraph, ProjectGraphProjectNode, } from '../../config/project-graph'; -import { - NxJsonConfiguration, - joinPathFragments, - output, - workspaceRoot, -} from '../../devkit-exports'; import { FsTree, Tree, flushChanges } from '../../generators/tree'; +import { createProjectFileMapUsingProjectGraph } from '../../project-graph/file-map-utils'; import { createProjectGraphAsync, readProjectsConfigurationFromProjectGraph, } from '../../project-graph/project-graph'; +import { output } from '../../utils/output'; import { combineOptionsForGenerator, handleErrors } from '../../utils/params'; +import { joinPathFragments } from '../../utils/path'; +import { workspaceRoot } from '../../utils/workspace-root'; import { parseGeneratorString } from '../generate/generate'; import { getGeneratorInformation } from '../generate/generator-utils'; import { VersionOptions } from './command-object'; @@ -43,6 +42,8 @@ import { handleDuplicateGitTags, } from './utils/shared'; +const LARGE_BUFFER = 1024 * 1000000; + // Reexport some utils for use in plugin release-version generator implementations export { deriveNewSemverVersion } from './utils/semver'; export type { @@ -67,6 +68,9 @@ export interface ReleaseVersionGeneratorSchema { firstRelease?: boolean; // auto means the existing prefix will be preserved, and is the default behavior versionPrefix?: typeof validReleaseVersionPrefixes[number]; + skipLockFileUpdate?: boolean; + installArgs?: string; + installIgnoreScripts?: boolean; } export interface NxReleaseVersionResult { @@ -106,6 +110,7 @@ export async function releaseVersion( // Apply default configuration to any optional user configuration const { error: configError, nxReleaseConfig } = await createNxReleaseConfig( projectGraph, + await createProjectFileMapUsingProjectGraph(projectGraph), nxJson.release ); if (configError) { @@ -148,6 +153,11 @@ export async function releaseVersion( process.exit(1); } + runPreVersionCommand(nxReleaseConfig.version.preVersionCommand, { + dryRun: args.dryRun, + verbose: args.verbose, + }); + const tree = new FsTree(workspaceRoot, args.verbose); const versionData: VersionData = {}; @@ -197,6 +207,7 @@ export async function releaseVersion( args, tree, generatorData, + args.generatorOptionsOverrides, projectNames, releaseGroup, versionData @@ -206,7 +217,10 @@ export async function releaseVersion( const changedFiles = await generatorCallback(tree, { dryRun: !!args.dryRun, verbose: !!args.verbose, - generatorOptions, + generatorOptions: { + ...generatorOptions, + ...args.generatorOptionsOverrides, + }, }); changedFiles.forEach((f) => additionalChangedFiles.add(f)); }); @@ -324,6 +338,7 @@ export async function releaseVersion( args, tree, generatorData, + args.generatorOptionsOverrides, projectNames, releaseGroup, versionData @@ -333,7 +348,10 @@ export async function releaseVersion( const changedFiles = await generatorCallback(tree, { dryRun: !!args.dryRun, verbose: !!args.verbose, - generatorOptions, + generatorOptions: { + ...generatorOptions, + ...args.generatorOptionsOverrides, + }, }); changedFiles.forEach((f) => additionalChangedFiles.add(f)); }); @@ -445,6 +463,7 @@ async function runVersionOnProjects( args: VersionOptions, tree: Tree, generatorData: GeneratorData, + generatorOverrides: Record | undefined, projectNames: string[], releaseGroup: ReleaseGroupWithName, versionData: VersionData @@ -454,6 +473,7 @@ async function runVersionOnProjects( specifier: args.specifier ?? '', preid: args.preid ?? '', ...generatorData.configGeneratorOptions, + ...(generatorOverrides ?? {}), // The following are not overridable by user config projects: projectNames.map((p) => projectGraph.nodes[p]), projectGraph, @@ -610,3 +630,43 @@ function resolveGeneratorData({ throw err; } } +function runPreVersionCommand( + preVersionCommand: string, + { dryRun, verbose }: { dryRun: boolean; verbose: boolean } +) { + if (!preVersionCommand) { + return; + } + + output.logSingleLine(`Executing pre-version command`); + if (verbose) { + console.log(`Executing the following pre-version command:`); + console.log(preVersionCommand); + } + + let env: Record = { + ...process.env, + }; + if (dryRun) { + env.NX_DRY_RUN = 'true'; + } + + const stdio = verbose ? 'inherit' : 'pipe'; + try { + execSync(preVersionCommand, { + encoding: 'utf-8', + maxBuffer: LARGE_BUFFER, + stdio, + env, + }); + } catch (e) { + const title = verbose + ? `The pre-version command failed. See the full output above.` + : `The pre-version command failed. Retry with --verbose to see the full output of the pre-version command.`; + output.error({ + title, + bodyLines: [preVersionCommand, e], + }); + process.exit(1); + } +} diff --git a/packages/nx/src/config/nx-json.ts b/packages/nx/src/config/nx-json.ts index 3abfe052e08b0..c73633a3ca123 100644 --- a/packages/nx/src/config/nx-json.ts +++ b/packages/nx/src/config/nx-json.ts @@ -232,6 +232,12 @@ interface NxReleaseConfiguration { * Enable or override configuration for git operations as part of the version subcommand */ git?: NxReleaseGitConfiguration; + /** + * A command to run after validation of nx release configuration, but before versioning begins. + * Used for preparing build artifacts. If --dry-run is passed, the command is still executed, but + * with the NX_DRY_RUN environment variable set to 'true'. + */ + preVersionCommand?: string; }; /** * Optionally override the git/release tag pattern to use. This field is the source of truth diff --git a/packages/nx/src/executors/run-commands/run-commands.impl.spec.ts b/packages/nx/src/executors/run-commands/run-commands.impl.spec.ts index 624ee827b1f5b..92922c240f523 100644 --- a/packages/nx/src/executors/run-commands/run-commands.impl.spec.ts +++ b/packages/nx/src/executors/run-commands/run-commands.impl.spec.ts @@ -190,6 +190,16 @@ describe('Run Commands', () => { ).toEqual('echo --additional-arg'); }); + it('should add forward unknown options when forwardAllArgs is true', () => { + expect( + interpolateArgsIntoCommand( + 'echo', + { unknownOptions: { hello: 123 }, parsedArgs: { hello: 123 } } as any, + true + ) + ).toEqual('echo --hello 123'); + }); + it('should add all args and unparsed args when forwardAllArgs is true', () => { expect( interpolateArgsIntoCommand( diff --git a/packages/nx/src/executors/run-commands/run-commands.impl.ts b/packages/nx/src/executors/run-commands/run-commands.impl.ts index e1e7b4d5c4cac..630f9a302e9c4 100644 --- a/packages/nx/src/executors/run-commands/run-commands.impl.ts +++ b/packages/nx/src/executors/run-commands/run-commands.impl.ts @@ -62,6 +62,10 @@ const propKeys = [ 'cwd', 'args', 'envFile', + '__unparsed__', + 'env', + 'mode', + 'verbose', ]; export interface NormalizedRunCommandsOptions extends RunCommandsOptions { @@ -69,6 +73,9 @@ export interface NormalizedRunCommandsOptions extends RunCommandsOptions { command: string; forwardAllArgs?: boolean; }[]; + unknownOptions?: { + [k: string]: any; + }; parsedArgs: { [k: string]: any; }; @@ -173,7 +180,25 @@ function normalizeOptions( if (options.args && Array.isArray(options.args)) { options.args = options.args.join(' '); } - options.parsedArgs = parseArgs(options, options.args as string); + + const unparsedCommandArgs = yargsParser(options.__unparsed__, { + configuration: { + 'parse-numbers': false, + 'parse-positional-numbers': false, + 'dot-notation': false, + }, + }); + options.unknownOptions = Object.keys(options) + .filter( + (p) => propKeys.indexOf(p) === -1 && unparsedCommandArgs[p] === undefined + ) + .reduce((m, c) => ((m[c] = options[c]), m), {}); + + options.parsedArgs = parseArgs( + unparsedCommandArgs, + options.unknownOptions, + options.args as string + ); (options as NormalizedRunCommandsOptions).commands.forEach((c) => { c.command = interpolateArgsIntoCommand( @@ -361,7 +386,7 @@ export function interpolateArgsIntoCommand( command: string, opts: Pick< NormalizedRunCommandsOptions, - 'args' | 'parsedArgs' | '__unparsed__' + 'args' | 'parsedArgs' | '__unparsed__' | 'unknownOptions' >, forwardAllArgs: boolean ) { @@ -371,28 +396,38 @@ export function interpolateArgsIntoCommand( opts.parsedArgs[group] !== undefined ? opts.parsedArgs[group] : '' ); } else if (forwardAllArgs) { - return `${command}${opts.args ? ' ' + opts.args : ''}${ - opts.__unparsed__.length > 0 ? ' ' + opts.__unparsed__.join(' ') : '' - }`; + let args = ''; + if (Object.keys(opts.unknownOptions ?? {}).length > 0) { + args += + ' ' + + Object.keys(opts.unknownOptions) + .filter( + (k) => + typeof opts.unknownOptions[k] !== 'object' && + opts.parsedArgs[k] === opts.unknownOptions[k] + ) + .map((k) => `--${k} ${opts.unknownOptions[k]}`) + .join(' '); + } + if (opts.args) { + args += ` ${opts.args}`; + } + if (opts.__unparsed__?.length > 0) { + args += ` ${opts.__unparsed__.join(' ')}`; + } + return `${command}${args}`; } else { return command; } } -function parseArgs(options: RunCommandsOptions, args?: string) { +function parseArgs( + unparsedCommandArgs: { [k: string]: string }, + unknownOptions: { [k: string]: string }, + args?: string +) { if (!args) { - const unknownOptionsTreatedAsArgs = Object.keys(options) - .filter((p) => propKeys.indexOf(p) === -1) - .reduce((m, c) => ((m[c] = options[c]), m), {}); - - const unparsedCommandArgs = yargsParser(options.__unparsed__, { - configuration: { - 'parse-numbers': false, - 'parse-positional-numbers': false, - 'dot-notation': false, - }, - }); - return { ...unknownOptionsTreatedAsArgs, ...unparsedCommandArgs }; + return { ...unknownOptions, ...unparsedCommandArgs }; } return yargsParser(args.replace(/(^"|"$)/g, ''), { configuration: { 'camel-case-expansion': false }, diff --git a/packages/nx/src/plugins/js/lock-file/lock-file.ts b/packages/nx/src/plugins/js/lock-file/lock-file.ts index 00165fe15aca1..10f91d44a39af 100644 --- a/packages/nx/src/plugins/js/lock-file/lock-file.ts +++ b/packages/nx/src/plugins/js/lock-file/lock-file.ts @@ -143,6 +143,19 @@ export function getLockFileName(packageManager: PackageManager): string { throw new Error(`Unknown package manager: ${packageManager}`); } +function getLockFilePath(packageManager: PackageManager): string { + if (packageManager === 'yarn') { + return YARN_LOCK_PATH; + } + if (packageManager === 'pnpm') { + return PNPM_LOCK_PATH; + } + if (packageManager === 'npm') { + return NPM_LOCK_PATH; + } + throw new Error(`Unknown package manager: ${packageManager}`); +} + /** * Create lock file based on the root level lock file and (pruned) package.json * @@ -157,7 +170,7 @@ export function createLockFile( packageManager: PackageManager = detectPackageManager(workspaceRoot) ): string { const normalizedPackageJson = normalizePackageJson(packageJson); - const content = readFileSync(getLockFileName(packageManager), 'utf8'); + const content = readFileSync(getLockFilePath(packageManager), 'utf8'); try { if (packageManager === 'yarn') { diff --git a/packages/nx/src/project-graph/plugins/plugin-pool.ts b/packages/nx/src/project-graph/plugins/plugin-pool.ts index 03bc400612d4b..1c20608c5560a 100644 --- a/packages/nx/src/project-graph/plugins/plugin-pool.ts +++ b/packages/nx/src/project-graph/plugins/plugin-pool.ts @@ -13,16 +13,15 @@ const pool: Set = new Set(); const pidMap = new Map }>(); +interface PromiseBankEntry { + promise: Promise; + resolver: (result: any) => void; + rejector: (err: any) => void; +} + // transaction id (tx) -> Promise, Resolver, Rejecter // Makes sure that we can resolve the correct promise when the worker sends back the result -const promiseBank = new Map< - string, - { - promise: Promise; - resolver: (result: any) => void; - rejecter: (err: any) => void; - } ->(); +const promiseBank = new Map(); export function loadRemoteNxPlugin(plugin: PluginConfiguration, root: string) { // this should only really be true when running unit tests within @@ -71,17 +70,14 @@ export async function shutdownPluginWorkers() { const pending = getPendingPromises(pool, pidMap); - if (pending.length > 0) { - // logger.verbose( - // `[plugin-pool] waiting for ${pending.length} pending operations to complete` - // ); - await Promise.all(pending); + for (const pendingPromise of pending) { + pendingPromise.rejector(new Error('Shutting down')); } // logger.verbose(`[plugin-pool] all pending operations completed`); - for (const p of pool) { - p.kill('SIGINT'); + for (const childProcess of pool) { + childProcess.kill('SIGINT'); } // logger.verbose(`[plugin-pool] all workers killed`); @@ -167,31 +163,31 @@ function createWorkerHandler( } }, createDependenciesResult: ({ tx, ...result }) => { - const { resolver, rejecter } = promiseBank.get(tx); + const { resolver, rejector } = promiseBank.get(tx); if (result.success) { resolver(result.dependencies); } else if (result.success === false) { - rejecter(result.error); + rejector(result.error); } pidMap.get(worker.pid)?.pending.delete(tx); promiseBank.delete(tx); }, createNodesResult: ({ tx, ...result }) => { - const { resolver, rejecter } = promiseBank.get(tx); + const { resolver, rejector } = promiseBank.get(tx); if (result.success) { resolver(result.result); } else if (result.success === false) { - rejecter(result.error); + rejector(result.error); } pidMap.get(worker.pid)?.pending.delete(tx); promiseBank.delete(tx); }, processProjectGraphResult: ({ tx, ...result }) => { - const { resolver, rejecter } = promiseBank.get(tx); + const { resolver, rejector } = promiseBank.get(tx); if (result.success) { resolver(result.graph); } else if (result.success === false) { - rejecter(result.error); + rejector(result.error); } pidMap.get(worker.pid)?.pending.delete(tx); promiseBank.delete(tx); @@ -204,8 +200,8 @@ function createWorkerExitHandler(worker: ChildProcess) { return () => { if (!pluginWorkersShutdown) { pidMap.get(worker.pid)?.pending.forEach((tx) => { - const { rejecter } = promiseBank.get(tx); - rejecter( + const { rejector } = promiseBank.get(tx); + rejector( new Error( `Plugin worker ${ pidMap.get(worker.pid).name ?? worker.pid @@ -228,11 +224,11 @@ function getPendingPromises( pool: Set, pidMap: Map }> ) { - const pendingTxs: Array> = []; + const pendingTxs: Array = []; for (const p of pool) { const { pending } = pidMap.get(p.pid) ?? { pending: new Set() }; for (const tx of pending) { - pendingTxs.push(promiseBank.get(tx)?.promise); + pendingTxs.push(promiseBank.get(tx)); } } return pendingTxs; @@ -243,11 +239,11 @@ function registerPendingPromise( pending: Set, callback: () => void ): Promise { - let resolver, rejecter; + let resolver, rejector; const promise = new Promise((res, rej) => { resolver = res; - rejecter = rej; + rejector = rej; callback(); }).then((val) => { @@ -261,7 +257,7 @@ function registerPendingPromise( promiseBank.set(tx, { promise, resolver, - rejecter, + rejector, }); return promise; } diff --git a/packages/nx/src/project-graph/plugins/public-api.ts b/packages/nx/src/project-graph/plugins/public-api.ts index 917853ca37de4..a1bcd6b25a4fa 100644 --- a/packages/nx/src/project-graph/plugins/public-api.ts +++ b/packages/nx/src/project-graph/plugins/public-api.ts @@ -104,7 +104,7 @@ export type NxPluginV2 = { * Provides a file pattern and function that retrieves configuration info from * those files. e.g. { '**\/*.csproj': buildProjectsFromCsProjFile } */ - createNodes?: CreateNodes; + createNodes?: CreateNodes; // Todo(@AgentEnder): This shouldn't be a full processor, since its only responsible for defining edges between projects. What do we want the API to be? /** diff --git a/packages/playwright/src/generators/configuration/files/playwright.config.ts.template b/packages/playwright/src/generators/configuration/files/playwright.config.ts.template index 5b5d83bd27723..5b72109d6d062 100644 --- a/packages/playwright/src/generators/configuration/files/playwright.config.ts.template +++ b/packages/playwright/src/generators/configuration/files/playwright.config.ts.template @@ -29,7 +29,8 @@ export default defineConfig({ url: '<%= webServerAddress %>', reuseExistingServer: !process.env.CI, cwd: workspaceRoot - },<% } else {%>// webServer: { + },<% } else {%> + // webServer: { // command: 'npm run start', // url: 'http://127.0.0.1:3000', // reuseExistingServer: !process.env.CI, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7eb3dce3e634b..18cd26ece8305 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -273,50 +273,50 @@ devDependencies: specifier: ^3.10.0 version: 3.10.0(rollup@2.79.0) '@nx/angular': - specifier: 18.1.0-beta.1 - version: 18.1.0-beta.1(@angular-devkit/build-angular@17.2.0)(@angular-devkit/core@17.2.0)(@angular-devkit/schematics@17.2.0)(@schematics/angular@17.2.0)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(esbuild@0.19.5)(eslint@8.48.0)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(rxjs@7.8.1)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4) + specifier: 18.1.0-beta.3 + version: 18.1.0-beta.3(@angular-devkit/build-angular@17.2.0)(@angular-devkit/core@17.2.0)(@angular-devkit/schematics@17.2.0)(@schematics/angular@17.2.0)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(esbuild@0.19.5)(eslint@8.48.0)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(rxjs@7.8.1)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4) '@nx/cypress': - specifier: 18.1.0-beta.1 - version: 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + specifier: 18.1.0-beta.3 + version: 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) '@nx/devkit': - specifier: 18.1.0-beta.1 - version: 18.1.0-beta.1(nx@18.1.0-beta.1) + specifier: 18.1.0-beta.3 + version: 18.1.0-beta.3(nx@18.1.0-beta.3) '@nx/esbuild': - specifier: 18.1.0-beta.1 - version: 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + specifier: 18.1.0-beta.3 + version: 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) '@nx/eslint': - specifier: 18.1.0-beta.1 - version: 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(verdaccio@5.15.4) + specifier: 18.1.0-beta.3 + version: 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(verdaccio@5.15.4) '@nx/eslint-plugin': - specifier: 18.1.0-beta.1 - version: 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@6.18.1)(eslint-config-prettier@9.0.0)(eslint@8.48.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + specifier: 18.1.0-beta.3 + version: 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@6.18.1)(eslint-config-prettier@9.0.0)(eslint@8.48.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) '@nx/jest': - specifier: 18.1.0-beta.1 - version: 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4) + specifier: 18.1.0-beta.3 + version: 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4) '@nx/js': - specifier: 18.1.0-beta.1 - version: 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + specifier: 18.1.0-beta.3 + version: 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) '@nx/next': - specifier: 18.1.0-beta.1 - version: 18.1.0-beta.1(@babel/core@7.23.2)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(next@14.0.4)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4)(webpack@5.88.0) + specifier: 18.1.0-beta.3 + version: 18.1.0-beta.3(@babel/core@7.23.2)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(next@14.0.4)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4)(webpack@5.88.0) '@nx/playwright': - specifier: 18.1.0-beta.1 - version: 18.1.0-beta.1(@playwright/test@1.36.1)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + specifier: 18.1.0-beta.3 + version: 18.1.0-beta.3(@playwright/test@1.36.1)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) '@nx/react': - specifier: 18.1.0-beta.1 - version: 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + specifier: 18.1.0-beta.3 + version: 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) '@nx/storybook': - specifier: 18.1.0-beta.1 - version: 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + specifier: 18.1.0-beta.3 + version: 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) '@nx/vite': - specifier: 18.1.0-beta.1 - version: 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4)(vite@5.0.8)(vitest@1.3.1) + specifier: 18.1.0-beta.3 + version: 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4)(vite@5.0.8)(vitest@1.3.1) '@nx/web': - specifier: 18.1.0-beta.1 - version: 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + specifier: 18.1.0-beta.3 + version: 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) '@nx/webpack': - specifier: 18.1.0-beta.1 - version: 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + specifier: 18.1.0-beta.3 + version: 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) '@phenomnomnominal/tsquery': specifier: ~5.0.1 version: 5.0.1(typescript@5.3.3) @@ -543,8 +543,8 @@ devDependencies: specifier: ^5.0.0 version: 5.0.0(esbuild@0.19.5)(webpack@5.88.0) cypress: - specifier: ^13.0.0 - version: 13.0.0 + specifier: ^13.6.6 + version: 13.6.6 cytoscape: specifier: ^3.18.2 version: 3.23.0 @@ -774,8 +774,8 @@ devDependencies: specifier: ^3.10.0 version: 3.10.0(@types/node@18.19.8)(eslint@8.48.0)(less@4.1.3)(rollup@2.79.0)(sass@1.55.0)(stylus@0.59.0)(typescript@5.3.3)(vite@5.0.8) nx: - specifier: 18.1.0-beta.1 - version: 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86) + specifier: 18.1.0-beta.3 + version: 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86) octokit: specifier: ^2.0.14 version: 2.0.14 @@ -945,7 +945,7 @@ devDependencies: specifier: 5.0.8 version: 5.0.8(@types/node@18.19.8)(less@4.1.3)(sass@1.55.0)(stylus@0.59.0) vitest: - specifier: ^1.3.1 + specifier: 1.3.1 version: 1.3.1(@types/node@18.19.8)(less@4.1.3)(sass@1.55.0)(stylus@0.59.0) webpack: specifier: 5.88.0 @@ -7343,10 +7343,10 @@ packages: - supports-color dev: true - /@nrwl/angular@18.1.0-beta.1(@angular-devkit/build-angular@17.2.0)(@angular-devkit/core@17.2.0)(@angular-devkit/schematics@17.2.0)(@schematics/angular@17.2.0)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(esbuild@0.19.5)(eslint@8.48.0)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(rxjs@7.8.1)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-Fu4cR3JPBNcZlAniZuQD+wgSihKr8oINqxxTuTBEL3Pr1SFssw2QC1/dHBv3ux5GTG4PkmE8SjxJL43tId7QmA==} + /@nrwl/angular@18.1.0-beta.3(@angular-devkit/build-angular@17.2.0)(@angular-devkit/core@17.2.0)(@angular-devkit/schematics@17.2.0)(@schematics/angular@17.2.0)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(esbuild@0.19.5)(eslint@8.48.0)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(rxjs@7.8.1)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-IxIZHMulCNELtpCXkJ1mlz9MT0kD59DsQtUxXTlDVgHiK5d4IuWpFhmmedfbJgG1cPgy1pakQIt0nHiVZbnzvw==} dependencies: - '@nx/angular': 18.1.0-beta.1(@angular-devkit/build-angular@17.2.0)(@angular-devkit/core@17.2.0)(@angular-devkit/schematics@17.2.0)(@schematics/angular@17.2.0)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(esbuild@0.19.5)(eslint@8.48.0)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(rxjs@7.8.1)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/angular': 18.1.0-beta.3(@angular-devkit/build-angular@17.2.0)(@angular-devkit/core@17.2.0)(@angular-devkit/schematics@17.2.0)(@schematics/angular@17.2.0)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(esbuild@0.19.5)(eslint@8.48.0)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(rxjs@7.8.1)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4) tslib: 2.6.2 transitivePeerDependencies: - '@angular-devkit/build-angular' @@ -7387,10 +7387,10 @@ packages: - webpack-cli dev: true - /@nrwl/cypress@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-LokZ5hLHMq/UIegmFGqrNE3vC8FCZJLCcEki9DoO+g8MPOkm490gABaYlN2ju1fdR5R/xFcRsZZR60731ZiYcA==} + /@nrwl/cypress@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-XEzpjNIdJWAwqKUtCyziNsfNuUKBV94NWRu7QpXDv2EgYMoLphj4XYsYFRfE7LszZCBdjvNQ2yX05sf+hoO5rg==} dependencies: - '@nx/cypress': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/cypress': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -7414,18 +7414,18 @@ packages: - nx dev: true - /@nrwl/devkit@18.1.0-beta.1(nx@18.1.0-beta.1): - resolution: {integrity: sha512-4nQeuSNzSy+KURBaMb5JOQ363udzaXlZSnvDnCq3pCYGxlSjQjyYFGOivoPmthSxy2zzIMqpyzdxZ8MNGDTCng==} + /@nrwl/devkit@18.1.0-beta.3(nx@18.1.0-beta.3): + resolution: {integrity: sha512-yeJqrH4aLfagFZsnQW+8wuShTaxPs2QbJU9H55tgGpxE4BmGJs7iXXtYGl+B3N+wSNVXTDr3qMeECMtvE8ROEg==} dependencies: - '@nx/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) + '@nx/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) transitivePeerDependencies: - nx dev: true - /@nrwl/esbuild@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-P1pV/w8TQhUpqTJ7q8H4kel9PoxFAurZc6ooN9uHmIk2GugbvwfsKIrzDJDFJ6P7ExZ4AP3+DCHFhZh2A99lHA==} + /@nrwl/esbuild@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-fvAJW6t+7Aqbppm/rKu12HEdNQ6wVv3/njKybJacfIPT3ECMfQoFLuImnZUpkWtf3XYX/apoHbgkOcM7O7PVOg==} dependencies: - '@nx/esbuild': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/esbuild': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -7440,10 +7440,10 @@ packages: - verdaccio dev: true - /@nrwl/eslint-plugin-nx@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@6.18.1)(eslint-config-prettier@9.0.0)(eslint@8.48.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-mVLOnpqZMZNbOmcZ7bt9reHFySZiUAcKtucKzEBFMAN9HZWO2SG1Ri85ImQ0L35J3dmzex/9lawUCi4K0ITBrg==} + /@nrwl/eslint-plugin-nx@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@6.18.1)(eslint-config-prettier@9.0.0)(eslint@8.48.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-tMTPuBUwzDfU/sSXFplBXTkoNZkaak2yG7WPc9cOLgRgGkv91lAgR2StvGF1Q63i6fzyZXCUj9qC5ND1PmelNw==} dependencies: - '@nx/eslint-plugin': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@6.18.1)(eslint-config-prettier@9.0.0)(eslint@8.48.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/eslint-plugin': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@6.18.1)(eslint-config-prettier@9.0.0)(eslint@8.48.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -7460,10 +7460,10 @@ packages: - verdaccio dev: true - /@nrwl/jest@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-+8LzzpMXrJQ8eGYqH4mMR+mtKQOCcRsR2LYo8ojFUqT1plTWLUiuAi2i7kT1XPZ9q99DVn496Nwqp0E4gDfJvg==} + /@nrwl/jest@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-FfwoEoyF9OS5qFEE1aNdM362SjqOCQdZJsCBELTT3NlsUoST3ZUVaVrzcc0PRN8AnOq0x/pujINldyhz1CJL9w==} dependencies: - '@nx/jest': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/jest': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -7496,10 +7496,10 @@ packages: - verdaccio dev: true - /@nrwl/js@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-S139n9/IND3e3dk9s6qokfY45ytjFLKrvu+5ZXvjER1DvkkUJIkGzN4jN4T6I2RJkk9q7oJ2KgpJsovXvceQ2A==} + /@nrwl/js@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-7KHsrke30OSID1Nlx5dAn+HJj/MliI2Xvpv3qunGBaxsjbHA6njWziXhiZcH/eAMq7FwUJdHbbJ5Y2cDGwz+zQ==} dependencies: - '@nx/js': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/js': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -7513,10 +7513,10 @@ packages: - verdaccio dev: true - /@nrwl/next@18.1.0-beta.1(@babel/core@7.23.2)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(next@14.0.4)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4)(webpack@5.88.0): - resolution: {integrity: sha512-6zi/W7eGLUN9s7PCvzgdqDi/DvxE0nnwn/Jraqe9bOFflidxqNbB6+NK/spUXKT5aUerqb36Tp/KGwSHg/IgWQ==} + /@nrwl/next@18.1.0-beta.3(@babel/core@7.23.2)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(next@14.0.4)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4)(webpack@5.88.0): + resolution: {integrity: sha512-/P8K2Rj+wJwqb5GoTcnBFRT1hA65HGZ2xw4/CwsvxnURZr/BnMfa/Ml2xNlkQokukRV53NqNzkwcDZV49n/yqQ==} dependencies: - '@nx/next': 18.1.0-beta.1(@babel/core@7.23.2)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(next@14.0.4)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4)(webpack@5.88.0) + '@nx/next': 18.1.0-beta.3(@babel/core@7.23.2)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(next@14.0.4)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4)(webpack@5.88.0) transitivePeerDependencies: - '@babel/core' - '@babel/traverse' @@ -7551,10 +7551,10 @@ packages: - webpack-cli dev: true - /@nrwl/react@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-Zra+NxPdsxM20TKcE9l+ZtvBjeycdciEjrGaCSeXllagw0uQyT/Uk8mSJpjnx7X+gD41Gw+0dpiQlywBULua5A==} + /@nrwl/react@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-FyVN5fXyZsB6RK7mPdJuLIlGhDAQJMtSnixW5C3/nODYdpXkCWSXGLxZf5tMuluMqtkmSq0hXpcP3vq1ZBob2A==} dependencies: - '@nx/react': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/react': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -7569,10 +7569,10 @@ packages: - verdaccio dev: true - /@nrwl/storybook@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-trnFKDaDZISxQ/jBDOXP/aEBcKIrGxxAK59D/bhUH0oVLiYjU4opw1HyNaVxQWYdHZ0qsaO8HmP3PbkyRLpL2A==} + /@nrwl/storybook@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-DT8/MfvqssOQzLN/uiVg85opx7EoGCCVGqa0mWiiHw2nsbhBeS/nyi1MJV/U6fspmBnvx/3YZr23EAWm/BZahA==} dependencies: - '@nx/storybook': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/storybook': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -7600,11 +7600,11 @@ packages: - debug dev: true - /@nrwl/tao@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86): - resolution: {integrity: sha512-tm874jGUd6k93y768G32kslow3S1NaKhqEQq75OsKvu8GjJru/UOy8MNP+oHN6AIEaGSlV3UYjcBM0YIp7U/tQ==} + /@nrwl/tao@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86): + resolution: {integrity: sha512-AuFnRaJ96PK0b8qXQVxIWJBYeeUB+haZ2PFjKHWCGD4b39dALSSTTcA+iCayTVoNaUU+qHYrAFUs4TyZ45T83A==} hasBin: true dependencies: - nx: 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86) + nx: 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86) tslib: 2.6.2 transitivePeerDependencies: - '@swc-node/register' @@ -7612,10 +7612,10 @@ packages: - debug dev: true - /@nrwl/vite@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4)(vite@5.0.8)(vitest@1.3.1): - resolution: {integrity: sha512-AECmGPhW1lTDIAuRFgGCEHxjaKrTCs3R7LL2l/J3zL+d56d/XDnZwB3o5E5xvCwoHWY0vGoAjDtCF2GHv1/oiA==} + /@nrwl/vite@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4)(vite@5.0.8)(vitest@1.3.1): + resolution: {integrity: sha512-19LsEE4Au51fL1LCL8anW1i2svMnrDwYSSAzKeWLanKQnxsIoMUdfYXrSht9EVXEAkA5shcMlTeBc+qD/L84Vg==} dependencies: - '@nx/vite': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4)(vite@5.0.8)(vitest@1.3.1) + '@nx/vite': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4)(vite@5.0.8)(vitest@1.3.1) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -7631,10 +7631,10 @@ packages: - vitest dev: true - /@nrwl/web@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-8WNMipm+MjGncoGMs6gtiUxWj7P53PEMTseKx7lSJwunlMBaEHd0GADWMjRRTsshwyoozSTzRkLjCtXQGR2L8Q==} + /@nrwl/web@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-oXjKEp8cibHDNL5LbjkEKKEAbbFqwT3PjBIQcRHta4amZmU1gQeC444QeNRm4rx1bQbw8CLSw5ht48DCv8iv7Q==} dependencies: - '@nx/web': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/web': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -7648,10 +7648,10 @@ packages: - verdaccio dev: true - /@nrwl/webpack@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-LVvbq/g6EDZLHiIXMUAwVhAXNgrdtapFaH5nLljvRiu7ALODbvHh78Dpd7Kly02x3wRboHuH49+3cdpw2uICnA==} + /@nrwl/webpack@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-qofWcWGX4lmABn0ZuyRCrLUSVab1Q+NFvvQ3nYsPMy0O4i8oqFslMsgBknvAnIVXqajeoovf8w0cc0Ok7qhGMw==} dependencies: - '@nx/webpack': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/webpack': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) transitivePeerDependencies: - '@babel/traverse' - '@parcel/css' @@ -7691,10 +7691,10 @@ packages: - debug dev: true - /@nrwl/workspace@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86): - resolution: {integrity: sha512-ahZeqyScvLI7v6lc5h7THQ05SO0YN2+f/AmzgAz2TWrl+s9KasSAfa7SWqxE025UB2RG1aD6fIkcU8tDuOCLAA==} + /@nrwl/workspace@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86): + resolution: {integrity: sha512-C7oRm4Wq3dipE2HFr8Db+x8dsJQPE3HMN6WCmotHDwIVciOeXduxFXpQtgUleMPnHMy0wDdc7pDJY4jitUGmoA==} dependencies: - '@nx/workspace': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86) + '@nx/workspace': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86) transitivePeerDependencies: - '@swc-node/register' - '@swc/core' @@ -7938,8 +7938,8 @@ packages: - encoding dev: true - /@nx/angular@18.1.0-beta.1(@angular-devkit/build-angular@17.2.0)(@angular-devkit/core@17.2.0)(@angular-devkit/schematics@17.2.0)(@schematics/angular@17.2.0)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(esbuild@0.19.5)(eslint@8.48.0)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(rxjs@7.8.1)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-JP1tC8L7csyGBRtgK8NmpBf3QaplTPNOeoT8va+/9Crqdrg9eq0AjwOxD8RUIW3MzKfu6krXbQhNPGOXPPggLw==} + /@nx/angular@18.1.0-beta.3(@angular-devkit/build-angular@17.2.0)(@angular-devkit/core@17.2.0)(@angular-devkit/schematics@17.2.0)(@schematics/angular@17.2.0)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(esbuild@0.19.5)(eslint@8.48.0)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(rxjs@7.8.1)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-5vxbgjGcSfbZ5iskixn4gViEZUng7YAdhxjsEcAx1vWG329Jmv2f6wn5k3Jd2nrVpzJ6xlPnPQT77mWDnzcZ6Q==} peerDependencies: '@angular-devkit/build-angular': '>= 15.0.0 < 18.0.0' '@angular-devkit/core': '>= 15.0.0 < 18.0.0' @@ -7954,15 +7954,15 @@ packages: '@angular-devkit/build-angular': 17.2.0(@angular/compiler-cli@17.2.1)(@swc/core@1.3.86)(@types/express@4.17.14)(@types/node@18.19.8)(html-webpack-plugin@5.5.0)(jest-environment-jsdom@29.4.3)(jest@29.4.3)(ng-packagr@17.2.0)(stylus@0.59.0)(tailwindcss@3.2.4)(typescript@5.3.3) '@angular-devkit/core': 17.2.0 '@angular-devkit/schematics': 17.2.0 - '@nrwl/angular': 18.1.0-beta.1(@angular-devkit/build-angular@17.2.0)(@angular-devkit/core@17.2.0)(@angular-devkit/schematics@17.2.0)(@schematics/angular@17.2.0)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(esbuild@0.19.5)(eslint@8.48.0)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(rxjs@7.8.1)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/cypress': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) - '@nx/eslint': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(verdaccio@5.15.4) - '@nx/jest': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/js': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/web': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/webpack': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/workspace': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86) + '@nrwl/angular': 18.1.0-beta.3(@angular-devkit/build-angular@17.2.0)(@angular-devkit/core@17.2.0)(@angular-devkit/schematics@17.2.0)(@schematics/angular@17.2.0)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(esbuild@0.19.5)(eslint@8.48.0)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(rxjs@7.8.1)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/cypress': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) + '@nx/eslint': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(verdaccio@5.15.4) + '@nx/jest': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/js': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/web': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/webpack': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/workspace': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86) '@phenomnomnominal/tsquery': 5.0.1(typescript@5.3.3) '@schematics/angular': 17.2.0 '@typescript-eslint/type-utils': 6.18.1(eslint@8.48.0)(typescript@5.3.3) @@ -8011,20 +8011,20 @@ packages: - webpack-cli dev: true - /@nx/cypress@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-c1QRF2kazJQGruFqqWIAcOEwthqAlw4l+blgVMICiUpP2kEms2vt2GNBSs4JTk4mPVGyq+qy+xsHjwTNQfpRRw==} + /@nx/cypress@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-PLSABQ4cRr7OFIi18mWE/PDI1fGr1DTKU4GBpw9Q+V3IWBFi+BwFo9bzlpEpta7dS3LFzofs03/E6X14hZAngw==} peerDependencies: cypress: '>= 3 < 14' peerDependenciesMeta: cypress: optional: true dependencies: - '@nrwl/cypress': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) - '@nx/eslint': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(verdaccio@5.15.4) - '@nx/js': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nrwl/cypress': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) + '@nx/eslint': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(verdaccio@5.15.4) + '@nx/js': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) '@phenomnomnominal/tsquery': 5.0.1(typescript@5.3.3) - cypress: 13.0.0 + cypress: 13.6.6 detect-port: 1.5.1 semver: 7.6.0 tslib: 2.6.2 @@ -8057,33 +8057,33 @@ packages: tslib: 2.6.2 dev: true - /@nx/devkit@18.1.0-beta.1(nx@18.1.0-beta.1): - resolution: {integrity: sha512-yUXVYkoFHaqAq5jdtLHWmAKhfQ7wIZoRr70MQRkrJeOhoswnyAhUiExiQnRqx3D+/YcCWpHUC7T8i0oIzookWw==} + /@nx/devkit@18.1.0-beta.3(nx@18.1.0-beta.3): + resolution: {integrity: sha512-zSWiwEWFtmw2rHfNWiVkVZz+eknz4eMzWAkDYvGG1i9TYTgEhvLccK+38BP2IHixFTgFvyLCVWjoThLaiuPELw==} peerDependencies: nx: '>= 16 <= 18' dependencies: - '@nrwl/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) + '@nrwl/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) ejs: 3.1.8 enquirer: 2.3.6 ignore: 5.3.1 - nx: 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86) + nx: 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86) semver: 7.6.0 tmp: 0.2.1 tslib: 2.6.2 yargs-parser: 21.1.1 dev: true - /@nx/esbuild@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-hyNShzkh1VjBMMeWI6UsRCECilmCI7TqCqlsiNZpIVUg5ltNKuuuV9O+pz4GnJf8F5ShceogFWfIgb3lv7gdwQ==} + /@nx/esbuild@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-8t2eXgTFF51a+CrV1xDlB6psFGbllnp8ff8uDbk4U68+fpgEMhprnMFwjzy3/EG569jy8QGfKdJZdJWQNS/H1w==} peerDependencies: esbuild: ~0.19.2 peerDependenciesMeta: esbuild: optional: true dependencies: - '@nrwl/esbuild': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) - '@nx/js': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nrwl/esbuild': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) + '@nx/js': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) chalk: 4.1.2 esbuild: 0.19.5 fast-glob: 3.2.7 @@ -8103,8 +8103,8 @@ packages: - verdaccio dev: true - /@nx/eslint-plugin@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@6.18.1)(eslint-config-prettier@9.0.0)(eslint@8.48.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-334dKbydn2pnH+qj0kZRutho8N0luu1WT/46a8O3Gvp5Kei74xy3SMar4YDKruC1cN5JaSw1wQQcYLcMBbj6RQ==} + /@nx/eslint-plugin@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@6.18.1)(eslint-config-prettier@9.0.0)(eslint@8.48.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-mvJFH7dy6HisbwgqO+LZfPwNehh8UjxmOFCMc2+YmDLzoHQTu6wBtyVK9bH+lQnYxPFiNhIwKWn2C7x19dhYJA==} peerDependencies: '@typescript-eslint/parser': ^6.13.2 eslint-config-prettier: ^9.0.0 @@ -8112,9 +8112,9 @@ packages: eslint-config-prettier: optional: true dependencies: - '@nrwl/eslint-plugin-nx': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@6.18.1)(eslint-config-prettier@9.0.0)(eslint@8.48.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) - '@nx/js': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nrwl/eslint-plugin-nx': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@6.18.1)(eslint-config-prettier@9.0.0)(eslint@8.48.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) + '@nx/js': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) '@typescript-eslint/parser': 6.18.1(eslint@8.48.0)(typescript@5.3.3) '@typescript-eslint/type-utils': 6.18.1(eslint@8.48.0)(typescript@5.3.3) '@typescript-eslint/utils': 6.18.1(eslint@8.48.0)(typescript@5.3.3) @@ -8138,17 +8138,17 @@ packages: - verdaccio dev: true - /@nx/eslint@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(verdaccio@5.15.4): - resolution: {integrity: sha512-TgdLWR3VNSoiaiffbGtQVWo7mqHEEMre3jB4zYaJ0QnmenPcOKu8DnBeevMsr4vYR7+F0KchCR7M6U0ln3q87A==} + /@nx/eslint@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-PPwJUSMxOcPTZlFD/Qu//jbJKJSy8OWAulIB1LRuTXVAkd8RKWI/64cc+lw1HBlvD4q7Vg9PcUgbvXCx3yjo1g==} peerDependencies: js-yaml: 4.1.0 peerDependenciesMeta: js-yaml: optional: true dependencies: - '@nx/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) - '@nx/js': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/linter': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(verdaccio@5.15.4) + '@nx/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) + '@nx/js': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/linter': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(verdaccio@5.15.4) eslint: 8.48.0 js-yaml: 4.1.0 tslib: 2.6.2 @@ -8165,14 +8165,14 @@ packages: - verdaccio dev: true - /@nx/jest@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-ZHZjUARvH5iibfj/Sw5Nsa7L9Sb+j//lglBIFJe9GIM+kSPJs6h11Nne/KLAzeGnAqL1mghkuj5pZyCWZG8HNQ==} + /@nx/jest@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-oF8pNwjqLosbdz2tZzT60Rjwx+nFO83KBqO2AN1t0WyBNx6zaQpTUkjXoVsTVoWrBT/VJceELR93w+Gj6js88Q==} dependencies: '@jest/reporters': 29.5.0 '@jest/test-result': 29.7.0 - '@nrwl/jest': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) - '@nx/js': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nrwl/jest': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(ts-node@10.9.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) + '@nx/js': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) '@phenomnomnominal/tsquery': 5.0.1(typescript@5.3.3) chalk: 4.1.2 identity-obj-proxy: 3.0.0 @@ -8182,6 +8182,7 @@ packages: minimatch: 9.0.3 resolve.exports: 1.1.0 tslib: 2.6.2 + yargs-parser: 21.1.1 transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -8248,8 +8249,8 @@ packages: - typescript dev: true - /@nx/js@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-o7bzlr/KUdqiz2wwNjnWVaAmQ3uT4GUSrBPPxGHLhLPXN8l3qHJuHjdvK98uiYwzdKJkz/r5Kf4fydFpD2/GHw==} + /@nx/js@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-iUDfzcM+mC/u/Q19tvKohSxjVtjr6mfPXJr+Sg3UPxtZnPpjtbxag5dknRyRnVj/7stYGpy0lStjmxSZcqkRlg==} peerDependencies: verdaccio: ^5.0.4 peerDependenciesMeta: @@ -8263,9 +8264,9 @@ packages: '@babel/preset-env': 7.23.9(@babel/core@7.23.9) '@babel/preset-typescript': 7.22.5(@babel/core@7.23.9) '@babel/runtime': 7.23.9 - '@nrwl/js': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) - '@nx/workspace': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86) + '@nrwl/js': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) + '@nx/workspace': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86) '@phenomnomnominal/tsquery': 5.0.1(typescript@5.3.3) babel-plugin-const-enum: 1.2.0(@babel/core@7.23.9) babel-plugin-macros: 2.8.0 @@ -8299,10 +8300,10 @@ packages: - typescript dev: true - /@nx/linter@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(verdaccio@5.15.4): - resolution: {integrity: sha512-NusUrjBOZJkTVN9VXnozUcQWvVzDYsBOOAJx/BKXriRf2ltZM4oWK97AJX10QbeyfbAQ0qitY69dGACs5FGwKg==} + /@nx/linter@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-5ImfoppPzkoSVKwBoknslcYv2X1jikTIY4qwuV5Jc3Fv3g18Z9z/XKDPdur3lXZNDSXp9nRctxXh0T12rcws5A==} dependencies: - '@nx/eslint': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(verdaccio@5.15.4) + '@nx/eslint': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(verdaccio@5.15.4) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -8316,20 +8317,20 @@ packages: - verdaccio dev: true - /@nx/next@18.1.0-beta.1(@babel/core@7.23.2)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(next@14.0.4)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4)(webpack@5.88.0): - resolution: {integrity: sha512-AAa7xVDU7MEbDhlWb8ARlEsAW0o4T95kYmYOerF71WPj2npo+9iqO7i81xQwz66v18UhX8I9fFZjYYiLoJlQjQ==} + /@nx/next@18.1.0-beta.3(@babel/core@7.23.2)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(next@14.0.4)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4)(webpack@5.88.0): + resolution: {integrity: sha512-Qqxi5raVsx7Yzd9WA8z6hSJCPvwqnXWMnpYgJHxQttH133+yie39XYkwprqq7cK3YCqeKyEQMzbjomU7sr8bvg==} peerDependencies: next: '>=14.0.0' dependencies: '@babel/plugin-proposal-decorators': 7.23.9(@babel/core@7.23.2) - '@nrwl/next': 18.1.0-beta.1(@babel/core@7.23.2)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(next@14.0.4)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4)(webpack@5.88.0) - '@nx/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) - '@nx/eslint': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(verdaccio@5.15.4) - '@nx/js': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/react': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/web': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/webpack': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/workspace': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86) + '@nrwl/next': 18.1.0-beta.3(@babel/core@7.23.2)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(js-yaml@4.1.0)(next@14.0.4)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4)(webpack@5.88.0) + '@nx/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) + '@nx/eslint': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(verdaccio@5.15.4) + '@nx/js': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/react': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/web': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/webpack': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/workspace': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86) '@svgr/webpack': 8.0.1(typescript@5.3.3) chalk: 4.1.2 copy-webpack-plugin: 10.2.4(webpack@5.88.0) @@ -8382,8 +8383,8 @@ packages: dev: true optional: true - /@nx/nx-darwin-arm64@18.1.0-beta.1: - resolution: {integrity: sha512-5V3UtTVJ6n6nCwGN4r9FoRlsYIBB2iW+3D/qf3a/dB5bavieWjQ8ySbfGTbqezsUR4aXBQWT1u2vOc5Cf/ICbQ==} + /@nx/nx-darwin-arm64@18.1.0-beta.3: + resolution: {integrity: sha512-JO02jAPxWAeFxHZJR4z6HTc76ynDOKmPdDLtC1gL9JvJqdwREeOrlEVkMLb72OCxJVldEuhNl5cey1wAuyCNMA==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -8400,8 +8401,8 @@ packages: dev: true optional: true - /@nx/nx-darwin-x64@18.1.0-beta.1: - resolution: {integrity: sha512-lDwNMPI+TyJM98fxagN1IXbLNrbiTDd+0KiOxo51wuSIW4p5462N7NME4zqpXzRzWPgwBkXCF8ub9MmZvDtFFw==} + /@nx/nx-darwin-x64@18.1.0-beta.3: + resolution: {integrity: sha512-Rfe/gyemaiw5OuZKPMiX31fRGhnwSdmqOaN7aBhA1FYZ7DxPBODprZJYzSsxFA2rOy6jjVFnSWUSEUTyES7Nkw==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -8418,8 +8419,8 @@ packages: dev: true optional: true - /@nx/nx-freebsd-x64@18.1.0-beta.1: - resolution: {integrity: sha512-8ZQ+hNZ7ArD8cWjDRHoR/OyavCrdzGtpTRrw1K0cUhdmuQWrrt3jk3LSiGztSlDBuVrJodh70baGro6A6xdXAA==} + /@nx/nx-freebsd-x64@18.1.0-beta.3: + resolution: {integrity: sha512-3O+PxrXcfbLZCkCMO0gwEN2wFUpHI9KcER1cMXa9ZwwYUk08mlfcC3VtPJqmebNycLV41ufDLhqaeaW2HY8yDQ==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] @@ -8436,8 +8437,8 @@ packages: dev: true optional: true - /@nx/nx-linux-arm-gnueabihf@18.1.0-beta.1: - resolution: {integrity: sha512-OLWiJiBsZuPbMhK270A+fjVyCH6ELKv1JTgmzPjJfFfUkbrP7e0dIwJUrkUMM7ppxJYpzy6849d61D6WKLOOQw==} + /@nx/nx-linux-arm-gnueabihf@18.1.0-beta.3: + resolution: {integrity: sha512-TSXbc/ZuJXtnpdd/8zA5TmUn7ZtVAZWGKzffq6YmlQ+TrQC7T2l3239EqxUOTIrZhEbob7h7VCdCuBLCF7V/jQ==} engines: {node: '>= 10'} cpu: [arm] os: [linux] @@ -8454,8 +8455,8 @@ packages: dev: true optional: true - /@nx/nx-linux-arm64-gnu@18.1.0-beta.1: - resolution: {integrity: sha512-t5MAjd7kbbVyCc6m0r1wIThCRFuN35beZ6nNaVs5dLScxOkeBe+o21eSvLLCzk5HYM8UgBb5Ys9p16ENsiym0Q==} + /@nx/nx-linux-arm64-gnu@18.1.0-beta.3: + resolution: {integrity: sha512-hPKLiSXRIwRhAuJ+iXfCCHEl6bM8+qVrKmcUOE5HF7lj1udDnPcHRQ7Clu2n/Si/yx8ALnl8h/MaLcVcE32zjw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -8472,8 +8473,8 @@ packages: dev: true optional: true - /@nx/nx-linux-arm64-musl@18.1.0-beta.1: - resolution: {integrity: sha512-53eav3uxZgBWdqgLJlSCgCbZKpOOAMoBQTyEPkwAhORGVyEB/snZqKAzkZza7zNo56OFN1epe16F610aznuN/Q==} + /@nx/nx-linux-arm64-musl@18.1.0-beta.3: + resolution: {integrity: sha512-92hFccui1fNpBBUxIJyIuOmREwlCaspXk1r+50EhCjIONjSucmlhiUZezqllMMDcdyE0OMoV87dVuTIw9yDxWg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -8490,8 +8491,8 @@ packages: dev: true optional: true - /@nx/nx-linux-x64-gnu@18.1.0-beta.1: - resolution: {integrity: sha512-uHuxE2Bvq4+plY8vnE/Ooh3CyacG4me9ywnwvouL9lopMhojfAvl9VN8ZjR+0dyi9/7hSoAD2SjzyUj9pVW7wQ==} + /@nx/nx-linux-x64-gnu@18.1.0-beta.3: + resolution: {integrity: sha512-BL7NJAxn51M0wTmf9qwhsQzlp2Czb/yf629tlGJSe1nAAsiJ1r2zIvyJq2Aq2692oB5PqXk+Y9R8otVDAI0FuA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -8508,8 +8509,8 @@ packages: dev: true optional: true - /@nx/nx-linux-x64-musl@18.1.0-beta.1: - resolution: {integrity: sha512-q4mwcWP6dwuTU6zJG/0Mz2DQeLCDgi4UmJGxDfeFYxHCcrtJtPEtmZ5HaPShqheqdtmxNtP+ukpjTxvqnX0wDQ==} + /@nx/nx-linux-x64-musl@18.1.0-beta.3: + resolution: {integrity: sha512-zGzTUS0PwKUeM5OL0KyD7AEKZtDHdn0KOQBD+zh4BEc6jH81eaL/G16QZu/5e4hGzNAopNjLFR/Ck5y+PD1BXA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -8526,8 +8527,8 @@ packages: dev: true optional: true - /@nx/nx-win32-arm64-msvc@18.1.0-beta.1: - resolution: {integrity: sha512-XyWY432WltBwQ8+wPNjwRqAgCvanPbVyiGaNUJRk196p2MPoYr5X+O4kmb0ydhXJdW1biYHwPxV/RB/1wZAAyw==} + /@nx/nx-win32-arm64-msvc@18.1.0-beta.3: + resolution: {integrity: sha512-+KwvGMWMNgeBGmCdL48a2C5lcYLOy+YEAlLk2JI2mXLQ4n8vKHFG+KSOd4tPLzjN1NTyIxO3ONDTbnog8i9HHg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] @@ -8544,8 +8545,8 @@ packages: dev: true optional: true - /@nx/nx-win32-x64-msvc@18.1.0-beta.1: - resolution: {integrity: sha512-Zs9gJrY+tVQENyhFTKcIRvve/5PTXuYTS7VZCgp48/sF5LAtZEoYncAeQHEBKXQSsaopJRV40iEXhHye1yPCqg==} + /@nx/nx-win32-x64-msvc@18.1.0-beta.3: + resolution: {integrity: sha512-NrDH5A4or+/BfHeI83SEdVBxrU+IAEv9I1Xt24Dsux0NVNcI+glydFZhGAeuS0EkXGMVlzGyM79gHBVuV7FM9g==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -8553,17 +8554,17 @@ packages: dev: true optional: true - /@nx/playwright@18.1.0-beta.1(@playwright/test@1.36.1)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-wa9VcTvtXVsQnHFoKXmGr68JQxAbviRgTmggaeqx6Yglspkm5Utvjz8EbaiX7L/LyFte6eeh59N0DbpSzh0Wpw==} + /@nx/playwright@18.1.0-beta.3(@playwright/test@1.36.1)(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-6xckL6Lo5mii3UgPJE6MIs1TrQogpQneonn8NnB7+dUH2AatzhEu62WqN4Y1pcs0q3nPEKWtmLSq4lim0Kplcw==} peerDependencies: '@playwright/test': ^1.36.0 peerDependenciesMeta: '@playwright/test': optional: true dependencies: - '@nx/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) - '@nx/eslint': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(verdaccio@5.15.4) - '@nx/js': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) + '@nx/eslint': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(verdaccio@5.15.4) + '@nx/js': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) '@phenomnomnominal/tsquery': 5.0.1(typescript@5.3.3) '@playwright/test': 1.36.1 minimatch: 9.0.3 @@ -8582,14 +8583,14 @@ packages: - verdaccio dev: true - /@nx/react@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-vjlhZ9deBZohsnTSfivgAyaOpkFQt77fVOzmRxb6oHUqlzPkL4T2N5qCT4xVNQcjWRbU+7obyVIMmNgeNDGWnQ==} + /@nx/react@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-xLOD5B7EprXLWgVJvyiqnE0t78jHvUUpUDs2u948QFQekG06lgHPgLtnEldEyzJtiPW1CzHeFEjBL5sWxK4YeA==} dependencies: - '@nrwl/react': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) - '@nx/eslint': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(verdaccio@5.15.4) - '@nx/js': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/web': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nrwl/react': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) + '@nx/eslint': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(verdaccio@5.15.4) + '@nx/js': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/web': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) '@phenomnomnominal/tsquery': 5.0.1(typescript@5.3.3) '@svgr/webpack': 8.0.1(typescript@5.3.3) chalk: 4.1.2 @@ -8609,14 +8610,14 @@ packages: - verdaccio dev: true - /@nx/storybook@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-m5tRDIrLQARw3sl9d8d69HweudQOhnu6VGAQDTwHIX26v/d1bX88ExjubfbDm5lQogtQm2biPiRM0GjTNWiFEg==} + /@nx/storybook@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-Bs39QXa8TwNDvrdq6tvUPfdZIUDh10V+fu4np29xii6GJt2uoUV88ERs+JODMKaGu/UJ2Jdm+GQJ5tlpg0etMg==} dependencies: - '@nrwl/storybook': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/cypress': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.0.0)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) - '@nx/eslint': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.1)(verdaccio@5.15.4) - '@nx/js': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nrwl/storybook': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/cypress': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(cypress@13.6.6)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) + '@nx/eslint': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.1.0-beta.3)(verdaccio@5.15.4) + '@nx/js': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) '@phenomnomnominal/tsquery': 5.0.1(typescript@5.3.3) semver: 7.6.0 tslib: 2.6.2 @@ -8635,15 +8636,15 @@ packages: - verdaccio dev: true - /@nx/vite@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4)(vite@5.0.8)(vitest@1.3.1): - resolution: {integrity: sha512-/6NGrYBVwTIxcVijZP5wAqH4ZeV+1bvOex5fXePj5nBHKEtGbP82TS43O0x4yDAXo6gP6ugLKrSU5FwhXrDWDw==} + /@nx/vite@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4)(vite@5.0.8)(vitest@1.3.1): + resolution: {integrity: sha512-0BXxhUKZAPFJ4Ez1Uls6z6gV9P9N+bbTp0Qn0LNkyhgho7yXGwUM6Fw4qB6unurvi3ZtJZq0xhcU6UFH+e/YDw==} peerDependencies: vite: ^5.0.0 - vitest: ^1.0.0 + vitest: ^1.3.1 dependencies: - '@nrwl/vite': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4)(vite@5.0.8)(vitest@1.3.1) - '@nx/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) - '@nx/js': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nrwl/vite': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4)(vite@5.0.8)(vitest@1.3.1) + '@nx/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) + '@nx/js': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) '@phenomnomnominal/tsquery': 5.0.1(typescript@5.3.3) '@swc/helpers': 0.5.3 enquirer: 2.3.6 @@ -8663,12 +8664,12 @@ packages: - verdaccio dev: true - /@nx/web@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-OcJpZDNhrgF/voHrBH+0lrqaVtoeWU0bKMz56zYlIIhaC8ywKhxS+gmZv7oJd47B8Zc8UHcMwevn/9vtUtTJoQ==} + /@nx/web@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-eZ7X++m+FoT9EtpxAIxhHYXd8MqvXagfzPPdeVul9u3WwxfQ3hMbuDumEmATbDEzBvNWTXE0cYQHvbI7bBQWrA==} dependencies: - '@nrwl/web': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) - '@nx/js': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nrwl/web': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) + '@nx/js': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) chalk: 4.1.2 detect-port: 1.5.1 http-server: 14.1.0 @@ -8686,13 +8687,13 @@ packages: - verdaccio dev: true - /@nx/webpack@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4): - resolution: {integrity: sha512-E5bNuJUj8IjPcVBGpQJqwFfkBoT24ZtWakPfBIXOpX0OE3bRldOwIrJWL1dihOxt4OAQP6IZKJ0vBG2+y3wv2Q==} + /@nx/webpack@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4): + resolution: {integrity: sha512-MjmBUaMwxnJ9WMGjq43VoLa83OBYiVNcmEmkLcVFNp7PG/4fgOxm+ImKTvMMZQ3IiwDQzDVS3cP+oo1JVlHVnw==} dependencies: '@babel/core': 7.23.9 - '@nrwl/webpack': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) - '@nx/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) - '@nx/js': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.1)(typescript@5.3.3)(verdaccio@5.15.4) + '@nrwl/webpack': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(esbuild@0.19.5)(html-webpack-plugin@5.5.0)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) + '@nx/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) + '@nx/js': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.1.0-beta.3)(typescript@5.3.3)(verdaccio@5.15.4) ajv: 8.12.0 autoprefixer: 10.4.13(postcss@8.4.19) babel-loader: 9.1.3(@babel/core@7.23.9)(webpack@5.88.0) @@ -8771,14 +8772,14 @@ packages: - debug dev: true - /@nx/workspace@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86): - resolution: {integrity: sha512-/8fJeFsGJHZptfgJhAcELGo9meCHRDZx/cbPoI+OLqNE+kD9SZEHkjqrt2K5qXN8DLi9o2lW1p7Rbxd3/N7FzQ==} + /@nx/workspace@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86): + resolution: {integrity: sha512-s3sG6y39GkcaK7cAyaQS/IT72EPbQXsBjkBe0794P6lSAF1beQzsskY7NKZ3ukCD+J60J66t/AD0d1GwV5rasw==} dependencies: - '@nrwl/workspace': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86) - '@nx/devkit': 18.1.0-beta.1(nx@18.1.0-beta.1) + '@nrwl/workspace': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86) + '@nx/devkit': 18.1.0-beta.3(nx@18.1.0-beta.3) chalk: 4.1.2 enquirer: 2.3.6 - nx: 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86) + nx: 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86) tslib: 2.6.2 yargs-parser: 21.1.1 transitivePeerDependencies: @@ -12789,10 +12790,6 @@ packages: form-data: 3.0.1 dev: true - /@types/node@16.18.48: - resolution: {integrity: sha512-mlaecDKQ7rIZrYD7iiKNdzFb6e/qD5I9U1rAhq+Fd+DWvYVs+G2kv74UFHmSOlg5+i/vF3XxuR522V4u8BqO+Q==} - dev: true - /@types/node@18.19.8: resolution: {integrity: sha512-g1pZtPhsvGVTwmeVoexWZLTQaOvXwoSq//pTL0DHeNzUDrFnir4fgETdhjhIxjVnN+hKOuh98+E1eMLnUXstFg==} dependencies: @@ -17103,15 +17100,14 @@ packages: resolution: {integrity: sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw==} dev: true - /cypress@13.0.0: - resolution: {integrity: sha512-nWHU5dUxP2Wm/zrMd8SWTTl706aJex/l+H4vi/tbu2SWUr17BUcd/sIYeqyxeoSPW1JFV2pT1pf4JEImH/POMg==} + /cypress@13.6.6: + resolution: {integrity: sha512-S+2S9S94611hXimH9a3EAYt81QM913ZVA03pUmGDfLTFa5gyp85NJ8dJGSlEAEmyRsYkioS1TtnWtbv/Fzt11A==} engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} hasBin: true requiresBuild: true dependencies: '@cypress/request': 3.0.1 '@cypress/xvfb': 1.2.4(supports-color@8.1.1) - '@types/node': 16.18.48 '@types/sinonjs__fake-timers': 8.1.1 '@types/sizzle': 2.3.3 arch: 2.2.0 @@ -17147,7 +17143,7 @@ packages: process: 0.11.10 proxy-from-env: 1.0.0 request-progress: 3.0.0 - semver: 7.5.3 + semver: 7.6.0 supports-color: 8.1.1 tmp: 0.2.1 untildify: 4.0.0 @@ -22932,8 +22928,6 @@ packages: peerDependenciesMeta: webpack: optional: true - webpack-sources: - optional: true dependencies: webpack: 5.88.0(@swc/core@1.3.86)(esbuild@0.19.5) webpack-sources: 3.2.3 @@ -22946,8 +22940,6 @@ packages: peerDependenciesMeta: webpack: optional: true - webpack-sources: - optional: true dependencies: webpack: 5.90.1(@swc/core@1.3.86)(esbuild@0.20.0) webpack-sources: 3.2.3 @@ -23013,7 +23005,7 @@ packages: optional: true dependencies: cli-truncate: 2.1.0 - colorette: 2.0.19 + colorette: 2.0.20 enquirer: 2.3.6 log-update: 4.0.0 p-map: 4.0.0 @@ -25343,8 +25335,8 @@ packages: - debug dev: true - /nx@18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86): - resolution: {integrity: sha512-AaPqJj7yAX07QdWmhTJtgiMpl9ieGyg5jeGdOBzHeqAXnS9YEE624dDC+3t1yoSaDw0XeoV/fKeRqUQX7l56Kg==} + /nx@18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86): + resolution: {integrity: sha512-t1njGkImbAPeSKgozM+r4dfUY+xCziXtOcEvkMAwPo6LQ8+730fWlGwxUu1NyC5Ih0Aura5CaVJG0Yxxl2jBbg==} hasBin: true requiresBuild: true peerDependencies: @@ -25356,7 +25348,7 @@ packages: '@swc/core': optional: true dependencies: - '@nrwl/tao': 18.1.0-beta.1(@swc-node/register@1.8.0)(@swc/core@1.3.86) + '@nrwl/tao': 18.1.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86) '@swc-node/register': 1.8.0(@swc/core@1.3.86)(@swc/types@0.1.5)(typescript@5.3.3) '@swc/core': 1.3.86(@swc/helpers@0.5.3) '@yarnpkg/lockfile': 1.1.0 @@ -25393,16 +25385,16 @@ packages: yargs: 17.7.2 yargs-parser: 21.1.1 optionalDependencies: - '@nx/nx-darwin-arm64': 18.1.0-beta.1 - '@nx/nx-darwin-x64': 18.1.0-beta.1 - '@nx/nx-freebsd-x64': 18.1.0-beta.1 - '@nx/nx-linux-arm-gnueabihf': 18.1.0-beta.1 - '@nx/nx-linux-arm64-gnu': 18.1.0-beta.1 - '@nx/nx-linux-arm64-musl': 18.1.0-beta.1 - '@nx/nx-linux-x64-gnu': 18.1.0-beta.1 - '@nx/nx-linux-x64-musl': 18.1.0-beta.1 - '@nx/nx-win32-arm64-msvc': 18.1.0-beta.1 - '@nx/nx-win32-x64-msvc': 18.1.0-beta.1 + '@nx/nx-darwin-arm64': 18.1.0-beta.3 + '@nx/nx-darwin-x64': 18.1.0-beta.3 + '@nx/nx-freebsd-x64': 18.1.0-beta.3 + '@nx/nx-linux-arm-gnueabihf': 18.1.0-beta.3 + '@nx/nx-linux-arm64-gnu': 18.1.0-beta.3 + '@nx/nx-linux-arm64-musl': 18.1.0-beta.3 + '@nx/nx-linux-x64-gnu': 18.1.0-beta.3 + '@nx/nx-linux-x64-musl': 18.1.0-beta.3 + '@nx/nx-win32-arm64-msvc': 18.1.0-beta.3 + '@nx/nx-win32-x64-msvc': 18.1.0-beta.3 transitivePeerDependencies: - debug dev: true