Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: measure graph timings #29991

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 11 additions & 105 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ jobs:
runs-on: ubuntu-latest
env:
NX_E2E_CI_CACHE_KEY: e2e-github-linux
NX_DAEMON: 'true'
NX_PERF_LOGGING: 'false'
NX_DAEMON: 'false'
NX_PERF_LOGGING: 'true'
NX_VERBOSE_LOGGING: 'false'
NX_NATIVE_LOGGING: 'false'
NX_E2E_RUN_E2E: 'true'
Expand All @@ -35,103 +35,9 @@ jobs:
- name: Fetch Master
run: git fetch origin master:master
if: ${{ github.event_name == 'pull_request' }}


- name: Set SHAs
uses: nrwl/nx-set-shas@v4

- name: Start CI Run
run: npx nx-cloud@next start-ci-run --distribute-on="./.nx/workflows/dynamic-changesets.yaml" --stop-agents-after="e2e"

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y ca-certificates lsof libvips-dev libglib2.0-dev libgirepository1.0-dev

- name: Install Chrome
uses: browser-actions/setup-chrome@v1

- uses: pnpm/action-setup@v4
name: Install pnpm
with:
version: 9.8.0
run_install: false

- name: Install project dependencies
run: |
pnpm install --frozen-lockfile
pnpm playwright install --with-deps

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Check Documentation
run: pnpm nx documentation
timeout-minutes: 20

- name: Run Checks/Lint/Test/Build
run: |
pids=()

pnpm nx-cloud record -- nx format:check --base=$NX_BASE --head=$NX_HEAD &
pids+=($!)

pnpm nx-cloud record -- nx sync:check
pids+=($!)

pnpm nx-cloud record -- nx-cloud conformance:check
pids+=($!)

pnpm nx run-many -t check-imports check-commit check-lock-files check-codeowners --parallel=1 --no-dte &
pids+=($!)

pnpm nx affected --targets=lint,test,build,e2e,e2e-ci --base=$NX_BASE --head=$NX_HEAD --parallel=3 &
pids+=($!)

for pid in "${pids[@]}"; do
wait "$pid"
done
timeout-minutes: 100

main-macos:
runs-on: macos-latest
env:
NX_E2E_CI_CACHE_KEY: e2e-github-macos
NX_PERF_LOGGING: 'false'
NX_CI_EXECUTION_ENV: 'macos'
SELECTED_PM: 'npm'
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Fetch Master
run: git fetch origin master:master
if: ${{ github.event_name == 'pull_request' }}

- name: Restore Homebrew packages
uses: actions/cache@v3
with:
path: |
/usr/local/Homebrew
~/Library/Caches/Homebrew
key: nrwl-nx-homebrew-packages

- name: Configure Detox Environment, Install applesimutils
run: |
HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew >/dev/null
HOMEBREW_NO_AUTO_UPDATE=1 brew install applesimutils >/dev/null
xcrun simctl shutdown all && xcrun simctl erase all
timeout-minutes: 20

- name: Save Homebrew Cache
uses: actions/cache@v3
with:
path: |
/usr/local/Homebrew
~/Library/Caches/Homebrew
key: nrwl-nx-homebrew-packages

- uses: pnpm/action-setup@v4
name: Install pnpm
Expand All @@ -147,14 +53,14 @@ jobs:
- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Set SHAs
uses: nrwl/nx-set-shas@v4
- name: Calculate Graph (cold)
run: npx nx show projects

- name: Run E2E Tests for macOS
- name: Extract Nx Perf Timings (warm)
run: |
HAS_CHANGED=$(node ./scripts/check-react-native-changes.js $NX_BASE $NX_HEAD);
if $HAS_CHANGED; then
pnpm nx affected -t e2e-macos-local --parallel=1 --base=$NX_BASE --head=$NX_HEAD
else
echo "Skip E2E tests for macOS as there are no changes in React Native projects."
fi
node ./extract-timings.js perf-timings.csv
echo "################################"
echo "####### PERF TIMINGS ###########"
echo "################################"
echo " "
cat perf-timings.csv
12 changes: 6 additions & 6 deletions docs/generated/devkit/createNodesFromFiles.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@

#### Parameters

| Name | Type |
| :------------ | :------------------------------------------------------------------------- |
| `createNodes` | [`CreateNodesFunction`](../../devkit/documents/CreateNodesFunction)\<`T`\> |
| `configFiles` | readonly `string`[] |
| `options` | `T` |
| `context` | [`CreateNodesContextV2`](../../devkit/documents/CreateNodesContextV2) |
| Name | Type |
| :------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `createNodes` | (`projectConfigurationFile`: `string`, `options`: `T`, `context`: [`CreateNodesContext`](../../devkit/documents/CreateNodesContext), `idx`: `number`) => [`CreateNodesResult`](../../devkit/documents/CreateNodesResult) \| `Promise`\<[`CreateNodesResult`](../../devkit/documents/CreateNodesResult)\> |
| `configFiles` | readonly `string`[] |
| `options` | `T` |
| `context` | [`CreateNodesContextV2`](../../devkit/documents/CreateNodesContextV2) |

#### Returns

Expand Down
8 changes: 7 additions & 1 deletion docs/generated/devkit/isDaemonEnabled.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# Function: isDaemonEnabled

▸ **isDaemonEnabled**(): `boolean`
▸ **isDaemonEnabled**(`nxJson?`): `boolean`

#### Parameters

| Name | Type |
| :------- | :----------------------------------------------------------------------------------------- |
| `nxJson` | [`NxJsonConfiguration`](../../devkit/documents/NxJsonConfiguration)\<`string`[] \| `"*"`\> |

#### Returns

Expand Down
56 changes: 56 additions & 0 deletions extract-timings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//@ts-check
/**
* @type {Array<[string, number]>}
*/
const timings = [];
const { dirname } = require('path');
const labelReplacers = [
(l) => l.replace(dirname(dirname(require.resolve('nx'))), 'nx'),
];

const [filename] = process.argv.slice(2);

const child = require('child_process').fork(
require.resolve('nx'),
['show', 'projects'],
{
stdio: ['pipe', 'pipe', 'pipe', 'ipc'],
env: {
...process.env,
NX_DAEMON: 'false',
NX_PERF_LOGGING: 'true',
},
},
);

child.stdout?.on('data', (data) => {
const lines = data.toString().split('\n');
for (const line of lines) {
const regex = /Time for '(?<label>.*)' (?<duration>[\d,.]+)/;
const match = line.match(regex);
if (match) {
const { label, duration } = match.groups;
const normalizedLabel = labelReplacers.reduce(
(l, replacer) => replacer(l),
label,
);
console.log('label:', normalizedLabel, 'duration:', duration);
timings.push([normalizedLabel, parseFloat(duration)]);
}
}
});

process.on('beforeExit', () => {
const maxDuration = Math.max(...timings.map(([, duration]) => duration));
require('fs').writeFileSync(
filename ?? 'timings.csv',
'name,duration,ratio\n' +
timings
.sort((a, b) => b[1] - a[1])
.map(
([name, duration]) =>
`${name},${duration},${((duration / maxDuration) * 100).toFixed(2)}%`,
)
.join('\n'),
);
});
36 changes: 18 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,26 +70,26 @@
"@notionhq/client": "^2.2.15",
"@nuxt/kit": "^3.10.0",
"@nuxt/schema": "^3.10.0",
"@nx/angular": "20.5.0-beta.2",
"@nx/cypress": "20.5.0-beta.2",
"@nx/devkit": "20.5.0-beta.2",
"@nx/esbuild": "20.5.0-beta.2",
"@nx/eslint": "20.5.0-beta.2",
"@nx/eslint-plugin": "20.5.0-beta.2",
"@nx/jest": "20.5.0-beta.2",
"@nx/js": "20.5.0-beta.2",
"@nx/next": "20.5.0-beta.2",
"@nx/playwright": "20.5.0-beta.2",
"@nx/angular": "0.0.0-pr-29935-b2840f8",
"@nx/cypress": "0.0.0-pr-29935-b2840f8",
"@nx/devkit": "0.0.0-pr-29935-b2840f8",
"@nx/esbuild": "0.0.0-pr-29935-b2840f8",
"@nx/eslint": "0.0.0-pr-29935-b2840f8",
"@nx/eslint-plugin": "0.0.0-pr-29935-b2840f8",
"@nx/jest": "0.0.0-pr-29935-b2840f8",
"@nx/js": "0.0.0-pr-29935-b2840f8",
"@nx/next": "0.0.0-pr-29935-b2840f8",
"@nx/playwright": "0.0.0-pr-29935-b2840f8",
"@nx/powerpack-conformance": "1.2.3",
"@nx/powerpack-enterprise-cloud": "1.2.3",
"@nx/powerpack-license": "1.2.3",
"@nx/react": "20.5.0-beta.2",
"@nx/rsbuild": "20.5.0-beta.2",
"@nx/rspack": "20.5.0-beta.2",
"@nx/storybook": "20.5.0-beta.2",
"@nx/vite": "20.5.0-beta.2",
"@nx/web": "20.5.0-beta.2",
"@nx/webpack": "20.5.0-beta.2",
"@nx/react": "0.0.0-pr-29935-b2840f8",
"@nx/rsbuild": "0.0.0-pr-29935-b2840f8",
"@nx/rspack": "0.0.0-pr-29935-b2840f8",
"@nx/storybook": "0.0.0-pr-29935-b2840f8",
"@nx/vite": "0.0.0-pr-29935-b2840f8",
"@nx/web": "0.0.0-pr-29935-b2840f8",
"@nx/webpack": "0.0.0-pr-29935-b2840f8",
"@phenomnomnominal/tsquery": "~5.0.1",
"@playwright/test": "^1.36.1",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
Expand Down Expand Up @@ -252,7 +252,7 @@
"ng-packagr": "~19.1.0",
"npm-package-arg": "11.0.1",
"nuxt": "^3.10.0",
"nx": "20.5.0-beta.2",
"nx": "0.0.0-pr-29935-b2840f8",
"octokit": "^2.0.14",
"open": "^8.4.0",
"openai": "~4.3.1",
Expand Down
31 changes: 30 additions & 1 deletion packages/devkit/src/utils/calculate-hash-for-create-nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import {
hashArray,
} from 'nx/src/devkit-exports';

import { hashObject, hashWithWorkspaceContext } from 'nx/src/devkit-internals';
import {
hashMultiGlobWithWorkspaceContext,
hashObject,
hashWithWorkspaceContext,
} from 'nx/src/devkit-internals';

export async function calculateHashForCreateNodes(
projectRoot: string,
Expand All @@ -21,3 +25,28 @@ export async function calculateHashForCreateNodes(
hashObject(options),
]);
}

export async function calculateHashesForCreateNodes(
projectRoots: string[],
options: object,
context: CreateNodesContext | CreateNodesContextV2,
additionalGlobs: string[][] = []
): Promise<string[]> {
if (
additionalGlobs.length &&
additionalGlobs.length !== projectRoots.length
) {
throw new Error(
'If additionalGlobs is provided, it must be the same length as projectRoots'
);
}
return hashMultiGlobWithWorkspaceContext(
context.workspaceRoot,
projectRoots.map((projectRoot, idx) => [
join(projectRoot, '**/*'),
...(additionalGlobs.length ? additionalGlobs[idx] : []),
])
).then((hashes) => {
return hashes.map((hash) => hashArray([hash, hashObject(options)]));
});
}
Loading