feat(js): add typecheck task to generated ci workflow file when using the ts solution setup (#30219)

## Current Behavior

When generating a CI workflow (via creating a new workspace or invoking
the `ci-workflow` generator directly) in a workspace using the TS
solution setup, the `typecheck` task is not present in the affected
command that is generated in the CI workflow file.

## Expected Behavior

When generating a CI workflow in a workspace using the TS solution
setup, the `typecheck` task should be present in the affected command
that is generated in the CI workflow file.

## Related Issue(s)

Fixes #
This commit is contained in:
Leosvel Pérez Espinosa 2025-03-01 00:19:51 +01:00 committed by GitHub
parent 2b98830b3a
commit 1407152b70
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 290 additions and 7 deletions

View File

@ -78,8 +78,10 @@ describe('CI Workflow generator', () => {
const nxJson = readNxJson(tree); const nxJson = readNxJson(tree);
delete nxJson.nxCloudAccessToken; delete nxJson.nxCloudAccessToken;
updateNxJson(tree, nxJson); updateNxJson(tree, nxJson);
} else { } else if (nxCloudAccessToken) {
process.env.NX_CLOUD_ACCESS_TOKEN = nxCloudAccessToken; process.env.NX_CLOUD_ACCESS_TOKEN = nxCloudAccessToken;
} else {
delete process.env.NX_CLOUD_ACCESS_TOKEN;
} }
}); });
@ -275,4 +277,281 @@ describe('CI Workflow generator', () => {
'sharedGlobals', 'sharedGlobals',
]); ]);
}); });
describe('TS solution setup', () => {
let nxCloudAccessToken: string;
beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
updateJson(tree, 'package.json', (json) => {
json.workspaces = ['packages/*'];
return json;
});
writeJson(tree, 'tsconfig.base.json', {
compilerOptions: {
composite: true,
declaration: true,
},
});
writeJson(tree, 'tsconfig.json', {
extends: './tsconfig.base.json',
files: [],
references: [],
});
nxCloudAccessToken = process.env.NX_CLOUD_ACCESS_TOKEN;
delete process.env.NX_CLOUD_ACCESS_TOKEN;
});
afterEach(() => {
if (nxCloudAccessToken) {
process.env.NX_CLOUD_ACCESS_TOKEN = nxCloudAccessToken;
} else {
delete process.env.NX_CLOUD_ACCESS_TOKEN;
}
});
it('should generate github config with typecheck task', async () => {
await ciWorkflowGenerator(tree, { ci: 'github', name: 'CI' });
expect(tree.read('.github/workflows/ci.yml', 'utf-8'))
.toMatchInlineSnapshot(`
"name: CI
on:
push:
branches:
- main
pull_request:
permissions:
actions: read
contents: read
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# This enables task distribution via Nx Cloud
# Run this command as early as possible, before dependencies are installed
# Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun
# Connect your workspace by running "nx connect" and uncomment this line to enable task distribution
# - run: npx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="build"
# Cache node_modules
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci --legacy-peer-deps
- uses: nrwl/nx-set-shas@v4
# Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud
# - run: npx nx-cloud record -- echo Hello World
# Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected
- run: npx nx affected -t lint test build typecheck
"
`);
});
it('should generate circleci config with typecheck task', async () => {
await ciWorkflowGenerator(tree, { ci: 'circleci', name: 'CI' });
expect(tree.read('.circleci/config.yml', 'utf-8')).toMatchInlineSnapshot(`
"version: 2.1
orbs:
nx: nrwl/nx@1.6.2
jobs:
main:
docker:
- image: cimg/node:lts-browsers
steps:
- checkout
# This enables task distribution via Nx Cloud
# Run this command as early as possible, before dependencies are installed
# Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun
# Connect your workspace by running "nx connect" and uncomment this line to enable task distribution
# - run: npx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="build"
- run: npm ci --legacy-peer-deps
- nx/set-shas:
main-branch-name: 'main'
# Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud
# - run: npx nx-cloud record -- echo Hello World
# Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected
- run: npx nx affected -t lint test build typecheck
workflows:
version: 2
ci:
jobs:
- main
"
`);
});
it('should generate azure config with typecheck task', async () => {
await ciWorkflowGenerator(tree, { ci: 'azure', name: 'CI' });
expect(tree.read('azure-pipelines.yml', 'utf-8')).toMatchInlineSnapshot(`
"name: CI
trigger:
- main
pr:
- main
variables:
CI: 'true'
\${{ 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: main
pool:
vmImage: 'ubuntu-latest'
steps:
- checkout: self
fetchDepth: 0
# Set Azure Devops CLI default settings
- bash: az devops configure --defaults organization=$(System.TeamFoundationCollectionUri) project=$(System.TeamProject)
displayName: 'Set default Azure DevOps organization and project'
# Get last successfull commit from Azure Devops CLI
- 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
displayName: 'Get last successful commit SHA'
condition: ne(variables['Build.Reason'], 'PullRequest')
env:
AZURE_DEVOPS_EXT_PAT: $(System.AccessToken)
# This enables task distribution via Nx Cloud
# Run this command as early as possible, before dependencies are installed
# Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun
# Connect your workspace by running "nx connect" and uncomment this line to enable task distribution
# - script: npx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="build"
- script: npm ci --legacy-peer-deps
- script: git branch --track main origin/main
condition: eq(variables['Build.Reason'], 'PullRequest')
# Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud
# - script: npx nx-cloud record -- echo Hello World
# Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected
- script: npx nx affected --base=$(BASE_SHA) --head=$(HEAD_SHA) lint test build typecheck
"
`);
});
it('should generate bitbucket config with typecheck task', async () => {
await ciWorkflowGenerator(tree, {
ci: 'bitbucket-pipelines',
name: 'CI',
});
expect(tree.read('bitbucket-pipelines.yml', 'utf-8'))
.toMatchInlineSnapshot(`
"image: node:20
clone:
depth: full
pipelines:
pull-requests:
'**':
- step:
name: 'Build and test affected apps on Pull Requests'
script:
- export NX_BRANCH=$BITBUCKET_PR_ID
# This enables task distribution via Nx Cloud
# Run this command as early as possible, before dependencies are installed
# Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun
# Connect your workspace by running "nx connect" and uncomment this line to enable task distribution
# - npx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="build"
- npm ci --legacy-peer-deps
# Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud
# npx nx-cloud record -- echo Hello World
# Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected
- npx nx affected --base=origin/main -t lint test build typecheck
branches:
main:
- step:
name: 'Build and test affected apps on "main" branch changes'
script:
- export NX_BRANCH=$BITBUCKET_BRANCH
# This enables task distribution via Nx Cloud
# Run this command as early as possible, before dependencies are installed
# Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun
# Connect your workspace by running "nx connect" and uncomment this
# - npx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="build"
- npm ci --legacy-peer-deps
# Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud
# - npx nx-cloud record -- echo Hello World
# Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected
- npx nx affected -t lint test build typecheck --base=HEAD~1
"
`);
});
it('should generate gitlab config with typecheck task', async () => {
await ciWorkflowGenerator(tree, { ci: 'gitlab', name: 'CI' });
expect(tree.read('.gitlab-ci.yml', 'utf-8')).toMatchInlineSnapshot(`
"image: node:20
variables:
CI: 'true'
# Main job
CI:
interruptible: true
only:
- main
- merge_requests
script:
# This enables task distribution via Nx Cloud
# Run this command as early as possible, before dependencies are installed
# Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun
# Connect your workspace by running "nx connect" and uncomment this line to enable task distribution
# - npx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="build"
- npm ci --legacy-peer-deps
- NX_HEAD=$CI_COMMIT_SHA
- NX_BASE=\${CI_MERGE_REQUEST_DIFF_BASE_SHA:-$CI_COMMIT_BEFORE_SHA}
# Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud
# - npx nx-cloud record -- echo Hello World
# Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected
- npx nx affected -t lint test build typecheck
"
`);
});
});
}); });

View File

@ -12,6 +12,7 @@ import {
import { deduceDefaultBase } from '../../utilities/default-base'; import { deduceDefaultBase } from '../../utilities/default-base';
import { join } from 'path'; import { join } from 'path';
import { getNxCloudUrl, isNxCloudUsed } from 'nx/src/utils/nx-cloud-utils'; import { getNxCloudUrl, isNxCloudUsed } from 'nx/src/utils/nx-cloud-utils';
import { isUsingTsSolutionSetup } from '../../utilities/typescript/ts-solution-setup';
export interface Schema { export interface Schema {
name: string; name: string;
@ -47,6 +48,7 @@ interface Substitutes {
nxCloudHost: string; nxCloudHost: string;
hasCypress: boolean; hasCypress: boolean;
hasE2E: boolean; hasE2E: boolean;
hasTypecheck: boolean;
hasPlaywright: boolean; hasPlaywright: boolean;
tmpl: ''; tmpl: '';
connectedToCloud: boolean; connectedToCloud: boolean;
@ -78,6 +80,7 @@ function normalizeOptions(options: Schema, tree: Tree): Substitutes {
const hasCypress = allDependencies['@nx/cypress']; const hasCypress = allDependencies['@nx/cypress'];
const hasPlaywright = allDependencies['@nx/playwright']; const hasPlaywright = allDependencies['@nx/playwright'];
const hasE2E = hasCypress || hasPlaywright; const hasE2E = hasCypress || hasPlaywright;
const hasTypecheck = isUsingTsSolutionSetup(tree);
const connectedToCloud = isNxCloudUsed(readJson(tree, 'nx.json')); const connectedToCloud = isNxCloudUsed(readJson(tree, 'nx.json'));
@ -92,6 +95,7 @@ function normalizeOptions(options: Schema, tree: Tree): Substitutes {
hasCypress, hasCypress,
hasE2E, hasE2E,
hasPlaywright, hasPlaywright,
hasTypecheck,
nxCloudHost, nxCloudHost,
tmpl: '', tmpl: '',
connectedToCloud, connectedToCloud,

View File

@ -68,4 +68,4 @@ jobs:
# - script: <%= packageManagerPrefix %> nx-cloud record -- echo Hello World # - script: <%= packageManagerPrefix %> nx-cloud record -- echo Hello World
# Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected<% if(hasE2E){ %> # Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected<% if(hasE2E){ %>
# When you enable task distribution, run the e2e-ci task instead of e2e<% } %> # When you enable task distribution, run the e2e-ci task instead of e2e<% } %>
- script: <%= packageManagerPrefix %> nx affected --base=$(BASE_SHA) --head=$(HEAD_SHA) lint test build<% if(hasE2E){ %> e2e<% } %> - script: <%= packageManagerPrefix %> nx affected --base=$(BASE_SHA) --head=$(HEAD_SHA) lint test build<% if(hasTypecheck){ %> typecheck<% } %><% if(hasE2E){ %> e2e<% } %>

View File

@ -33,7 +33,7 @@ pipelines:
# <%= packageManagerPrefix %> nx-cloud record -- echo Hello World # <%= packageManagerPrefix %> nx-cloud record -- echo Hello World
# Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected<% if(hasE2E){ %> # Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected<% if(hasE2E){ %>
# When you enable task distribution, run the e2e-ci task instead of e2e<% } %> # When you enable task distribution, run the e2e-ci task instead of e2e<% } %>
- <%= packageManagerPrefix %> nx affected --base=origin/<%= mainBranch %> -t lint test build<% if(hasE2E){ %> e2e<% } %> - <%= packageManagerPrefix %> nx affected --base=origin/<%= mainBranch %> -t lint test build<% if(hasTypecheck){ %> typecheck<% } %><% if(hasE2E){ %> e2e<% } %>
branches: branches:
main: main:
@ -59,4 +59,4 @@ pipelines:
# Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud # Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud
# - <%= packageManagerPrefix %> nx-cloud record -- echo Hello World # - <%= packageManagerPrefix %> nx-cloud record -- echo Hello World
# Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected # Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected
- <%= packageManagerPrefix %> nx affected -t lint test build<% if(hasE2E){ %> e2e-ci<% } %> --base=HEAD~1 - <%= packageManagerPrefix %> nx affected -t lint test build<% if(hasTypecheck){ %> typecheck<% } %><% if(hasE2E){ %> e2e-ci<% } %> --base=HEAD~1

View File

@ -37,7 +37,7 @@ jobs:
# - run: <%= packageManagerPrefix %> nx-cloud record -- echo Hello World # - run: <%= packageManagerPrefix %> nx-cloud record -- echo Hello World
# Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected<% if(hasE2E){ %> # Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected<% if(hasE2E){ %>
# When you enable task distribution, run the e2e-ci task instead of e2e<% } %> # When you enable task distribution, run the e2e-ci task instead of e2e<% } %>
- run: <%= packageManagerPrefix %> nx affected -t lint test build<% if(hasE2E){ %> e2e<% } %> - run: <%= packageManagerPrefix %> nx affected -t lint test build<% if(hasTypecheck){ %> typecheck<% } %><% if(hasE2E){ %> e2e<% } %>
workflows: workflows:
version: 2 version: 2

View File

@ -50,4 +50,4 @@ jobs:
# - run: <%= packageManagerPrefix %> nx-cloud record -- echo Hello World # - run: <%= packageManagerPrefix %> nx-cloud record -- echo Hello World
# Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected<% if(hasE2E){ %> # Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected<% if(hasE2E){ %>
# When you enable task distribution, run the e2e-ci task instead of e2e<% } %> # When you enable task distribution, run the e2e-ci task instead of e2e<% } %>
- run: <%= packageManagerPrefix %> nx affected -t lint test build<% if(hasE2E){ %> e2e<% } %> - run: <%= packageManagerPrefix %> nx affected -t lint test build<% if(hasTypecheck){ %> typecheck<% } %><% if(hasE2E){ %> e2e<% } %>

View File

@ -31,4 +31,4 @@ variables:
# - <%= packageManagerPrefix %> nx-cloud record -- echo Hello World # - <%= packageManagerPrefix %> nx-cloud record -- echo Hello World
# Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected<% if(hasE2E){ %> # Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected<% if(hasE2E){ %>
# When you enable task distribution, run the e2e-ci task instead of e2e<% } %> # When you enable task distribution, run the e2e-ci task instead of e2e<% } %>
- <%= packageManagerPrefix %> nx affected -t lint test build<% if(hasE2E){ %> e2e<% } %> - <%= packageManagerPrefix %> nx affected -t lint test build<% if(hasTypecheck){ %> typecheck<% } %><% if(hasE2E){ %> e2e<% } %>