Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c6bf6414ce | |||
| 395c3562d0 | |||
| 5a2ea09d9b | |||
| 9c5873c9fa | |||
| 47d4eb8eb8 | |||
| ad9344152f | |||
| 491966b6e3 | |||
| cda123802f | |||
| 9690aea0a8 | |||
| 6a1164f7ae | |||
| 0ce7acdf77 | |||
| 137ba06499 | |||
| 5df932b108 | |||
| 62e75edd24 | |||
| 2145117b24 | |||
| a42cabccf9 |
@@ -1,5 +1,5 @@
|
||||
[build]
|
||||
target-dir = 'dist/target'
|
||||
target-dir = 'build/target'
|
||||
|
||||
[target.x86_64-unknown-linux-musl]
|
||||
rustflags = [
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
version: 2.1
|
||||
|
||||
# -------------------------
|
||||
# ORBS
|
||||
# -------------------------
|
||||
orbs:
|
||||
nx: nrwl/nx@1.6.1
|
||||
rust: circleci/rust@1.6.0
|
||||
browser-tools: circleci/browser-tools@1.4.0
|
||||
|
||||
# -------------------------
|
||||
# EXECUTORS
|
||||
# -------------------------
|
||||
@@ -11,20 +19,214 @@ executors:
|
||||
linux:
|
||||
<<: *defaults
|
||||
docker:
|
||||
- image: cimg/rust:1.84.0-browsers
|
||||
resource_class: small
|
||||
- image: cimg/rust:1.70.0-browsers
|
||||
resource_class: medium+
|
||||
|
||||
macos:
|
||||
<<: *defaults
|
||||
resource_class: macos.x86.medium.gen2
|
||||
macos:
|
||||
xcode: '14.2.0'
|
||||
|
||||
# -------------------------
|
||||
# COMMANDS
|
||||
# -------------------------
|
||||
commands:
|
||||
run-pnpm-install:
|
||||
parameters:
|
||||
os:
|
||||
type: string
|
||||
steps:
|
||||
- restore_cache:
|
||||
name: Restore pnpm Package Cache
|
||||
keys:
|
||||
- node-deps-{{ arch }}-v3-{{ checksum "pnpm-lock.yaml" }}
|
||||
- when:
|
||||
condition:
|
||||
equal: [<< parameters.os >>, linux]
|
||||
steps:
|
||||
- run:
|
||||
name: Install pnpm package manager (linux)
|
||||
command: |
|
||||
npm install --prefix=$HOME/.local -g @pnpm/exe@8.3.1
|
||||
- when:
|
||||
condition:
|
||||
equal: [<< parameters.os >>, macos]
|
||||
steps:
|
||||
- run:
|
||||
name: Install pnpm package manager (macos)
|
||||
command: |
|
||||
npm install -g @pnpm/exe@8.3.1
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
pnpm install --frozen-lockfile
|
||||
- save_cache:
|
||||
name: Save pnpm Package Cache
|
||||
key: node-deps-{{ arch }}-v3-{{ checksum "pnpm-lock.yaml" }}
|
||||
paths:
|
||||
- ~/.pnpm-store
|
||||
- ~/.cache/Cypress
|
||||
- node_modules
|
||||
|
||||
setup:
|
||||
parameters:
|
||||
os:
|
||||
type: string
|
||||
steps:
|
||||
- checkout
|
||||
- when:
|
||||
condition:
|
||||
equal: [<< parameters.os >>, macos]
|
||||
steps:
|
||||
- restore_cache:
|
||||
name: Restore Homebrew packages
|
||||
keys:
|
||||
- nrwl-nx-homebrew-packages
|
||||
- run:
|
||||
name: Configure Detox Environment, Install applesimutils
|
||||
command: |
|
||||
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
|
||||
no_output_timeout: 20m
|
||||
- save_cache:
|
||||
name: Save Homebrew Cache
|
||||
key: nrwl-nx-homebrew-packages
|
||||
paths:
|
||||
- /usr/local/Homebrew
|
||||
- ~/Library/Caches/Homebrew
|
||||
- when:
|
||||
condition:
|
||||
equal: [<< parameters.os >>, linux]
|
||||
steps:
|
||||
- run:
|
||||
command: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ca-certificates lsof
|
||||
- browser-tools/install-chrome
|
||||
- browser-tools/install-chromedriver
|
||||
- run-pnpm-install:
|
||||
os: << parameters.os >>
|
||||
|
||||
# -------------------------
|
||||
# JOBS
|
||||
# -------------------------
|
||||
jobs:
|
||||
# -------------------------
|
||||
# JOBS: Agent
|
||||
# -------------------------
|
||||
agent:
|
||||
parameters:
|
||||
os:
|
||||
type: string
|
||||
default: 'linux'
|
||||
pm:
|
||||
type: string
|
||||
default: 'pnpm'
|
||||
executor: << parameters.os >>
|
||||
environment:
|
||||
GIT_AUTHOR_EMAIL: test@test.com
|
||||
GIT_AUTHOR_NAME: Test
|
||||
GIT_COMMITTER_EMAIL: test@test.com
|
||||
GIT_COMMITTER_NAME: Test
|
||||
NX_E2E_CI_CACHE_KEY: e2e-circleci-<< parameters.os >>
|
||||
SELECTED_PM: << parameters.pm >>
|
||||
NX_E2E_RUN_E2E: 'true'
|
||||
NX_VERBOSE_LOGGING: 'false'
|
||||
NX_NATIVE_LOGGING: 'false'
|
||||
NX_PERF_LOGGING: 'false'
|
||||
steps:
|
||||
- run:
|
||||
name: Configure git metadata (needed for lerna smoke tests)
|
||||
command: |
|
||||
git config --global user.email test@test.com
|
||||
git config --global user.name "Test Test"
|
||||
- run:
|
||||
name: Set dynamic nx run variable
|
||||
command: |
|
||||
echo "export NX_CI_EXECUTION_ENV=\"<< parameters.os >>\";" >> $BASH_ENV
|
||||
- setup:
|
||||
os: << parameters.os >>
|
||||
- run:
|
||||
name: Agent
|
||||
command: pnpm nx-cloud start-agent
|
||||
no_output_timeout: 60m
|
||||
|
||||
# -------------------------
|
||||
# JOBS: Main Linux
|
||||
# -------------------------
|
||||
main-linux:
|
||||
executor: linux
|
||||
environment:
|
||||
NX_E2E_CI_CACHE_KEY: e2e-circleci-linux
|
||||
NX_VERBOSE_LOGGING: 'false'
|
||||
NX_DAEMON: 'true'
|
||||
NX_PERF_LOGGING: 'false'
|
||||
NX_NATIVE_LOGGING: 'false'
|
||||
steps:
|
||||
- run: echo "We are in the process of transitioning from Circle CI to GitHub Actions. For details about your build results, consult github actions build logs."
|
||||
- run:
|
||||
name: Set dynamic nx run variable
|
||||
command: |
|
||||
echo "export NX_CI_EXECUTION_ENV=\"linux\";" >> $BASH_ENV
|
||||
- setup:
|
||||
os: linux
|
||||
- nx/set-shas:
|
||||
main-branch-name: 'master'
|
||||
- run: pnpm nx-cloud start-ci-run --stop-agents-after="e2e"
|
||||
- run:
|
||||
name: Check Documentation
|
||||
command: pnpm nx documentation --no-dte
|
||||
no_output_timeout: 20m
|
||||
- run:
|
||||
name: Run Checks/Lint/Test/Build
|
||||
no_output_timeout: 60m
|
||||
command: |
|
||||
pids=()
|
||||
|
||||
pnpm nx-cloud record -- nx format:check --base=$NX_BASE --head=$NX_HEAD &
|
||||
pids+=($!)
|
||||
|
||||
pnpm nx run-many -t check-imports check-commit check-lock-files check-codeowners documentation --parallel=1 --no-dte &
|
||||
pids+=($!)
|
||||
|
||||
pnpm nx affected --target=lint --base=$NX_BASE --head=$NX_HEAD --parallel=3 &
|
||||
pids+=($!)
|
||||
pnpm nx affected --target=test --base=$NX_BASE --head=$NX_HEAD --parallel=1 &
|
||||
pids+=($!)
|
||||
(pnpm nx affected --target=build --base=$NX_BASE --head=$NX_HEAD --parallel=3 &&
|
||||
pnpm nx affected --target=e2e --base=$NX_BASE --head=$NX_HEAD --parallel=1) &
|
||||
pids+=($!)
|
||||
|
||||
for pid in "${pids[@]}"; do
|
||||
wait "$pid"
|
||||
done
|
||||
# -------------------------
|
||||
# JOBS: Main-MacOS
|
||||
# -------------------------
|
||||
mainmacos:
|
||||
executor: macos
|
||||
environment:
|
||||
NX_E2E_CI_CACHE_KEY: e2e-circleci-macos
|
||||
NX_DAEMON: 'false' # TODO: set to true after #18410
|
||||
NX_PERF_LOGGING: 'false'
|
||||
SELECTED_PM: 'npm' # explicitly define npm for macOS tests
|
||||
NX_SKIP_NX_CACHE: 'true' # TODO: Remove after #18410
|
||||
steps:
|
||||
- run:
|
||||
name: Set dynamic nx run variable
|
||||
command: |
|
||||
echo "export NX_CI_EXECUTION_ENV=\"macos\";" >> $BASH_ENV
|
||||
- setup:
|
||||
os: macos
|
||||
- rust/install
|
||||
- nx/set-shas:
|
||||
main-branch-name: 'master'
|
||||
- run:
|
||||
name: Run E2E Tests for macOS
|
||||
command: |
|
||||
pnpm nx affected -t e2e-macos --parallel=1 --base=$NX_BASE --head=$NX_HEAD
|
||||
no_output_timeout: 45m
|
||||
|
||||
# -------------------------
|
||||
# WORKFLOWS(JOBS)
|
||||
@@ -34,4 +236,22 @@ workflows:
|
||||
|
||||
build:
|
||||
jobs:
|
||||
- agent:
|
||||
name: 'agent1'
|
||||
- agent:
|
||||
name: 'agent2'
|
||||
- agent:
|
||||
name: 'agent3'
|
||||
- agent:
|
||||
name: 'agent4'
|
||||
- agent:
|
||||
name: 'agent5'
|
||||
- agent:
|
||||
name: 'agent6'
|
||||
- agent:
|
||||
name: 'agent7'
|
||||
- agent:
|
||||
name: 'agent8'
|
||||
- main-linux
|
||||
- mainmacos:
|
||||
name: main-macos-e2e
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
# Commit Command
|
||||
|
||||
## Description
|
||||
|
||||
Create a git commit following Nx repository standards and validation requirements.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
/commit [message]
|
||||
```
|
||||
|
||||
## What this command does:
|
||||
|
||||
1. **Pre-commit validation**: Runs the full validation suite (`pnpm nx prepush`) to ensure code quality
|
||||
2. **Formatting**: Automatically formats changed files with Prettier
|
||||
3. **Testing**: Runs tests on affected projects to validate changes
|
||||
4. **Commit creation**: Creates a well-formed commit with proper message formatting (without co-author attribution)
|
||||
5. **Status reporting**: Provides clear feedback on the commit process
|
||||
|
||||
## Workflow:
|
||||
|
||||
1. Format any modified files with Prettier
|
||||
2. Run the prepush validation suite
|
||||
3. If validation passes, stage relevant changes
|
||||
4. Create commit with descriptive message
|
||||
5. Provide summary of what was committed
|
||||
|
||||
## Commit Message Format:
|
||||
|
||||
- Use conventional commit format when appropriate
|
||||
- Include scope (e.g., `feat(core):`, `fix(angular):`, `docs(nx):`)
|
||||
- Keep first line under 72 characters
|
||||
- Include detailed description if needed
|
||||
|
||||
## Examples:
|
||||
|
||||
- `/commit "feat(core): add new project graph visualization"`
|
||||
- `/commit "fix(react): resolve build issues with webpack config"`
|
||||
- `/commit "docs(nx): update getting started guide"`
|
||||
|
||||
## Validation Requirements:
|
||||
|
||||
- All tests must pass
|
||||
- Code must be properly formatted
|
||||
- No linting errors
|
||||
- E2E tests for affected areas should pass
|
||||
@@ -1,155 +0,0 @@
|
||||
# GitHub Issue Planning and Resolution
|
||||
|
||||
This command provides guidance for both automated and manual GitHub issue workflows.
|
||||
|
||||
## Automated Workflow (GitHub Actions)
|
||||
|
||||
The automated workflow consists of two phases:
|
||||
|
||||
### Phase 1: Planning (`@claude plan` or `claude:plan` label)
|
||||
|
||||
- Claude analyzes the issue and creates a detailed implementation plan
|
||||
- Plan is posted as a comment on the issue
|
||||
- Issue is labeled with `claude:planned`
|
||||
|
||||
### Phase 2: Implementation (`@claude implement` or `claude:implement` label)
|
||||
|
||||
- Claude implements the solution based on the plan
|
||||
- Runs validation tests and creates a feature branch
|
||||
- Suggests opening a PR with proper formatting
|
||||
|
||||
## Planning Phase Template
|
||||
|
||||
When creating a plan (either automated or manual), include these sections:
|
||||
|
||||
### Problem Analysis
|
||||
|
||||
- Root cause identification
|
||||
- Impact assessment
|
||||
- Related components or systems affected
|
||||
|
||||
### Proposed Solution
|
||||
|
||||
- High-level approach
|
||||
- Alternative solutions considered
|
||||
- Trade-offs and rationale
|
||||
|
||||
### Implementation Details
|
||||
|
||||
- Files that need to be modified
|
||||
- Key changes required
|
||||
- Dependencies or prerequisites
|
||||
|
||||
### Testing Strategy
|
||||
|
||||
- Unit tests to add/modify
|
||||
- Integration tests needed
|
||||
- E2E test considerations
|
||||
|
||||
### Validation Steps
|
||||
|
||||
```bash
|
||||
# Test specific affected projects
|
||||
nx run-many -t test,build,lint -p PROJECT_NAME
|
||||
|
||||
# Test all affected projects
|
||||
nx affected -t build,test,lint
|
||||
|
||||
# Run affected e2e tests
|
||||
nx affected -t e2e-local
|
||||
|
||||
# Format code
|
||||
npx nx prettier -- FILES
|
||||
|
||||
# Final validation
|
||||
pnpm nx prepush
|
||||
```
|
||||
|
||||
### Risks and Considerations
|
||||
|
||||
- Breaking changes
|
||||
- Performance implications
|
||||
- Migration requirements
|
||||
|
||||
## Manual Workflow
|
||||
|
||||
When working on a GitHub issue manually, follow this systematic approach:
|
||||
|
||||
## 1. Get Issue Details
|
||||
|
||||
```bash
|
||||
# Get issue details using GitHub CLI (replace ISSUE_NUMBER with actual number)
|
||||
gh issue view ISSUE_NUMBER
|
||||
```
|
||||
|
||||
When cloning reproduction repos, please clone within `./tmp/claude/repro-ISSUE_NUMBER`
|
||||
|
||||
## 2. Analyze the Plan
|
||||
|
||||
- Look for a plan or implementation details in the issue description
|
||||
- Check comments for additional context or clarification
|
||||
- Identify affected projects and components
|
||||
|
||||
## 3. Implement the Solution
|
||||
|
||||
- Follow the plan outlined in the issue
|
||||
- Make focused changes that address the specific problem
|
||||
- Ensure code follows existing patterns and conventions
|
||||
|
||||
## 4. Run Full Validation
|
||||
|
||||
```bash
|
||||
# Test specific affected projects first
|
||||
nx run-many -t test,build,lint -p PROJECT_NAME
|
||||
|
||||
# Test all affected projects
|
||||
nx affected -t build,test,lint
|
||||
|
||||
# Run affected e2e tests
|
||||
nx affected -t e2e-local
|
||||
|
||||
# Final pre-push validation
|
||||
pnpm nx prepush
|
||||
```
|
||||
|
||||
## 5. Submit Pull Request
|
||||
|
||||
- Create a descriptive PR title that references the issue
|
||||
- Include "Fixes #ISSUE_NUMBER" in the PR description
|
||||
- Provide a clear summary of changes made
|
||||
- Request appropriate reviewers
|
||||
|
||||
## Pull Request Template
|
||||
|
||||
When creating a pull request, follow the template found in `.github/PULL_REQUEST_TEMPLATE.md`. The template includes:
|
||||
|
||||
### Required Sections
|
||||
|
||||
1. **Current Behavior**: Describe the behavior we have today
|
||||
2. **Expected Behavior**: Describe the behavior we should expect with the changes in this PR
|
||||
3. **Related Issue(s)**: Link the issue being fixed so it gets closed when the PR is merged
|
||||
|
||||
### Template Format
|
||||
|
||||
```markdown
|
||||
## Current Behavior
|
||||
|
||||
<!-- This is the behavior we have today -->
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
<!-- This is the behavior we should expect with the changes in this PR -->
|
||||
|
||||
## Related Issue(s)
|
||||
|
||||
<!-- Please link the issue being fixed so it gets closed when this is merged. -->
|
||||
|
||||
Fixes #ISSUE_NUMBER
|
||||
```
|
||||
|
||||
### Guidelines
|
||||
|
||||
- Ensure your commit message follows the conventional commit format (use `pnpm commit`)
|
||||
- Read the submission guidelines in CONTRIBUTING.md before posting
|
||||
- For complex changes, you can request a dedicated Nx release by mentioning the Nx team
|
||||
- Always link the related issue using "Fixes #ISSUE_NUMBER" to automatically close it when merged
|
||||
@@ -1,30 +0,0 @@
|
||||
# Claude Issue Workflow Usage Guide
|
||||
|
||||
## Quick Start
|
||||
|
||||
## Expected Outputs
|
||||
|
||||
### Planning Phase
|
||||
|
||||
- Detailed analysis comment posted to issue
|
||||
- Implementation plan with steps and file changes
|
||||
- Testing strategy and validation steps
|
||||
- Risk assessment
|
||||
|
||||
### Implementation Phase
|
||||
|
||||
- Code changes made according to plan
|
||||
- Tests run and validated
|
||||
- Feature branch created: `fix/issue-{number}`
|
||||
- PR suggestion with proper title format
|
||||
|
||||
## Manual Override
|
||||
|
||||
If you need to work on an issue manually, use the `/gh-issue-plan` command for structured guidance following the same workflow patterns.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- Ensure you're on the authorized users list
|
||||
- Check that the issue has sufficient detail for analysis
|
||||
- For implementation, ensure a plan comment exists from the planning phase
|
||||
- If workflows fail, check the Actions tab for detailed logs
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(find:*)",
|
||||
"Bash(ls:*)",
|
||||
"Bash(mkdir:*)",
|
||||
"WebFetch(domain:github.com)",
|
||||
"WebFetch(domain:www.typescriptlang.org)",
|
||||
"Bash(git log:*)",
|
||||
"Bash(gh issue list:*)",
|
||||
"Bash(gh issue view:*)",
|
||||
"Bash(npx prettier:*)",
|
||||
"Bash(nx prepush:*)",
|
||||
"Bash(pnpm commit:*)",
|
||||
"Bash(rg:*)",
|
||||
"mcp__nx__nx_docs",
|
||||
"mcp__nx__nx_workspace",
|
||||
"mcp__nx__nx_project_details",
|
||||
"Bash(nx show projects:*)",
|
||||
"Bash(nx run-many:*)",
|
||||
"Bash(nx run:*)",
|
||||
"Bash(nx affected:*)",
|
||||
"Bash(nx lint:*)",
|
||||
"Bash(nx test:*)",
|
||||
"Bash(nx build:*)",
|
||||
"Bash(nx documentation:*)"
|
||||
],
|
||||
"deny": []
|
||||
},
|
||||
"enableAllProjectMcpServers": true,
|
||||
"env": {
|
||||
"BASH_MAX_TIMEOUT_MS": "1800000"
|
||||
}
|
||||
}
|
||||
@@ -3,46 +3,26 @@
|
||||
{
|
||||
"name": "NxDevContainer",
|
||||
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
||||
|
||||
// Starting from a base image that already contains GLIBC v2.33 or higher (required by Nx)
|
||||
// Try a more recent distribution, if your are having build issues related to GLIBC version
|
||||
// Here we use 'bookworm', which is based on `Debian-12`, which comes with `GLIBC v2.36`
|
||||
// (Nx tools currenlty requires `GLIBC v2.33` or higher)
|
||||
"image": "mcr.microsoft.com/devcontainers/typescript-node:20-bookworm",
|
||||
|
||||
"image": "mcr.microsoft.com/devcontainers/typescript-node:0-18",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/rust:1": {}
|
||||
},
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// 4211 = nx graph port
|
||||
// 4873 = verdaccio (local npm registry) port
|
||||
"forwardPorts": [4211, 4873],
|
||||
"forwardPorts": [4211],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
"postCreateCommand": "./.devcontainer/postCreateCommand.sh",
|
||||
|
||||
// Configure tool-specific properties.
|
||||
"postCreateCommand": "pnpm install",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"nrwl.angular-console",
|
||||
"firsttris.vscode-jest-runner",
|
||||
"eamodio.gitlens",
|
||||
"mhutchie.git-graph",
|
||||
"mutantdino.resourcemonitor" // to monitor cpu, memory usage from the dev container
|
||||
],
|
||||
"settings": {
|
||||
"debug.javascript.autoAttachFilter": "disabled" // workaround for that issue: https://github.com/microsoft/vscode-js-debug/issues/374#issuecomment-622239998
|
||||
}
|
||||
"extensions": ["nrwl.angular-console"]
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// Configure tool-specific properties.
|
||||
// "customizations": {},
|
||||
|
||||
// To improve disk performances when installing node modules
|
||||
// See https://code.visualstudio.com/remote/advancedcontainers/improve-performance
|
||||
"mounts": [
|
||||
"source=${localWorkspaceFolderBasename}-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume"
|
||||
],
|
||||
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||
"remoteUser": "root"
|
||||
// "remoteUser": "root"
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Update the underlying (Debian) OS, to make sure we have the latest security patches and libraries like 'GLIBC'
|
||||
echo "⚙️ Updating the underlying OS..."
|
||||
sudo apt-get update && sudo apt-get -y upgrade
|
||||
|
||||
# Uninstall globally installed PNPM (required version will be reinstalled through corepack)
|
||||
echo "❌ Uninstalling globally installed PNPM..."
|
||||
npm uninstall -g pnpm
|
||||
|
||||
# Prevent corepack from prompting user before downloading PNPM
|
||||
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||
|
||||
# Enable corepack
|
||||
corepack enable
|
||||
|
||||
# Install the PNPM version defined in the root package.json
|
||||
echo "⚙️ Installing required PNPM version..."
|
||||
corepack prepare --activate
|
||||
|
||||
# Install NPM dependencies
|
||||
echo "⚙️ Installing NPM dependencies..."
|
||||
pnpm install --frozen-lockfile
|
||||
@@ -9,7 +9,7 @@ end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
# 4 space indentation
|
||||
[*.{kts,kt,js,ts,jsx,tsx}]
|
||||
[*.{js,ts,jsx,tsx}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
|
||||
@@ -4,26 +4,12 @@
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"ignorePatterns": ["**/*.ts", "**/test-output"],
|
||||
"ignorePatterns": ["**/*.ts"],
|
||||
"plugins": ["@typescript-eslint", "@nx"],
|
||||
"extends": ["plugin:storybook/recommended"],
|
||||
"rules": {
|
||||
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"paths": [
|
||||
{
|
||||
"name": "create-nx-workspace",
|
||||
"message": "Please import utils from nx or @nx/devkit instead."
|
||||
},
|
||||
{
|
||||
"name": "node-fetch",
|
||||
"message": "Please default to native fetch instead of 'node-fetch'."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"no-restricted-imports": ["error", "create-nx-workspace"],
|
||||
"@typescript-eslint/no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
@@ -31,10 +17,6 @@
|
||||
{
|
||||
"group": ["nx/src/plugins/js*"],
|
||||
"message": "Imports from 'nx/src/plugins/js' are not allowed. Use '@nx/js' instead"
|
||||
},
|
||||
{
|
||||
"group": ["**/native-bindings", "**/native-bindings.js", ""],
|
||||
"message": "Direct imports from native-bindings.js are not allowed. Import from index.js instead."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -42,8 +24,7 @@
|
||||
"storybook/no-uninstalled-addons": [
|
||||
"error",
|
||||
{
|
||||
"ignore": ["@nx/react/plugins/storybook"],
|
||||
"packageJsonLocation": "../../package.json"
|
||||
"ignore": ["@nx/react/plugins/storybook"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -75,27 +56,8 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"@nx/workspace/valid-command-object": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["pnpm-lock.yaml"],
|
||||
"parser": "./tools/eslint-rules/raw-file-parser.js",
|
||||
"rules": {
|
||||
"@nx/workspace/ensure-pnpm-lock-version": [
|
||||
"error",
|
||||
{
|
||||
"version": "9.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts"],
|
||||
"rules": {
|
||||
"@angular-eslint/prefer-standalone": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"nx-mcp": {
|
||||
"type": "stdio",
|
||||
"command": "npx",
|
||||
"args": ["nx", "mcp"]
|
||||
}
|
||||
},
|
||||
"contextFileName": "AGENTS.md"
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
#
|
||||
# https://help.github.com/articles/dealing-with-line-endings/
|
||||
#
|
||||
# Linux start script should use lf
|
||||
/gradlew text eol=lf
|
||||
# These are Windows script files and should use crlf
|
||||
*.bat text eol=crlf
|
||||
# Exclude files from Graphite reviews
|
||||
docs/generated/* linguist-generated=true
|
||||
*.pdf,*.gif,*.mp4,*.webp,*.avif,*.png,*.jpeg,*.jpg,*.tiff filter=lfs diff=lfs merge=lfs -text
|
||||
@@ -1,7 +1,6 @@
|
||||
name: 🐞 Bug Report
|
||||
description: This form is to report unexpected behavior in Nx.
|
||||
labels: ["type: bug"]
|
||||
type: Bug
|
||||
labels: [ "type: bug" ]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
@@ -54,13 +53,6 @@ body:
|
||||
label: Failure Logs
|
||||
description: Please include any relevant log snippets or files here. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
- type: input
|
||||
id: pm
|
||||
attributes:
|
||||
label: Package Manager Version
|
||||
description: |
|
||||
If `nx report` doesn't work, please provide the name and the version of your package manager.
|
||||
You can get version information by running `PACKAGE_MANAGER --version`, where PACKAGE_MANAGER is any of `yarn`, `pnpm`, `bun` or `npm`, depending on the package manager used.
|
||||
- type: checkboxes
|
||||
id: os
|
||||
attributes:
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
name: "\U0001F680 Feature Request"
|
||||
about: Suggest a new feature.
|
||||
labels: "type: feature"
|
||||
|
||||
---
|
||||
<!-- Please do your best to fill out all of the sections below! -->
|
||||
<!-- Use this issue type for concrete suggestions, otherwise, open a discussion type issue instead. -->
|
||||
|
||||
- [ ] I'd be willing to implement this feature ([contributing guide](https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md))
|
||||
|
||||
|
||||
## Description
|
||||
<!-- What is the behavior that you would like to see introduced? -->
|
||||
|
||||
## Motivation
|
||||
<!-- Why do you believe this behavior would be beneficial? -->
|
||||
|
||||
## Suggested Implementation
|
||||
<!-- How do you imagine this might work? -->
|
||||
|
||||
## Alternate Implementations
|
||||
<!-- How else do you imagine this might work? -->
|
||||
@@ -1,17 +1,14 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: "\U0001F680 Feature Request"
|
||||
about: "Suggest a new feature to make Nx better"
|
||||
url: https://github.com/nrwl/nx/discussions/new?category=feature-requests
|
||||
- name: Start a Discussion
|
||||
about: "Start a discussion to share your experience with Nx"
|
||||
url: https://github.com/nrwl/nx/discussions/new/choose
|
||||
- name: Join the Discord
|
||||
url: https://go.nx.dev/community
|
||||
about: "The Nx Official Discord Server is a great place for questions to be asked and answered. Please use the #forum if you need help with your workspace!"
|
||||
- name: Are you looking for integration with a new tool?
|
||||
url: https://nx.dev/community
|
||||
about: "There are a lot of awesome Plugins for Nx provided by the community! Check here to see if there is a community plugin to integrate your tool."
|
||||
- name: Read the community guidelines
|
||||
about: "Please make sure you have read the submission guidelines before posting an issue"
|
||||
url: https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-an-issue
|
||||
- name: Want to start a discussion?
|
||||
about: "Want to start a thread to discuss an idea? Use the discussions feature provided by GitHub."
|
||||
url: https://github.com/nrwl/nx/discussions
|
||||
- name: Have a question?
|
||||
url: https://go.nrwl.io/join-slack
|
||||
about: "The Community Slack is a great place for questions to be asked and answered. Please use the #support channel if you need help with your workspace!"
|
||||
- name: Are you looking for integration with a new tool?
|
||||
url: https://nx.dev/community
|
||||
about: "There are a lot of awesome Plugins for Nx provided by the community! Check here to see if there is a community plugin to integrate your tool."
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
<!-- Please make sure that your commit message follows our format -->
|
||||
<!-- Example: `fix(nx): must begin with lowercase` -->
|
||||
|
||||
<!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. -->
|
||||
|
||||
## Current Behavior
|
||||
<!-- This is the behavior we have today -->
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ Example:
|
||||
}]
|
||||
```
|
||||
|
||||
Once merged, your plugin will be available when running the `nx list` command, and will also be available in the Plugin Registry on [nx.dev](https://nx.dev/plugin-registry)
|
||||
Once merged, your plugin will be available when running the `nx list` command, and will also be available in the Plugin Registry on [nx.dev](https://nx.dev/extending-nx/registry)
|
||||
-->
|
||||
|
||||
# Community Plugin Submission
|
||||
|
||||
@@ -1,297 +0,0 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- '[0-9]+.[0-9]+.x'
|
||||
pull_request:
|
||||
branches:
|
||||
- "**"
|
||||
|
||||
env:
|
||||
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
PNPM_HOME: ~/.pnpm
|
||||
|
||||
jobs:
|
||||
main-linux:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
NX_E2E_CI_CACHE_KEY: e2e-github-linux
|
||||
NX_DAEMON: 'true'
|
||||
NX_PERF_LOGGING: 'false'
|
||||
NX_VERBOSE_LOGGING: 'false'
|
||||
NX_NATIVE_LOGGING: 'false'
|
||||
NX_E2E_RUN_E2E: 'true'
|
||||
NX_CI_EXECUTION_ENV: 'linux'
|
||||
NX_CLOUD_NO_TIMEOUTS: 'true'
|
||||
NX_ALLOW_NON_CACHEABLE_DTE: 'true'
|
||||
NX_CLOUD_USE_NEW_TASK_APIS: 'true'
|
||||
NX_CLOUD_USE_NEW_STREAM_OUTPUT: 'true'
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
filter: tree:0
|
||||
|
||||
- name: Fetch Master
|
||||
run: git fetch origin master:master
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
- name: Set SHAs
|
||||
uses: nrwl/nx-set-shas@1859e66a83ac9be0dceecbd9a023702e27ac47f4 # v4.3.3
|
||||
with:
|
||||
main-branch-name: 'master'
|
||||
|
||||
- name: Start CI Run
|
||||
run: npx nx-cloud@next start-ci-run --auto-apply-fixes="*format:check*,*documentation*" --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@2dbff04819ebbfd5c974947148805a825b8a07fd # v2.1.0
|
||||
|
||||
- uses: pnpm/action-setup@7088e561eb65bb68695d245aa206f005ef30921d # v4.1.0
|
||||
name: Install pnpm
|
||||
with:
|
||||
version: 10.11.1
|
||||
run_install: false
|
||||
|
||||
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: 20
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install Rust
|
||||
uses: actions-rust-lang/setup-rust-toolchain@ac90e63697ac2784f4ecfe2964e1a285c304003a # v1
|
||||
with:
|
||||
rustflags: ''
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 17
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@48b5f213c81028ace310571dc5ec0fbbca0b2947 # v4.4.3
|
||||
|
||||
- name: Install project dependencies
|
||||
run: |
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm playwright install --with-deps
|
||||
|
||||
- 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 &
|
||||
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,test-kt,build,e2e,e2e-ci,format-native,lint-native &
|
||||
pids+=($!)
|
||||
|
||||
for pid in "${pids[@]}"; do
|
||||
wait "$pid"
|
||||
done
|
||||
timeout-minutes: 100
|
||||
- name: Fix CI
|
||||
run: pnpm nx-cloud fix-ci
|
||||
if: failure()
|
||||
|
||||
main-macos:
|
||||
runs-on: macos-latest
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}${{ contains(github.event_name, 'push') && format('-{0}', github.sha) || '' }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
NX_E2E_CI_CACHE_KEY: e2e-github-macos
|
||||
NX_PERF_LOGGING: 'false'
|
||||
NX_CI_EXECUTION_ENV: 'macos'
|
||||
SELECTED_PM: 'npm'
|
||||
steps:
|
||||
|
||||
- name: Log concurrency info
|
||||
run: |
|
||||
echo "Concurrency group: ${{ github.workflow }}-${{ github.ref }}${{ contains(github.event_name, 'push') && format('-{0}', github.sha) || '' }}"
|
||||
echo "Concurrency cancel-in-progress: ${{ !contains(github.event_name, 'push') }}"
|
||||
echo "Concurrency cancel-event-name: ${{ github.event_name }}"
|
||||
if: always()
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
filter: tree:0
|
||||
|
||||
- name: Fetch Master
|
||||
run: git fetch origin master:master
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
- name: Restore Homebrew packages
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
with:
|
||||
path: |
|
||||
/opt/homebrew
|
||||
~/Library/Caches/Homebrew
|
||||
key: nrwl-nx-homebrew-packages
|
||||
|
||||
- name: Configure Detox Environment, Install applesimutils
|
||||
run: |
|
||||
# Ensure Xcode command line tools are installed and configured
|
||||
xcode-select --print-path || sudo xcode-select --reset
|
||||
sudo xcode-select -s /Applications/Xcode.app
|
||||
|
||||
# Install or update applesimutils with error handling
|
||||
if ! brew list applesimutils &>/dev/null; then
|
||||
echo "Installing applesimutils..."
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew >/dev/null
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install applesimutils >/dev/null || {
|
||||
echo "Failed to install applesimutils, retrying with update..."
|
||||
brew update
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install applesimutils
|
||||
}
|
||||
else
|
||||
echo "Updating applesimutils..."
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew upgrade applesimutils || true
|
||||
fi
|
||||
|
||||
# Verify applesimutils installation
|
||||
applesimutils --version || (echo "applesimutils installation failed" && exit 1)
|
||||
|
||||
# Configure environment for M-series Mac
|
||||
echo "DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer" >> $GITHUB_ENV
|
||||
echo "PLATFORM_NAME=iOS Simulator" >> $GITHUB_ENV
|
||||
|
||||
# Set additional environment variables for better debugging
|
||||
echo "DETOX_DISABLE_TELEMETRY=1" >> $GITHUB_ENV
|
||||
echo "DETOX_LOG_LEVEL=trace" >> $GITHUB_ENV
|
||||
|
||||
# Verify Xcode installation
|
||||
xcodebuild -version
|
||||
|
||||
# List available simulators
|
||||
xcrun simctl list devices available
|
||||
timeout-minutes: 10
|
||||
continue-on-error: false
|
||||
|
||||
- name: Reset iOS Simulators
|
||||
id: reset-simulators
|
||||
run: |
|
||||
echo "Resetting iOS Simulators..."
|
||||
|
||||
# Kill simulator processes
|
||||
sudo killall -9 com.apple.CoreSimulator.CoreSimulatorService 2>/dev/null || true
|
||||
killall "Simulator" 2>/dev/null || true
|
||||
killall "iOS Simulator" 2>/dev/null || true
|
||||
|
||||
# Wait for processes to terminate
|
||||
sleep 3
|
||||
|
||||
# Shutdown and erase all simulators (ignore failures)
|
||||
xcrun simctl shutdown all 2>/dev/null || true
|
||||
sleep 5
|
||||
xcrun simctl erase all 2>/dev/null || true
|
||||
|
||||
# If erase failed, try the nuclear option
|
||||
if xcrun simctl list devices | grep -q "Booted" 2>/dev/null; then
|
||||
echo "Standard reset failed, using nuclear option..."
|
||||
rm -rf ~/Library/Developer/CoreSimulator/Devices/* 2>/dev/null || true
|
||||
launchctl remove com.apple.CoreSimulator.CoreSimulatorService 2>/dev/null || true
|
||||
sleep 3
|
||||
fi
|
||||
|
||||
# Clean up additional directories
|
||||
rm -rf ~/Library/Developer/CoreSimulator/Caches/* 2>/dev/null || true
|
||||
rm -rf ~/Library/Logs/CoreSimulator/* 2>/dev/null || true
|
||||
rm -rf ~/Library/Developer/Xcode/DerivedData/* 2>/dev/null || true
|
||||
|
||||
echo "Simulator reset completed"
|
||||
timeout-minutes: 5
|
||||
continue-on-error: true
|
||||
|
||||
- name: Verify Simulator Reset
|
||||
if: ${{ steps.reset-simulators.outcome == 'success' }}
|
||||
run: |
|
||||
# Verify CoreSimulator service restarted
|
||||
pgrep -fl "CoreSimulator" || (echo "CoreSimulator service not running" && exit 1)
|
||||
|
||||
# Check simulator list is clean
|
||||
xcrun simctl list devices
|
||||
|
||||
# Verify simulator runtime paths exist and are writable
|
||||
test -d ~/Library/Developer/CoreSimulator/Devices || (echo "Simulator devices directory missing" && exit 1)
|
||||
touch ~/Library/Developer/CoreSimulator/Devices/test || (echo "Simulator devices directory not writable" && exit 1)
|
||||
rm ~/Library/Developer/CoreSimulator/Devices/test
|
||||
timeout-minutes: 5
|
||||
|
||||
- name: Diagnose Simulator Reset Failure
|
||||
if: ${{ steps.reset-simulators.outcome == 'failure' }}
|
||||
run: |
|
||||
echo "Simulator reset failed. Collecting diagnostic information..."
|
||||
xcrun simctl list
|
||||
echo "Checking simulator logs..."
|
||||
ls -la ~/Library/Logs/CoreSimulator/ || echo "No simulator logs found"
|
||||
|
||||
- name: Save Homebrew Cache
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
with:
|
||||
path: |
|
||||
/opt/homebrew
|
||||
~/Library/Caches/Homebrew
|
||||
key: nrwl-nx-homebrew-packages
|
||||
|
||||
- uses: pnpm/action-setup@7088e561eb65bb68695d245aa206f005ef30921d # v4.1.0
|
||||
name: Install pnpm
|
||||
with:
|
||||
version: 10.11.1
|
||||
run_install: false
|
||||
|
||||
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: 20
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install Rust
|
||||
uses: actions-rust-lang/setup-rust-toolchain@ac90e63697ac2784f4ecfe2964e1a285c304003a # v1
|
||||
with:
|
||||
rustflags: ''
|
||||
|
||||
- name: Install project dependencies
|
||||
run: |
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm playwright install --with-deps
|
||||
|
||||
- name: Set SHAs
|
||||
uses: nrwl/nx-set-shas@1859e66a83ac9be0dceecbd9a023702e27ac47f4 # v4.3.3
|
||||
with:
|
||||
main-branch-name: 'master'
|
||||
|
||||
- name: Run E2E Tests for macOS
|
||||
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
|
||||
@@ -1,104 +0,0 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
schedule:
|
||||
- cron: '20 14 * * 6'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze (${{ matrix.language }})
|
||||
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
||||
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
||||
# - https://gh.io/supported-runners-and-hardware-resources
|
||||
# - https://gh.io/using-larger-runners (GitHub.com only)
|
||||
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
|
||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
||||
permissions:
|
||||
# required for all workflows
|
||||
security-events: write
|
||||
|
||||
# required to fetch internal or private CodeQL packs
|
||||
packages: read
|
||||
|
||||
# only required for workflows in private repositories
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- language: actions
|
||||
build-mode: none
|
||||
|
||||
# We would like to test our Java / Kotlin... but its currently failing. We can follow up.
|
||||
# - language: java-kotlin
|
||||
# build-mode: autobuild
|
||||
- language: javascript-typescript
|
||||
build-mode: none
|
||||
- language: rust
|
||||
build-mode: none
|
||||
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'
|
||||
# Use `c-cpp` to analyze code written in C, C++ or both
|
||||
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
|
||||
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
|
||||
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
|
||||
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
|
||||
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
|
||||
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
# Add any setup steps before running the `github/codeql-action/init` action.
|
||||
# This includes steps like installing compilers or runtimes (`actions/setup-node`
|
||||
# or others). This is typically only required for manual builds.
|
||||
# - name: Setup runtime (example)
|
||||
# uses: actions/setup-example@v1
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@15403aac29bd91419968e066cded66bde56b0283 # v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
build-mode: ${{ matrix.build-mode }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
# If the analyze step fails for one of the languages you are analyzing with
|
||||
# "We were unable to automatically build your code", modify the matrix above
|
||||
# to set the build mode to "manual" for that language. Then modify this step
|
||||
# to build your code.
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
- if: matrix.build-mode == 'manual'
|
||||
shell: bash
|
||||
run: |
|
||||
echo 'If you are using a "manual" build mode for one or more of the' \
|
||||
'languages you are analyzing, replace this with the commands to build' \
|
||||
'your code, for example:'
|
||||
echo ' make bootstrap'
|
||||
echo ' make release'
|
||||
exit 1
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@15403aac29bd91419968e066cded66bde56b0283 # v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
@@ -1,101 +0,0 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ "**" ]
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze (${{ matrix.language }})
|
||||
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
||||
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
||||
# - https://gh.io/supported-runners-and-hardware-resources
|
||||
# - https://gh.io/using-larger-runners (GitHub.com only)
|
||||
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
|
||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
||||
permissions:
|
||||
# required to fetch internal or private CodeQL packs
|
||||
packages: read
|
||||
|
||||
# only required for workflows in private repositories
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- language: actions
|
||||
build-mode: none
|
||||
|
||||
# See comment in @./codeql-master.yml about Java / Kotlin
|
||||
# - language: java-kotlin
|
||||
# build-mode: autobuild
|
||||
- language: javascript-typescript
|
||||
build-mode: none
|
||||
- language: rust
|
||||
build-mode: none
|
||||
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'
|
||||
# Use `c-cpp` to analyze code written in C, C++ or both
|
||||
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
|
||||
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
|
||||
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
|
||||
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
|
||||
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
|
||||
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
# Add any setup steps before running the `github/codeql-action/init` action.
|
||||
# This includes steps like installing compilers or runtimes (`actions/setup-node`
|
||||
# or others). This is typically only required for manual builds.
|
||||
# - name: Setup runtime (example)
|
||||
# uses: actions/setup-example@v1
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@15403aac29bd91419968e066cded66bde56b0283 # v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
build-mode: ${{ matrix.build-mode }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
# If the analyze step fails for one of the languages you are analyzing with
|
||||
# "We were unable to automatically build your code", modify the matrix above
|
||||
# to set the build mode to "manual" for that language. Then modify this step
|
||||
# to build your code.
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
- if: matrix.build-mode == 'manual'
|
||||
shell: bash
|
||||
run: |
|
||||
echo 'If you are using a "manual" build mode for one or more of the' \
|
||||
'languages you are analyzing, replace this with the commands to build' \
|
||||
'your code, for example:'
|
||||
echo ' make bootstrap'
|
||||
echo ' make release'
|
||||
exit 1
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@15403aac29bd91419968e066cded66bde56b0283 # v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
upload: 'never'
|
||||
upload-database: false
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Unmergeable Labels Check
|
||||
name: Unmergable Labels Check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
@@ -2,7 +2,7 @@ name: E2E matrix
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 5 * * *"
|
||||
- cron: "0 0 * * *"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
debug_enabled:
|
||||
@@ -14,75 +14,52 @@ on:
|
||||
env:
|
||||
CYPRESS_CACHE_FOLDER: ${{ github.workspace }}/.cypress
|
||||
|
||||
permissions: { }
|
||||
permissions: {}
|
||||
jobs:
|
||||
preinstall:
|
||||
if: ${{ github.repository_owner == 'nrwl' }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- macos-latest
|
||||
# - windows-latest Windows fails to build gradle wrapper which always runs when we build nx.
|
||||
## https://staging.nx.app/runs/LgD4vxGn8w?utm_source=pull-request&utm_medium=comment
|
||||
node_version:
|
||||
- 20
|
||||
- 22
|
||||
# - 23
|
||||
- 19
|
||||
- 18
|
||||
- 16
|
||||
exclude:
|
||||
# run just node v20 on macos and windows
|
||||
# run just node v18 on macos
|
||||
- os: macos-latest
|
||||
node_version: 22
|
||||
# - os: macos-latest
|
||||
# node_version: 23
|
||||
# - os: windows-latest TODO (emily): Windows fails to build gradle wrapper which always runs when we build nx. Re-enable when we fix this.
|
||||
# node_version: 22
|
||||
# - os: windows-latest TODO (emily): Windows fails to build gradle wrapper which always runs when we build nx. Re-enable when we fix this.
|
||||
# node_version: 23
|
||||
node_version: 19
|
||||
- os: macos-latest
|
||||
node_version: 16
|
||||
|
||||
name: Cache install (${{ matrix.os }}, node v${{ matrix.node_version }})
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
filter: tree:0
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- uses: pnpm/action-setup@7088e561eb65bb68695d245aa206f005ef30921d # v4.1.0
|
||||
name: Install pnpm
|
||||
with:
|
||||
version: 10.11.1
|
||||
run_install: false
|
||||
- name: Install PNPM
|
||||
run: |
|
||||
npm install -g @pnpm/exe@8.3.1
|
||||
|
||||
- name: Set node
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node_version }}
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: echo "path=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache pnpm store
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
- name: Cache node_modules
|
||||
id: cache-modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.path }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Ensure Python setuptools Installed on Macos
|
||||
if: ${{ matrix.os == 'macos-latest' }}
|
||||
id: brew-install-python-setuptools
|
||||
run: brew install python-setuptools
|
||||
lookup-only: true
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-modules-${{ matrix.node_version }}-${{ github.run_id }}
|
||||
|
||||
- name: Install packages
|
||||
run: |
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm playwright install --with-deps
|
||||
if: steps.cache-modules.outputs.cache-hit != 'true'
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Homebrew cache directory path
|
||||
if: ${{ matrix.os == 'macos-latest' }}
|
||||
@@ -91,7 +68,7 @@ jobs:
|
||||
|
||||
- name: Cache Homebrew
|
||||
if: ${{ matrix.os == 'macos-latest' }}
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
lookup-only: true
|
||||
path: ${{ steps.homebrew-cache-dir-path.outputs.dir }}
|
||||
@@ -101,7 +78,7 @@ jobs:
|
||||
|
||||
- name: Cache Cypress
|
||||
id: cache-cypress
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
lookup-only: true
|
||||
path: '${{ github.workspace }}/.cypress'
|
||||
@@ -111,82 +88,262 @@ jobs:
|
||||
if: steps.cache-cypress.outputs.cache-hit != 'true'
|
||||
run: npx cypress install
|
||||
|
||||
prepare-matrix:
|
||||
name: Prepare matrix combinations
|
||||
if: ${{ github.repository_owner == 'nrwl' }}
|
||||
timeout-minutes: 5
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.process-json.outputs.MATRIX }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
filter: tree:0
|
||||
|
||||
- name: Process matrix data
|
||||
id: process-json
|
||||
run:
|
||||
echo "MATRIX=$(npx tsx .github/workflows/nightly/process-matrix.ts | jq -c .)" >> $GITHUB_OUTPUT
|
||||
|
||||
e2e:
|
||||
if: ${{ github.repository_owner == 'nrwl' }}
|
||||
needs:
|
||||
- preinstall
|
||||
- prepare-matrix
|
||||
needs: preinstall
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 200 # <- cap each job to 200 minutes
|
||||
timeout-minutes: 90
|
||||
strategy:
|
||||
matrix: ${{fromJson(needs.prepare-matrix.outputs.matrix)}} # Load matrix from previous job
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- macos-latest
|
||||
node_version:
|
||||
- 19
|
||||
- 18
|
||||
- 16
|
||||
package_manager:
|
||||
- npm
|
||||
- yarn
|
||||
- pnpm
|
||||
project:
|
||||
- e2e-angular-core
|
||||
- e2e-angular-extensions
|
||||
- e2e-cypress
|
||||
- e2e-detox
|
||||
- e2e-esbuild
|
||||
- e2e-expo
|
||||
- e2e-jest
|
||||
- e2e-js
|
||||
- e2e-lerna-smoke-tests
|
||||
- e2e-linter
|
||||
- e2e-next
|
||||
- e2e-node
|
||||
- e2e-nx-init
|
||||
- e2e-nx-misc
|
||||
- e2e-nx-plugin
|
||||
- e2e-nx-run
|
||||
- e2e-react-core
|
||||
- e2e-react-extensions
|
||||
- e2e-react-native
|
||||
- e2e-web
|
||||
- e2e-rollup
|
||||
- e2e-storybook
|
||||
- e2e-storybook-angular
|
||||
- e2e-vite
|
||||
- e2e-webpack
|
||||
- e2e-workspace-create
|
||||
- e2e-workspace-create-npm
|
||||
include:
|
||||
# os short names
|
||||
- os: ubuntu-latest
|
||||
os_name: 'Linux'
|
||||
- os: macos-latest
|
||||
os_name: 'MacOS'
|
||||
# test timeouts
|
||||
- os: ubuntu-latest
|
||||
os_timeout: 60
|
||||
- os: macos-latest
|
||||
os_timeout: 90
|
||||
# codeowner groups
|
||||
- project: e2e-angular-core
|
||||
codeowners: 'S04SS457V38'
|
||||
- project: e2e-angular-extensions
|
||||
codeowners: 'S04SS457V38'
|
||||
- project: e2e-cypress
|
||||
codeowners: 'S04T16BTJJY'
|
||||
- project: e2e-detox
|
||||
codeowners: 'S04TNCNJG5N'
|
||||
- project: e2e-esbuild
|
||||
codeowners: 'S04SJ6HHP0X'
|
||||
- project: e2e-expo
|
||||
codeowners: 'S04TNCNJG5N'
|
||||
- project: e2e-jest
|
||||
codeowners: 'S04T16BTJJY'
|
||||
- project: e2e-js
|
||||
codeowners: 'S04SJ6HHP0X'
|
||||
- project: e2e-lerna-smoke-tests
|
||||
codeowners: 'S04TNCVEETS'
|
||||
- project: e2e-linter
|
||||
codeowners: 'S04SYJGKSCT'
|
||||
- project: e2e-next
|
||||
codeowners: 'S04TNCNJG5N'
|
||||
- project: e2e-node
|
||||
codeowners: 'S04SJ6HHP0X'
|
||||
- project: e2e-nx-init
|
||||
codeowners: 'S04SYHYKGNP'
|
||||
- project: e2e-nx-misc
|
||||
codeowners: 'S04SYHYKGNP'
|
||||
- project: e2e-nx-plugin
|
||||
codeowners: 'S04SYHYKGNP'
|
||||
- project: e2e-nx-run
|
||||
codeowners: 'S04SYHYKGNP'
|
||||
- project: e2e-react-core
|
||||
codeowners: 'S04TNCNJG5N'
|
||||
- project: e2e-react-extensions
|
||||
codeowners: 'S04TNCNJG5N'
|
||||
- project: e2e-react-native
|
||||
codeowners: 'S04TNCNJG5N'
|
||||
- project: e2e-web
|
||||
codeowners: 'S04SJ6PL98X'
|
||||
- project: e2e-rollup
|
||||
codeowners: 'S04SJ6PL98X'
|
||||
- project: e2e-storybook
|
||||
codeowners: 'S04SVQ8H0G5'
|
||||
- project: e2e-storybook-angular
|
||||
codeowners: 'S04SVQ8H0G5'
|
||||
- project: e2e-vite
|
||||
codeowners: 'S04SJ6PL98X'
|
||||
- project: e2e-webpack
|
||||
codeowners: 'S04SJ6PL98X'
|
||||
- project: e2e-workspace-create
|
||||
codeowners: 'S04SYHYKGNP'
|
||||
- project: e2e-workspace-create-npm
|
||||
codeowners: 'S04SYHYKGNP'
|
||||
exclude:
|
||||
# exclude react-native tests from ubuntu
|
||||
- os: ubuntu-latest
|
||||
project: e2e-react-native
|
||||
- os: ubuntu-latest
|
||||
project: e2e-detox
|
||||
- os: ubuntu-latest
|
||||
project: e2e-expo
|
||||
# exclude non-CNW/Lerna tests from non-LTS node versions
|
||||
- node_version: 16
|
||||
project: e2e-angular-core
|
||||
- node_version: 16
|
||||
project: e2e-angular-extensions
|
||||
- node_version: 16
|
||||
project: e2e-cypress
|
||||
- node_version: 16
|
||||
project: e2e-detox
|
||||
- node_version: 16
|
||||
project: e2e-esbuild
|
||||
- node_version: 16
|
||||
project: e2e-expo
|
||||
- node_version: 16
|
||||
project: e2e-jest
|
||||
- node_version: 16
|
||||
project: e2e-js
|
||||
- node_version: 16
|
||||
project: e2e-linter
|
||||
- node_version: 16
|
||||
project: e2e-next
|
||||
- node_version: 16
|
||||
project: e2e-node
|
||||
- node_version: 16
|
||||
project: e2e-nx-init
|
||||
- node_version: 16
|
||||
project: e2e-nx-misc
|
||||
- node_version: 16
|
||||
project: e2e-nx-plugin
|
||||
- node_version: 16
|
||||
project: e2e-lerna-smoke-tests
|
||||
- node_version: 16
|
||||
project: e2e-react-core
|
||||
- node_version: 16
|
||||
project: e2e-react-extensions
|
||||
- node_version: 16
|
||||
project: e2e-react-native
|
||||
- node_version: 16
|
||||
project: e2e-web
|
||||
- node_version: 16
|
||||
project: e2e-rollup
|
||||
- node_version: 16
|
||||
project: e2e-storybook
|
||||
- node_version: 16
|
||||
project: e2e-storybook-angular
|
||||
- node_version: 16
|
||||
project: e2e-vite
|
||||
- node_version: 16
|
||||
project: e2e-webpack
|
||||
- node_version: 19
|
||||
project: e2e-angular-core
|
||||
- node_version: 19
|
||||
project: e2e-angular-extensions
|
||||
- node_version: 19
|
||||
project: e2e-cypress
|
||||
- node_version: 19
|
||||
project: e2e-detox
|
||||
- node_version: 19
|
||||
project: e2e-esbuild
|
||||
- node_version: 19
|
||||
project: e2e-expo
|
||||
- node_version: 19
|
||||
project: e2e-jest
|
||||
- node_version: 19
|
||||
project: e2e-js
|
||||
- node_version: 19
|
||||
project: e2e-linter
|
||||
- node_version: 19
|
||||
project: e2e-next
|
||||
- node_version: 19
|
||||
project: e2e-node
|
||||
- node_version: 19
|
||||
project: e2e-nx-init
|
||||
- node_version: 19
|
||||
project: e2e-nx-misc
|
||||
- node_version: 19
|
||||
project: e2e-nx-plugin
|
||||
- node_version: 19
|
||||
project: e2e-lerna-smoke-tests
|
||||
- node_version: 19
|
||||
project: e2e-react-core
|
||||
- node_version: 19
|
||||
project: e2e-react-extensions
|
||||
- node_version: 19
|
||||
project: e2e-react-native
|
||||
- node_version: 19
|
||||
project: e2e-web
|
||||
- node_version: 19
|
||||
project: e2e-rollup
|
||||
- node_version: 19
|
||||
project: e2e-storybook
|
||||
- node_version: 19
|
||||
project: e2e-storybook-angular
|
||||
- node_version: 19
|
||||
project: e2e-vite
|
||||
- node_version: 19
|
||||
project: e2e-webpack
|
||||
# run just npm v18 on macos
|
||||
- os: macos-latest
|
||||
package_manager: yarn
|
||||
- os: macos-latest
|
||||
package_manager: pnpm
|
||||
- os: macos-latest
|
||||
node_version: 16
|
||||
- os: macos-latest
|
||||
node_version: 19
|
||||
fail-fast: false
|
||||
|
||||
name: ${{ matrix.os_name }}/${{ matrix.package_manager }}/${{ matrix.node_version }} ${{ join(matrix.project) }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
filter: tree:0
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Prepare dir for output
|
||||
run: mkdir -p outputs
|
||||
|
||||
- uses: pnpm/action-setup@7088e561eb65bb68695d245aa206f005ef30921d # v4.1.0
|
||||
name: Install pnpm
|
||||
with:
|
||||
version: 10.11.1
|
||||
run_install: false
|
||||
- name: Install PNPM
|
||||
run: |
|
||||
npm install -g @pnpm/exe@8.3.1
|
||||
|
||||
- name: Use Node.js ${{ matrix.node_version }}
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node_version }}
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install Rust
|
||||
if: ${{ matrix.os != 'windows-latest' }}
|
||||
run: |
|
||||
curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
source "$HOME/.cargo/env"
|
||||
rustup toolchain install 1.70.0
|
||||
|
||||
- name: Load Cargo Env
|
||||
if: ${{ matrix.os != 'windows-latest' }}
|
||||
run: echo "PATH=$HOME/.cargo/bin:$PATH" >> $GITHUB_ENV
|
||||
|
||||
- name: Install bun
|
||||
if: ${{ matrix.os != 'windows-latest' }}
|
||||
uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2.0.2
|
||||
- name: Cache node_modules
|
||||
id: cache-modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
bun-version: latest
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-modules-${{ matrix.node_version }}-${{ github.run_id }}
|
||||
|
||||
- name: Install packages
|
||||
run: |
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm playwright install --with-deps
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Cleanup
|
||||
if: ${{ matrix.os == 'ubuntu-latest' }}
|
||||
@@ -207,7 +364,7 @@ jobs:
|
||||
|
||||
- name: Cache Homebrew
|
||||
if: ${{ matrix.os == 'macos-latest' }}
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.homebrew-cache-dir-path.outputs.dir }}
|
||||
key: brew-${{ matrix.node_version }}
|
||||
@@ -216,7 +373,7 @@ jobs:
|
||||
|
||||
- name: Cache Cypress
|
||||
id: cache-cypress
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: '${{ github.workspace }}/.cypress'
|
||||
key: ${{ runner.os }}-cypress
|
||||
@@ -225,159 +382,43 @@ jobs:
|
||||
if: steps.cache-cypress.outputs.cache-hit != 'true'
|
||||
run: npx cypress install
|
||||
|
||||
- name: Configure Detox Environment, Install applesimutils
|
||||
- name: Install applesimutils, reset ios simulators
|
||||
if: ${{ matrix.os == 'macos-latest' }}
|
||||
run: |
|
||||
# Ensure Xcode command line tools are installed and configured
|
||||
xcode-select --print-path || sudo xcode-select --reset
|
||||
sudo xcode-select -s /Applications/Xcode.app
|
||||
|
||||
# Install or update applesimutils with error handling
|
||||
if ! brew list applesimutils &>/dev/null; then
|
||||
echo "Installing applesimutils..."
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew >/dev/null
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install applesimutils >/dev/null || {
|
||||
echo "Failed to install applesimutils, retrying with update..."
|
||||
brew update
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install applesimutils
|
||||
}
|
||||
else
|
||||
echo "Updating applesimutils..."
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew upgrade applesimutils || true
|
||||
fi
|
||||
|
||||
# Verify applesimutils installation
|
||||
applesimutils --version || (echo "applesimutils installation failed" && exit 1)
|
||||
|
||||
# Configure environment for M-series Mac
|
||||
echo "DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer" >> $GITHUB_ENV
|
||||
echo "PLATFORM_NAME=iOS Simulator" >> $GITHUB_ENV
|
||||
|
||||
# Set additional environment variables for better debugging
|
||||
echo "DETOX_DISABLE_TELEMETRY=1" >> $GITHUB_ENV
|
||||
echo "DETOX_LOG_LEVEL=trace" >> $GITHUB_ENV
|
||||
|
||||
# Verify Xcode installation
|
||||
xcodebuild -version
|
||||
|
||||
timeout-minutes: 10
|
||||
continue-on-error: false
|
||||
|
||||
- name: Reset iOS Simulators
|
||||
if: ${{ matrix.os == 'macos-latest' }}
|
||||
id: reset-simulators
|
||||
run: |
|
||||
echo "Resetting iOS Simulators..."
|
||||
|
||||
# Kill simulator processes
|
||||
sudo killall -9 com.apple.CoreSimulator.CoreSimulatorService 2>/dev/null || true
|
||||
killall "Simulator" 2>/dev/null || true
|
||||
killall "iOS Simulator" 2>/dev/null || true
|
||||
|
||||
# Wait for processes to terminate
|
||||
sleep 3
|
||||
|
||||
# Shutdown and erase all simulators (ignore failures)
|
||||
xcrun simctl shutdown all 2>/dev/null || true
|
||||
sleep 5
|
||||
xcrun simctl erase all 2>/dev/null || true
|
||||
|
||||
# If erase failed, try the nuclear option
|
||||
if xcrun simctl list devices | grep -q "Booted" 2>/dev/null; then
|
||||
echo "Standard reset failed, using nuclear option..."
|
||||
rm -rf ~/Library/Developer/CoreSimulator/Devices/* 2>/dev/null || true
|
||||
launchctl remove com.apple.CoreSimulator.CoreSimulatorService 2>/dev/null || true
|
||||
sleep 3
|
||||
fi
|
||||
|
||||
# Clean up additional directories
|
||||
rm -rf ~/Library/Developer/CoreSimulator/Caches/* 2>/dev/null || true
|
||||
rm -rf ~/Library/Logs/CoreSimulator/* 2>/dev/null || true
|
||||
rm -rf ~/Library/Developer/Xcode/DerivedData/* 2>/dev/null || true
|
||||
|
||||
echo "Simulator reset completed"
|
||||
timeout-minutes: 5
|
||||
continue-on-error: true
|
||||
|
||||
- name: Verify Simulator Reset
|
||||
if: ${{ matrix.os == 'macos-latest' && steps.reset-simulators.outcome == 'success' }}
|
||||
run: |
|
||||
# Verify CoreSimulator service restarted
|
||||
pgrep -fl "CoreSimulator" || (echo "CoreSimulator service not running" && exit 1)
|
||||
|
||||
# Verify simulator runtime paths exist and are writable
|
||||
test -d ~/Library/Developer/CoreSimulator/Devices || (echo "Simulator devices directory missing" && exit 1)
|
||||
touch ~/Library/Developer/CoreSimulator/Devices/test || (echo "Simulator devices directory not writable" && exit 1)
|
||||
rm ~/Library/Developer/CoreSimulator/Devices/test
|
||||
timeout-minutes: 5
|
||||
|
||||
- name: Diagnose Simulator Reset Failure
|
||||
if: ${{ matrix.os == 'macos-latest' && steps.reset-simulators.outcome == 'failure' }}
|
||||
run: |
|
||||
echo "Simulator reset failed. Collecting diagnostic information..."
|
||||
xcrun simctl list
|
||||
echo "Checking simulator logs..."
|
||||
ls -la ~/Library/Logs/CoreSimulator/ || echo "No simulator logs found"
|
||||
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
|
||||
|
||||
- name: Configure git metadata (needed for lerna smoke tests)
|
||||
if: ${{ (matrix.os != 'macos-latest') || (matrix.os == 'macos-latest' && steps.reset-simulators.outcome == 'success') }}
|
||||
run: |
|
||||
git config --global user.email test@test.com
|
||||
git config --global user.name "Test Test"
|
||||
|
||||
- name: Set starting timestamp
|
||||
if: ${{ (matrix.os != 'macos-latest') || (matrix.os == 'macos-latest' && steps.reset-simulators.outcome == 'success') }}
|
||||
id: before-e2e
|
||||
shell: bash
|
||||
run: |
|
||||
echo "timestamp=$(date +%s)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Run e2e tests with pnpm (Linux/Windows)
|
||||
id: e2e-run-pnpm
|
||||
if: ${{ matrix.os != 'macos-latest' }}
|
||||
run: pnpm nx run ${{ matrix.project }}:e2e-local
|
||||
shell: bash
|
||||
- name: Run e2e tests
|
||||
id: e2e-run
|
||||
run: pnpm nx run-many -t e2e,e2e-macos -p ${{ matrix.project }}
|
||||
timeout-minutes: ${{ matrix.os_timeout }}
|
||||
env:
|
||||
GIT_AUTHOR_EMAIL: test@test.com
|
||||
GIT_AUTHOR_NAME: Test
|
||||
GIT_COMMITTER_EMAIL: test@test.com
|
||||
GIT_COMMITTER_NAME: Test
|
||||
NX_E2E_CI_CACHE_KEY: e2e-gha-${{ matrix.os }}-${{ matrix.node_version }}-${{ matrix.package_manager }}
|
||||
NX_DAEMON: 'true'
|
||||
NX_PERF_LOGGING: 'false'
|
||||
NX_E2E_VERBOSE_LOGGING: 'true'
|
||||
NX_NATIVE_LOGGING: 'false'
|
||||
NX_E2E_RUN_E2E: 'true'
|
||||
NX_CLOUD_NO_TIMEOUTS: 'true'
|
||||
NX_E2E_SKIP_CLEANUP: 'true'
|
||||
NODE_OPTIONS: --max_old_space_size=8192
|
||||
SELECTED_PM: ${{ matrix.package_manager }}
|
||||
npm_config_registry: http://localhost:4872
|
||||
YARN_REGISTRY: http://localhost:4872
|
||||
CI: true
|
||||
|
||||
- name: Run e2e tests with npm (macOS)
|
||||
id: e2e-run-npm
|
||||
if: ${{ matrix.os == 'macos-latest' && steps.reset-simulators.outcome == 'success' }}
|
||||
run: |
|
||||
# Run the tests
|
||||
if [[ "${{ matrix.project }}" == "e2e-detox" ]] || [[ "${{ matrix.project }}" == "e2e-react-native" ]] || [[ "${{ matrix.project }}" == "e2e-expo" ]]; then
|
||||
NX_E2E_VERBOSE_DEBUG=1 pnpm nx run ${{ matrix.project }}:e2e-macos-local
|
||||
else
|
||||
NX_E2E_VERBOSE_DEBUG=1 pnpm nx run ${{ matrix.project }}:e2e-local
|
||||
fi
|
||||
|
||||
env:
|
||||
NX_E2E_CI_CACHE_KEY: e2e-gha-${{ matrix.os }}-${{ matrix.node_version }}-${{ matrix.package_manager }}
|
||||
NX_PERF_LOGGING: 'false'
|
||||
NX_CI_EXECUTION_ENV: 'macos'
|
||||
NX_E2E_VERBOSE_LOGGING: 'true'
|
||||
NX_NATIVE_LOGGING: 'false'
|
||||
NX_CACHE_DIRECTORY: 'tmp'
|
||||
NX_E2E_SKIP_BUILD_CLEANUP: 'true'
|
||||
NX_E2E_RUN_E2E: 'true'
|
||||
NX_E2E_SKIP_CLEANUP: 'true'
|
||||
NODE_OPTIONS: --max_old_space_size=8192
|
||||
SELECTED_PM: 'npm'
|
||||
npm_config_registry: http://localhost:4872
|
||||
YARN_REGISTRY: http://localhost:4872
|
||||
DEVELOPER_DIR: '/Applications/Xcode.app/Contents/Developer'
|
||||
CI: true
|
||||
NX_E2E_VERBOSE_LOGGING: 'true'
|
||||
NX_PERF_LOGGING: 'false'
|
||||
NX_DAEMON: 'true'
|
||||
|
||||
- name: Save matrix config in file
|
||||
if: ${{ always() }}
|
||||
@@ -387,99 +428,210 @@ jobs:
|
||||
before=${{ steps.before-e2e.outputs.timestamp }}
|
||||
now=$(date +%s)
|
||||
delta=$(($now - $before))
|
||||
|
||||
# Determine the outcome based on which step ran
|
||||
outcome="${{ matrix.os == 'macos-latest' && steps.e2e-run-npm.outcome || steps.e2e-run-pnpm.outcome }}"
|
||||
|
||||
matrix=$((
|
||||
echo '${{ toJSON(matrix) }}'
|
||||
) | jq --argjson delta $delta -c '. + { "status": "'"$outcome"'", "duration": $delta }')
|
||||
echo "$matrix" > 'outputs/matrix.json'
|
||||
) | jq --argjson delta $delta -c '. + { "status": "${{ steps.e2e-run.outcome}}", "duration": $delta }')
|
||||
echo "$matrix" > matrix
|
||||
path=outputs/${{ matrix.os_name}}-${{ matrix.node_version}}-${{ matrix.package_manager}}-${{ matrix.project }}
|
||||
echo "path=$path" >> $GITHUB_OUTPUT
|
||||
echo "$matrix" > $path
|
||||
|
||||
- name: Upload matrix config
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
uses: actions/upload-artifact@v3
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: ${{ matrix.os_name}}-${{ matrix.node_version}}-${{ matrix.package_manager}}-${{ matrix.project }}
|
||||
overwrite: true
|
||||
if-no-files-found: 'ignore'
|
||||
path: 'outputs/matrix.json'
|
||||
name: outputs
|
||||
path: ${{ steps.save-matrix.outputs.path }}
|
||||
|
||||
- name: Setup tmate session
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled && failure() }}
|
||||
uses: mxschmitt/action-tmate@1fb8b1023602bf1fd0e2994d7f1e93015cb5bbec # v3.22
|
||||
uses: mxschmitt/action-tmate@v3.8
|
||||
timeout-minutes: 15
|
||||
with:
|
||||
sudo: ${{ matrix.os != 'windows-latest' }} # disable sudo for windows debugging
|
||||
|
||||
process-result:
|
||||
if: ${{ always() && github.repository_owner == 'nrwl' && github.event_name != 'workflow_dispatch' }}
|
||||
if: ${{ always() }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: e2e
|
||||
timeout-minutes: 10
|
||||
outputs:
|
||||
message: ${{ steps.process-json.outputs.slack_message }}
|
||||
proj_duration: ${{ steps.process-json.outputs.slack_proj_duration }}
|
||||
pm_duration: ${{ steps.process-json.outputs.slack_pm_duration }}
|
||||
codeowners: ${{ steps.process-json.outputs.codeowners }}
|
||||
has_golden_failures: ${{ steps.process-json.outputs.has_golden_failures }}
|
||||
message: ${{ steps.process-json.outputs.SLACK_MESSAGE }}
|
||||
proj-duration: ${{ steps.process-json.outputs.SLACK_PROJ_DURATION }}
|
||||
pm-duration: ${{ steps.process-json.outputs.SLACK_PM_DURATION }}
|
||||
codeowners: ${{ steps.process-json.outputs.CODEOWNERS }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
filter: tree:0
|
||||
|
||||
- name: Prepare dir for output
|
||||
run: mkdir -p outputs
|
||||
|
||||
- name: Load outputs
|
||||
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: outputs
|
||||
path: outputs
|
||||
|
||||
- name: Join and stringify matrix configs
|
||||
id: combine-json
|
||||
run: |
|
||||
combined=$(jq -sc . outputs/*/matrix.json)
|
||||
combined=$((jq -s . outputs/*) | jq tostring)
|
||||
echo "combined=$combined" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Process results with TypeScript script
|
||||
- name: Make slack outputs
|
||||
id: process-json
|
||||
run: |
|
||||
echo '${{ steps.combine-json.outputs.combined }}' | npx tsx .github/workflows/nightly/process-result.ts
|
||||
uses: actions/github-script@v6
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
script: |
|
||||
const combined = JSON.parse(${{ steps.combine-json.outputs.combined }});
|
||||
const failedProjects = combined.filter(c => c.status === 'failure').sort((a, b) => a.project.localeCompare(b.project));
|
||||
|
||||
// codeowners
|
||||
const codeowners = new Set();
|
||||
failedProjects.forEach(c => {
|
||||
codeowners.add(c.codeowners);
|
||||
});
|
||||
core.setOutput('CODEOWNERS', Array.from(codeowners).join(','));
|
||||
|
||||
function trimSpace(res) {
|
||||
return res.split('\n').map((l) => l.trim()).join('\n');
|
||||
}
|
||||
|
||||
// failed message
|
||||
let lastProject;
|
||||
let result = `
|
||||
\`\`\`
|
||||
| Failed project | PM | OS | Node |
|
||||
|--------------------------------|------|-------|------|`;
|
||||
failedProjects.forEach(matrix => {
|
||||
const project = matrix.project !== lastProject ? matrix.project : '...';
|
||||
result += `\n| ${project.padEnd(30)} | ${matrix.package_manager.padEnd(4)} | ${matrix.os_name} | v${matrix.node_version.toString().padEnd(3)} |`
|
||||
lastProject = matrix.project;
|
||||
});
|
||||
result += `\`\`\``;
|
||||
core.setOutput('SLACK_MESSAGE', trimSpace(result));
|
||||
|
||||
function humanizeDuration(num) {
|
||||
let res = '';
|
||||
const hours = Math.floor(num / 3600);
|
||||
if (hours) {
|
||||
res += `${hours}h `;
|
||||
}
|
||||
const mins = Math.floor((num % 3600) / 60);
|
||||
if (mins) {
|
||||
res += `${mins}m `;
|
||||
}
|
||||
const sec = num % 60;
|
||||
if (sec) {
|
||||
res += `${sec}s`
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// duration message
|
||||
const timeReport = {};
|
||||
const pmReport = {
|
||||
npm: 0,
|
||||
yarn: 0,
|
||||
pnpm: 0
|
||||
};
|
||||
const macosProjects = ['e2e-detox', 'e2e-expo', 'e2e-react-native'];
|
||||
combined.forEach((matrix) => {
|
||||
if (matrix.os_name === 'Linux' && matrix.node_version === 18) {
|
||||
pmReport[matrix.package_manager] += matrix.duration;
|
||||
}
|
||||
if (matrix.os_name === 'Linux' || macosProjects.includes(matrix.project)) {
|
||||
if (timeReport[matrix.project]) {
|
||||
if (matrix.duration > timeReport[matrix.project].max) {
|
||||
timeReport[matrix.project].max = matrix.duration;
|
||||
timeReport[
|
||||
matrix.project
|
||||
].maxEnv = `${matrix.os_name}, ${matrix.package_manager}`;
|
||||
}
|
||||
if (matrix.duration < timeReport[matrix.project].min) {
|
||||
timeReport[matrix.project].min = matrix.duration;
|
||||
timeReport[
|
||||
matrix.project
|
||||
].minEnv = `${matrix.os_name}, ${matrix.package_manager}`;
|
||||
}
|
||||
} else {
|
||||
timeReport[matrix.project] = {
|
||||
min: matrix.duration,
|
||||
max: matrix.duration,
|
||||
minEnv: `${matrix.os_name}, ${matrix.package_manager}`,
|
||||
maxEnv: `${matrix.os_name}, ${matrix.package_manager}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// project time report
|
||||
let resultPkg = `
|
||||
\`\`\`
|
||||
| Project | Time |
|
||||
|--------------------------------|---------------------------|`;
|
||||
function mapProjectTime(proj, section) {
|
||||
let res = '';
|
||||
res += `${humanizeDuration(timeReport[proj][section])}`;
|
||||
res += ` (${timeReport[proj][section + 'Env']})`
|
||||
return res;
|
||||
}
|
||||
function durationIcon(proj, section) {
|
||||
if (timeReport[proj][section] < 12 * 60) {
|
||||
return `${section} ✅`;
|
||||
}
|
||||
if (timeReport[proj][section] < 15 * 60) {
|
||||
return `${section} ❗`;
|
||||
}
|
||||
return `${section} ❌`;
|
||||
}
|
||||
Object.keys(timeReport).forEach(proj => {
|
||||
resultPkg += `\n| ${proj.padEnd(30)} | |`;
|
||||
resultPkg += `\n| ${durationIcon(proj, 'min').padStart(29)} | ${mapProjectTime(proj, 'min').padEnd(25)} |`;
|
||||
resultPkg += `\n| ${durationIcon(proj, 'max').padStart(29)} | ${mapProjectTime(proj, 'max').padEnd(25)} |`;
|
||||
});
|
||||
resultPkg += `\`\`\``;
|
||||
core.setOutput('SLACK_PROJ_DURATION', trimSpace(resultPkg));
|
||||
|
||||
// Print project duration report inline to allow reviewing on manual runs (when no slack message will be sent)
|
||||
console.log(trimSpace(resultPkg));
|
||||
|
||||
let resultPm = `
|
||||
\`\`\`
|
||||
| PM | Total time |
|
||||
|------|-------------|`;
|
||||
Object.keys(pmReport).forEach(pm => {
|
||||
resultPm += `\n| ${pm.padEnd(4)} | ${humanizeDuration(pmReport[pm]).padEnd(11)} |`
|
||||
});
|
||||
resultPm += `\`\`\``;
|
||||
core.setOutput('SLACK_PM_DURATION', trimSpace(resultPm));
|
||||
|
||||
// Print package manager duration report inline to allow reviewing on manual runs (when no slack message will be sent)
|
||||
console.log(trimSpace(resultPm));
|
||||
|
||||
report-failure:
|
||||
if: ${{ always() && needs.process-result.outputs.has_golden_failures == 'true' && github.repository_owner == 'nrwl' && github.event_name != 'workflow_dispatch' }}
|
||||
if: ${{ failure() && github.repository_owner == 'nrwl' && github.event_name != 'workflow_dispatch' }}
|
||||
needs: process-result
|
||||
runs-on: ubuntu-latest
|
||||
name: Report failure
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Send notification
|
||||
uses: ravsamhq/notify-slack-action@be814b201e233b2dc673608aa46e5447c8ab13f2 # v11
|
||||
uses: ravsamhq/notify-slack-action@v2
|
||||
with:
|
||||
status: 'failure'
|
||||
message_format: '${{ needs.process-result.outputs.message }}'
|
||||
notification_title: 'Golden Test Failure'
|
||||
message_format: '{emoji} Workflow has {status_message} ${{ needs.process-result.outputs.message }}'
|
||||
notification_title: '{workflow}'
|
||||
footer: '<{run_url}|View Run> / Last commit <{commit_url}|{commit_sha}>'
|
||||
mention_groups: ${{ needs.process-result.outputs.codeowners }}
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.ACTION_MONITORING_SLACK }}
|
||||
|
||||
report-success:
|
||||
if: ${{ always() && needs.process-result.outputs.has_golden_failures == 'false' && github.repository_owner == 'nrwl' && github.event_name != 'workflow_dispatch' }}
|
||||
needs: process-result
|
||||
if: ${{ success() && github.repository_owner == 'nrwl' && github.event_name != 'workflow_dispatch' }}
|
||||
needs: e2e
|
||||
runs-on: ubuntu-latest
|
||||
name: Report status
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Send notification
|
||||
uses: ravsamhq/notify-slack-action@be814b201e233b2dc673608aa46e5447c8ab13f2 # v11
|
||||
uses: ravsamhq/notify-slack-action@v2
|
||||
with:
|
||||
status: 'success'
|
||||
message_format: '${{ needs.process-result.outputs.message }}'
|
||||
notification_title: '✅ Golden Tests: All Passed!'
|
||||
status: ${{ needs.e2e.result }}
|
||||
message_format: '{emoji} Workflow has {status_message}'
|
||||
notification_title: '{workflow}'
|
||||
footer: '<{run_url}|View Run> / Last commit <{commit_url}|{commit_sha}>'
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.ACTION_MONITORING_SLACK }}
|
||||
@@ -488,15 +640,14 @@ jobs:
|
||||
if: ${{ always() && github.repository_owner == 'nrwl' && github.event_name != 'workflow_dispatch' }}
|
||||
needs: process-result
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
name: Report duration per package manager
|
||||
steps:
|
||||
- name: Send notification
|
||||
uses: ravsamhq/notify-slack-action@be814b201e233b2dc673608aa46e5447c8ab13f2 # v11
|
||||
uses: ravsamhq/notify-slack-action@v2
|
||||
with:
|
||||
status: 'skipped'
|
||||
message_format: '${{ needs.process-result.outputs.pm_duration }}'
|
||||
notification_title: '⌛ Total duration per package manager (ubuntu only)'
|
||||
message_format: '${{ needs.process-result.outputs.pm-duration }}'
|
||||
notification_title: 'Total duration per package manager (ubuntu only)'
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.ACTION_MONITORING_SLACK }}
|
||||
|
||||
@@ -504,14 +655,13 @@ jobs:
|
||||
if: ${{ always() && github.repository_owner == 'nrwl' && github.event_name != 'workflow_dispatch' }}
|
||||
needs: process-result
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
name: Report duration per project
|
||||
name: Report duration per package manager
|
||||
steps:
|
||||
- name: Send notification
|
||||
uses: ravsamhq/notify-slack-action@be814b201e233b2dc673608aa46e5447c8ab13f2 # v11
|
||||
uses: ravsamhq/notify-slack-action@v2
|
||||
with:
|
||||
status: 'skipped'
|
||||
message_format: '${{ needs.process-result.outputs.proj_duration }}'
|
||||
notification_title: '⌛ E2E Project duration stats'
|
||||
message_format: '${{ needs.process-result.outputs.proj-duration }}'
|
||||
notification_title: 'E2E Project duration stats'
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.ACTION_MONITORING_SLACK }}
|
||||
|
||||
@@ -0,0 +1,421 @@
|
||||
name: E2E matrix (Windows)
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
debug_enabled:
|
||||
type: boolean
|
||||
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
|
||||
required: false
|
||||
default: false
|
||||
|
||||
env:
|
||||
CYPRESS_CACHE_FOLDER: ${{ github.workspace }}/.cypress
|
||||
|
||||
permissions: {}
|
||||
jobs:
|
||||
preinstall:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node_version:
|
||||
- 19
|
||||
- 18
|
||||
- 16
|
||||
|
||||
name: Cache install (node v${{ matrix.node_version }})
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- uses: pnpm/action-setup@v2
|
||||
name: Install pnpm
|
||||
with:
|
||||
version: 8.3.1
|
||||
run_install: false
|
||||
|
||||
- name: Set node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node_version }}
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Cache node_modules
|
||||
id: cache-modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
lookup-only: true
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-modules-${{ matrix.node_version }}-${{ github.run_id }}
|
||||
|
||||
- name: Install packages
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Cache Cypress
|
||||
id: cache-cypress
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
lookup-only: true
|
||||
path: '${{ github.workspace }}/.cypress'
|
||||
key: windows-cypress
|
||||
|
||||
- name: Install Cypress
|
||||
if: steps.cache-cypress.outputs.cache-hit != 'true'
|
||||
run: npx cypress install
|
||||
|
||||
e2e:
|
||||
needs: preinstall
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node_version:
|
||||
- 19
|
||||
- 18
|
||||
- 16
|
||||
package_manager:
|
||||
- npm
|
||||
project:
|
||||
- e2e-angular-core
|
||||
- e2e-angular-extensions
|
||||
- e2e-cypress
|
||||
- e2e-esbuild
|
||||
- e2e-jest
|
||||
- e2e-js
|
||||
- e2e-lerna-smoke-tests
|
||||
- e2e-linter
|
||||
- e2e-next
|
||||
- e2e-node
|
||||
- e2e-nx-init
|
||||
- e2e-nx-misc
|
||||
- e2e-plugin
|
||||
- e2e-nx-run
|
||||
- e2e-react-core
|
||||
- e2e-react-extensions
|
||||
- e2e-web
|
||||
- e2e-rollup
|
||||
- e2e-storybook
|
||||
- e2e-storybook-angular
|
||||
- e2e-vite
|
||||
- e2e-webpack
|
||||
- e2e-workspace-create
|
||||
- e2e-workspace-create-npm
|
||||
include:
|
||||
# codeowner groups
|
||||
- project: e2e-angular-core
|
||||
codeowners: 'S04SS457V38'
|
||||
- project: e2e-angular-extensions
|
||||
codeowners: 'S04SS457V38'
|
||||
- project: e2e-cypress
|
||||
codeowners: 'S04T16BTJJY'
|
||||
- project: e2e-esbuild
|
||||
codeowners: 'S04SJ6HHP0X'
|
||||
- project: e2e-jest
|
||||
codeowners: 'S04T16BTJJY'
|
||||
- project: e2e-js
|
||||
codeowners: 'S04SJ6HHP0X'
|
||||
- project: e2e-lerna-smoke-tests
|
||||
codeowners: 'S04TNCVEETS'
|
||||
- project: e2e-linter
|
||||
codeowners: 'S04SYJGKSCT'
|
||||
- project: e2e-next
|
||||
codeowners: 'S04TNCNJG5N'
|
||||
- project: e2e-node
|
||||
codeowners: 'S04SJ6HHP0X'
|
||||
- project: e2e-nx-init
|
||||
codeowners: 'S04SYHYKGNP'
|
||||
- project: e2e-nx-misc
|
||||
codeowners: 'S04SYHYKGNP'
|
||||
- project: e2e-plugin
|
||||
codeowners: 'S04SYHYKGNP'
|
||||
- project: e2e-nx-run
|
||||
codeowners: 'S04SYHYKGNP'
|
||||
- project: e2e-react-core
|
||||
codeowners: 'S04TNCNJG5N'
|
||||
- project: e2e-react-extensions
|
||||
codeowners: 'S04TNCNJG5N'
|
||||
- project: e2e-web
|
||||
codeowners: 'S04SJ6PL98X'
|
||||
- project: e2e-rollup
|
||||
codeowners: 'S04SJ6PL98X'
|
||||
- project: e2e-storybook
|
||||
codeowners: 'S04SVQ8H0G5'
|
||||
- project: e2e-storybook-angular
|
||||
codeowners: 'S04SVQ8H0G5'
|
||||
- project: e2e-vite
|
||||
codeowners: 'S04SJ6PL98X'
|
||||
- project: e2e-webpack
|
||||
codeowners: 'S04SJ6PL98X'
|
||||
- project: e2e-workspace-create
|
||||
codeowners: 'S04SYHYKGNP'
|
||||
- project: e2e-workspace-create-npm
|
||||
codeowners: 'S04SYHYKGNP'
|
||||
exclude:
|
||||
# exclude non-CNW/Lerna tests from non-LTS node versions
|
||||
- node_version: 16
|
||||
project: e2e-angular-core
|
||||
- node_version: 16
|
||||
project: e2e-angular-extensions
|
||||
- node_version: 16
|
||||
project: e2e-cypress
|
||||
- node_version: 16
|
||||
project: e2e-esbuild
|
||||
- node_version: 16
|
||||
project: e2e-jest
|
||||
- node_version: 16
|
||||
project: e2e-js
|
||||
- node_version: 16
|
||||
project: e2e-linter
|
||||
- node_version: 16
|
||||
project: e2e-next
|
||||
- node_version: 16
|
||||
project: e2e-node
|
||||
- node_version: 16
|
||||
project: e2e-nx-init
|
||||
- node_version: 16
|
||||
project: e2e-nx-misc
|
||||
- node_version: 16
|
||||
project: e2e-plugin
|
||||
- node_version: 16
|
||||
project: e2e-lerna-smoke-tests
|
||||
- node_version: 16
|
||||
project: e2e-react-core
|
||||
- node_version: 16
|
||||
project: e2e-react-extensions
|
||||
- node_version: 16
|
||||
project: e2e-web
|
||||
- node_version: 16
|
||||
project: e2e-rollup
|
||||
- node_version: 16
|
||||
project: e2e-storybook
|
||||
- node_version: 16
|
||||
project: e2e-storybook-angular
|
||||
- node_version: 16
|
||||
project: e2e-vite
|
||||
- node_version: 16
|
||||
project: e2e-webpack
|
||||
- node_version: 19
|
||||
project: e2e-angular-core
|
||||
- node_version: 19
|
||||
project: e2e-angular-extensions
|
||||
- node_version: 19
|
||||
project: e2e-cypress
|
||||
- node_version: 19
|
||||
project: e2e-esbuild
|
||||
- node_version: 19
|
||||
project: e2e-jest
|
||||
- node_version: 19
|
||||
project: e2e-js
|
||||
- node_version: 19
|
||||
project: e2e-linter
|
||||
- node_version: 19
|
||||
project: e2e-next
|
||||
- node_version: 19
|
||||
project: e2e-node
|
||||
- node_version: 19
|
||||
project: e2e-nx-init
|
||||
- node_version: 19
|
||||
project: e2e-nx-misc
|
||||
- node_version: 19
|
||||
project: e2e-plugin
|
||||
- node_version: 19
|
||||
project: e2e-lerna-smoke-tests
|
||||
- node_version: 19
|
||||
project: e2e-react-core
|
||||
- node_version: 19
|
||||
project: e2e-react-extensions
|
||||
- node_version: 19
|
||||
project: e2e-web
|
||||
- node_version: 19
|
||||
project: e2e-rollup
|
||||
- node_version: 19
|
||||
project: e2e-storybook
|
||||
- node_version: 19
|
||||
project: e2e-storybook-angular
|
||||
- node_version: 19
|
||||
project: e2e-vite
|
||||
- node_version: 19
|
||||
project: e2e-webpack
|
||||
fail-fast: false
|
||||
|
||||
name: ${{ matrix.project }} (v${{ matrix.node_version }})
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Prepare dir for output
|
||||
run: mkdir -p outputs
|
||||
|
||||
- uses: pnpm/action-setup@v2
|
||||
name: Install pnpm
|
||||
with:
|
||||
version: 8.3.1
|
||||
run_install: false
|
||||
|
||||
- name: Use Node.js ${{ matrix.node_version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node_version }}
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Cache node_modules
|
||||
id: cache-modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-modules-${{ matrix.node_version }}-${{ github.run_id }}
|
||||
|
||||
- name: Install packages
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Cache Cypress
|
||||
id: cache-cypress
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: '${{ github.workspace }}/.cypress'
|
||||
key: ${{ runner.os }}-cypress
|
||||
|
||||
- name: Install Cypress
|
||||
if: steps.cache-cypress.outputs.cache-hit != 'true'
|
||||
run: npx cypress install
|
||||
|
||||
- name: Configure git metadata (needed for lerna smoke tests)
|
||||
run: |
|
||||
git config --global user.email test@test.com
|
||||
git config --global user.name "Test Test"
|
||||
|
||||
- name: Run e2e tests
|
||||
id: e2e-run
|
||||
run: pnpm nx run ${{ matrix.project }}:e2e
|
||||
shell: bash
|
||||
timeout-minutes: 120
|
||||
env:
|
||||
GIT_AUTHOR_EMAIL: test@test.com
|
||||
GIT_AUTHOR_NAME: Test
|
||||
GIT_COMMITTER_EMAIL: test@test.com
|
||||
GIT_COMMITTER_NAME: Test
|
||||
NX_E2E_CI_CACHE_KEY: e2e-gha-windows-${{ matrix.node_version }}-${{ matrix.package_manager }}
|
||||
NODE_OPTIONS: --max_old_space_size=8192
|
||||
SELECTED_PM: ${{ matrix.package_manager }}
|
||||
npm_config_registry: http://localhost:4872
|
||||
NX_CACHE_DIRECTORY: 'tmp'
|
||||
NX_E2E_SKIP_BUILD_CLEANUP: 'true'
|
||||
NX_E2E_RUN_E2E: 'true'
|
||||
NX_E2E_VERBOSE_LOGGING: 'true'
|
||||
NX_PERF_LOGGING: 'false'
|
||||
NX_DAEMON: 'true'
|
||||
|
||||
- name: Save matrix config in file
|
||||
if: ${{ always() }}
|
||||
id: save-matrix
|
||||
shell: bash
|
||||
run: |
|
||||
matrix=$((
|
||||
echo '${{ toJSON(matrix) }}'
|
||||
) | jq -c '. + { "status": "${{ steps.e2e-run.outcome}}" }')
|
||||
echo "$matrix" > matrix
|
||||
path=outputs/windows-${{ matrix.node_version}}-${{ matrix.package_manager}}-${{ matrix.project }}
|
||||
echo "path=$path" >> $GITHUB_OUTPUT
|
||||
echo "$matrix" > $path
|
||||
|
||||
- name: Upload matrix config
|
||||
uses: actions/upload-artifact@v3
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: outputs
|
||||
path: ${{ steps.save-matrix.outputs.path }}
|
||||
|
||||
- name: Setup tmate session
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled && failure() }}
|
||||
uses: mxschmitt/action-tmate@v3.8
|
||||
timeout-minutes: 15
|
||||
with:
|
||||
sudo: false # disable sudo for windows debugging
|
||||
|
||||
process-result:
|
||||
if: ${{ always() }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: e2e
|
||||
outputs:
|
||||
message: ${{ steps.process-json.outputs.SLACK_MESSAGE }}
|
||||
codeowners: ${{ steps.process-json.outputs.CODEOWNERS }}
|
||||
steps:
|
||||
- name: Load outputs
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: outputs
|
||||
path: outputs
|
||||
|
||||
- name: Join and stringify matrix configs
|
||||
id: combine-json
|
||||
shell: bash
|
||||
run: |
|
||||
combined=$((jq -s . outputs/*) | jq tostring)
|
||||
echo "combined=$combined" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Make slack outputs
|
||||
id: process-json
|
||||
uses: actions/github-script@v6
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
script: |
|
||||
const combined = JSON.parse(${{ steps.combine-json.outputs.combined }});
|
||||
const failedProjects = combined.filter(c => c.status === 'failure').sort((a, b) => a.project.localeCompare(b.project));
|
||||
|
||||
// codeowners
|
||||
const codeowners = new Set();
|
||||
failedProjects.forEach(c => {
|
||||
codeowners.add(c.codeowners);
|
||||
});
|
||||
core.setOutput('CODEOWNERS', Array.from(codeowners).join(','));
|
||||
|
||||
// message
|
||||
let result = `
|
||||
*OS* Windows
|
||||
*Package manager* npm
|
||||
\`\`\`
|
||||
| Failed project | Node |
|
||||
|--------------------------------|------|`;
|
||||
failedProjects.forEach(matrix => {
|
||||
result += `\n| ${matrix.project.padEnd(30)} | v${matrix.node_version.toString().padEnd(3)} |`
|
||||
});
|
||||
result += `\`\`\``;
|
||||
const message = result.split('\n').map(l => l.trim()).join('\n');
|
||||
core.setOutput('SLACK_MESSAGE', message);
|
||||
|
||||
report-failure:
|
||||
if: ${{ failure() && github.repository_owner == 'nrwl' && github.event_name != 'workflow_dispatch' }}
|
||||
needs: process-result
|
||||
runs-on: ubuntu-latest
|
||||
name: Report failure
|
||||
steps:
|
||||
- name: Send notification
|
||||
uses: ravsamhq/notify-slack-action@v2
|
||||
with:
|
||||
status: 'failure'
|
||||
message_format: '{emoji} Workflow has {status_message} ${{ needs.process-result.outputs.message }}'
|
||||
notification_title: '{workflow}'
|
||||
footer: '<{run_url}|View Run> / Last commit <{commit_url}|{commit_sha}>'
|
||||
mention_groups: ${{ needs.process-result.outputs.codeowners }}
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.ACTION_MONITORING_SLACK }}
|
||||
|
||||
report-success:
|
||||
if: ${{ success() && github.repository_owner == 'nrwl' && github.event_name != 'workflow_dispatch' }}
|
||||
needs: e2e
|
||||
runs-on: ubuntu-latest
|
||||
name: Report success
|
||||
steps:
|
||||
- name: Send notification
|
||||
uses: ravsamhq/notify-slack-action@v2
|
||||
with:
|
||||
status: ${{ needs.e2e.result }}
|
||||
message_format: '{emoji} Workflow has {status_message}'
|
||||
notification_title: '{workflow}'
|
||||
footer: '<{run_url}|View Run> / Last commit <{commit_url}|{commit_sha}>'
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.ACTION_MONITORING_SLACK }}
|
||||
@@ -10,22 +10,22 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: ['20.19.0']
|
||||
|
||||
node-version: [18]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '20.19.0'
|
||||
node-version: 18
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@7088e561eb65bb68695d245aa206f005ef30921d # v4.1.0
|
||||
uses: pnpm/action-setup@v2
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 10.11.1
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Setup pnpm cache
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
@@ -46,8 +46,8 @@ jobs:
|
||||
run: pnpm install --no-frozen-lockfile
|
||||
|
||||
- name: Run embeddings script
|
||||
run: pnpm exec nx run tools-documentation-create-embeddings:run-node
|
||||
run: pnpm exec nx run tools-documentation-create-embeddings:run-node
|
||||
env:
|
||||
NX_NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NX_NEXT_PUBLIC_SUPABASE_URL }}
|
||||
NX_SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.NX_SUPABASE_SERVICE_ROLE_KEY }}
|
||||
NX_OPENAI_KEY: ${{ secrets.NX_OPENAI_KEY }}
|
||||
NX_OPENAI_KEY: ${{ secrets.NX_OPENAI_KEY }}
|
||||
@@ -16,21 +16,21 @@ jobs:
|
||||
name: Report status
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- uses: pnpm/action-setup@7088e561eb65bb68695d245aa206f005ef30921d # v4.1.0
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: 10.11.1
|
||||
version: 8.2
|
||||
|
||||
- name: Use Node.js ${{ matrix.node_version }}
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '20.19.0'
|
||||
node-version: '18'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Cache node_modules
|
||||
id: cache-modules
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
lookup-only: true
|
||||
path: '**/node_modules'
|
||||
@@ -41,28 +41,27 @@ jobs:
|
||||
|
||||
- name: Download artifact
|
||||
id: download-artifact
|
||||
uses: dawidd6/action-download-artifact@268677152d06ba59fcec7a7f0b5d961b6ccd7e1e # v2 # Needed since we are downloading artifact from a different workflow run, official actions/download-artifact doesn't support this.
|
||||
uses: dawidd6/action-download-artifact@v2 # Needed since we are downloading artifact from a different workflow run, official actions/download-artifact doesn't support this.
|
||||
with:
|
||||
name: cached-issue-data
|
||||
path: ${{ github.workspace }}/scripts/issues-scraper/cached
|
||||
search_artifacts: true
|
||||
allow_forks: false
|
||||
continue-on-error: true
|
||||
|
||||
- name: Collect Issue Data
|
||||
id: collect
|
||||
run: npx tsx ./scripts/issues-scraper/index.ts
|
||||
run: npx ts-node ./scripts/issues-scraper/index.ts
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
|
||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: cached-issue-data
|
||||
path: ./scripts/issues-scraper/cached/data.json
|
||||
|
||||
- name: Send GitHub Action trigger data to Slack workflow
|
||||
id: slack
|
||||
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1
|
||||
uses: slackapi/slack-github-action@v1.23.0
|
||||
with:
|
||||
payload: ${{ steps.collect.outputs.SLACK_MESSAGE }}
|
||||
env:
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
if: ${{ github.repository_owner == 'nrwl' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@7de207be1d3ce97a9abe6ff1306222982d1ca9f9 # v5.0.1
|
||||
- uses: dessant/lock-threads@v4
|
||||
id: lockthreads
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
type MatrixDataProject = {
|
||||
name: string,
|
||||
codeowners: string,
|
||||
is_golden?: boolean, // true if this is a golden project, false otherwise
|
||||
};
|
||||
|
||||
type MatrixDataOS = {
|
||||
os: string, // GH runner machine name: e.g. ubuntu-latest
|
||||
os_name: string, // short name that will be printed in the report and on the action
|
||||
os_timeout: number, // 60
|
||||
package_managers: string[], // package managers to run on this OS
|
||||
node_versions: Array<number | string>, // node versions to run on this OS
|
||||
excluded?: string[], // projects to exclude from running on this OS
|
||||
};
|
||||
|
||||
type MatrixData = {
|
||||
coreProjects: MatrixDataProject[],
|
||||
projects: MatrixDataProject[],
|
||||
nodeTLS: number,
|
||||
setup: MatrixDataOS[],
|
||||
}
|
||||
|
||||
export type MatrixItem = {
|
||||
project: string,
|
||||
codeowners: string,
|
||||
node_version: number | string,
|
||||
package_manager: string,
|
||||
os: string,
|
||||
os_name: string,
|
||||
os_timeout: number,
|
||||
is_golden?: boolean,
|
||||
};
|
||||
|
||||
// TODO: Extract Slack groups into named groups for easier maintenance
|
||||
const matrixData: MatrixData = {
|
||||
coreProjects: [
|
||||
{ name: 'e2e-lerna-smoke-tests', codeowners: 'S04TNCVEETS', is_golden: true },
|
||||
{ name: 'e2e-js', codeowners: 'S04SJ6HHP0X', is_golden: true },
|
||||
{ name: 'e2e-nx-init', codeowners: 'S04SYHYKGNP', is_golden: true },
|
||||
{ name: 'e2e-nx', codeowners: 'S04SYHYKGNP' },
|
||||
{ name: 'e2e-release', codeowners: 'S04SYHYKGNP' },
|
||||
{ name: 'e2e-workspace-create', codeowners: 'S04SYHYKGNP' }
|
||||
],
|
||||
projects: [
|
||||
{ name: 'e2e-cypress', codeowners: 'S04T16BTJJY', is_golden: true },
|
||||
{ name: 'e2e-docker', codeowners: 'S04SJ6HHP0X', is_golden: true },
|
||||
{ name: 'e2e-detox', codeowners: 'S04TNCNJG5N', is_golden: true },
|
||||
{ name: 'e2e-esbuild', codeowners: 'S04SJ6HHP0X', is_golden: true },
|
||||
{ name: 'e2e-gradle', codeowners: 'S04TNCNJG5N', is_golden: true },
|
||||
{ name: 'e2e-eslint', codeowners: 'S04SYJGKSCT', is_golden: true },
|
||||
{ name: 'e2e-node', codeowners: 'S04SJ6HHP0X', is_golden: true },
|
||||
{ name: 'e2e-playwright', codeowners: 'S04SVQ8H0G5', is_golden: true },
|
||||
{ name: 'e2e-remix', codeowners: 'S04SVQ8H0G5', is_golden: true },
|
||||
{ name: 'e2e-rspack', codeowners: 'S04SJ6HHP0X', is_golden: true },
|
||||
{ name: 'e2e-vite', codeowners: 'S04SJ6PL98X', is_golden: true },
|
||||
{ name: 'e2e-vue', codeowners: 'S04SJ6PL98X', is_golden: true },
|
||||
{ name: 'e2e-web', codeowners: 'S04SJ6PL98X', is_golden: true },
|
||||
{ name: 'e2e-webpack', codeowners: 'S04SJ6PL98X', is_golden: true },
|
||||
{ name: 'e2e-jest', codeowners: 'S04T16BTJJY', is_golden: true },
|
||||
{ name: 'e2e-expo', codeowners: 'S04TNCNJG5N', is_golden: true },
|
||||
{ name: 'e2e-react-native', codeowners: 'S04TNCNJG5N', is_golden: true },
|
||||
{ name: 'e2e-angular', codeowners: 'S04SS457V38' },
|
||||
{ name: 'e2e-next', codeowners: 'S04TNCNJG5N' },
|
||||
{ name: 'e2e-plugin', codeowners: 'S04SYHYKGNP' },
|
||||
{ name: 'e2e-react', codeowners: 'S04TNCNJG5N' },
|
||||
{ name: 'e2e-rollup', codeowners: 'S04SJ6PL98X' },
|
||||
{ name: 'e2e-storybook', codeowners: 'S04SVQ8H0G5' },
|
||||
{ name: 'e2e-nuxt', codeowners: 'S04SJ6PL98X' }
|
||||
],
|
||||
nodeTLS: 20,
|
||||
setup: [
|
||||
{
|
||||
os: 'ubuntu-latest',
|
||||
os_name: 'Linux',
|
||||
os_timeout: 60,
|
||||
package_managers: ['npm', 'pnpm', 'yarn'],
|
||||
node_versions: ['20.19.0', '22.12.0'],
|
||||
excluded: ['e2e-detox', 'e2e-react-native', 'e2e-expo']
|
||||
},
|
||||
{ os: 'macos-latest', os_name: 'MacOS', os_timeout: 90, package_managers: ['npm'], node_versions: ['20.19.0'] }
|
||||
// TODO (emily): Fix Windows support as gradle fails when running nx build https://staging.nx.app/runs/LgD4vxGn8w?utm_source=pull-request&utm_medium=comment
|
||||
// { os: 'windows-latest', os_name: 'WinOS', os_timeout: 180, package_managers: ['npm'], node_versions: ['20.19.0'], excluded: ['e2e-detox', 'e2e-react-native', 'e2e-expo'] }
|
||||
]
|
||||
};
|
||||
|
||||
const matrix: Array<MatrixItem> = [];
|
||||
|
||||
function addMatrixCombo(project: MatrixDataProject, nodeVersion: number | string, pm: number, os: number) {
|
||||
matrix.push({
|
||||
project: project.name,
|
||||
codeowners: project.codeowners,
|
||||
node_version: nodeVersion,
|
||||
package_manager: matrixData.setup[os].package_managers[pm],
|
||||
os: matrixData.setup[os].os,
|
||||
os_name: matrixData.setup[os].os_name,
|
||||
os_timeout: matrixData.setup[os].os_timeout,
|
||||
is_golden: !!project.is_golden // Mark golden projects as true, others as false
|
||||
});
|
||||
}
|
||||
|
||||
function processProject(project: MatrixDataProject, nodeVersion?: number) {
|
||||
for (let os = 0; os < matrixData.setup.length; os++) {
|
||||
for (let pm = 0; pm < matrixData.setup[os].package_managers.length; pm++) {
|
||||
if (!matrixData.setup[os].excluded || !matrixData.setup[os].excluded?.includes(project.name)) {
|
||||
if (nodeVersion) {
|
||||
addMatrixCombo(project, nodeVersion, pm, os);
|
||||
} else {
|
||||
for (let n = 0; n < matrixData.setup[os].node_versions.length; n++) {
|
||||
addMatrixCombo(project, matrixData.setup[os].node_versions[n], pm, os);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// process core projects
|
||||
for (let p = 0; p < matrixData.coreProjects.length; p++) {
|
||||
processProject(matrixData.coreProjects[p]);
|
||||
}
|
||||
// process other projects
|
||||
for (let p = 0; p < matrixData.projects.length; p++) {
|
||||
processProject(matrixData.projects[p], matrixData.nodeTLS);
|
||||
}
|
||||
|
||||
if (matrix.length > 256) {
|
||||
throw new Error('You have exceeded the size of the matrix. GitHub allows only 256 jobs in a matrix. Found ${matrix.length} jobs.');
|
||||
}
|
||||
|
||||
// print result to stdout for pipeline to consume
|
||||
process.stdout.write(JSON.stringify({ include: matrix }, null, 0));
|
||||
@@ -1,197 +0,0 @@
|
||||
import * as fs from 'fs';
|
||||
import { MatrixItem } from './process-matrix';
|
||||
|
||||
interface MatrixResult extends MatrixItem {
|
||||
status: 'success' | 'failure' | 'cancelled';
|
||||
duration: number;
|
||||
}
|
||||
|
||||
interface ProcessedResults {
|
||||
codeowners: string;
|
||||
slack_message: string;
|
||||
slack_proj_duration: string;
|
||||
slack_pm_duration: string;
|
||||
has_golden_failures: string;
|
||||
}
|
||||
|
||||
function trimSpace(res: string): string {
|
||||
return res.split('\n').map((l) => l.trim()).join('\n');
|
||||
}
|
||||
|
||||
function humanizeDuration(num: number): string {
|
||||
let res = '';
|
||||
const hours = Math.floor(num / 3600);
|
||||
if (hours) res += `${hours}h `;
|
||||
const mins = Math.floor((num % 3600) / 60);
|
||||
if (mins) res += `${mins}m `;
|
||||
const sec = num % 60;
|
||||
if (sec) res += `${sec}s`;
|
||||
return res;
|
||||
}
|
||||
|
||||
function processResults(combined: MatrixResult[]): ProcessedResults {
|
||||
const failedProjects = combined.filter(c => c.status === 'failure' || c.status === 'cancelled').sort((a, b) => a.project.localeCompare(b.project));
|
||||
const failedGoldenProjects = failedProjects.filter(c => c.is_golden);
|
||||
const hasGoldenFailures = failedGoldenProjects.length > 0;
|
||||
const codeowners = new Set<string>();
|
||||
failedGoldenProjects.forEach(c => codeowners.add(c.codeowners));
|
||||
|
||||
let result = '';
|
||||
|
||||
const allGoldenProjects = combined.filter(c => c.is_golden);
|
||||
const uniqueGoldenProjects = new Set(allGoldenProjects.map(c => c.project));
|
||||
const uniqueFailedGoldenProjects = new Set(failedGoldenProjects.map(c => c.project));
|
||||
const goldenPassingCount = uniqueGoldenProjects.size - uniqueFailedGoldenProjects.size;
|
||||
const goldenFailingCount = uniqueFailedGoldenProjects.size;
|
||||
|
||||
const allOtherProjects = combined.filter(c => !c.is_golden);
|
||||
const uniqueOtherProjects = new Set(allOtherProjects.map(c => c.project));
|
||||
const failedRegularProjects = failedProjects.filter(c => !c.is_golden);
|
||||
const uniqueFailedOtherProjects = new Set(failedRegularProjects.map(c => c.project));
|
||||
const otherPassingCount = uniqueOtherProjects.size - uniqueFailedOtherProjects.size;
|
||||
const otherFailingCount = uniqueFailedOtherProjects.size;
|
||||
|
||||
result += `\n🌟 *Golden Projects*`;
|
||||
result += `\n✅ Passing: ${goldenPassingCount}`;
|
||||
result += `\n❌ Failing: ${goldenFailingCount}`;
|
||||
|
||||
if (failedGoldenProjects.length > 0) {
|
||||
result += `\n\n🚨 *Failed Golden Projects*\n\`\`\``;
|
||||
result += `\n| Failed project |`;
|
||||
result += `\n|--------------------------------|`;
|
||||
let lastProject: string | undefined;
|
||||
failedGoldenProjects.forEach(matrix => {
|
||||
const project = matrix.project !== lastProject ? matrix.project : '';
|
||||
if (project) {
|
||||
result += `\n| ${project.padEnd(30)} |`;
|
||||
lastProject = matrix.project;
|
||||
}
|
||||
});
|
||||
result += `\n\`\`\``;
|
||||
}
|
||||
|
||||
result += `\n\n🔧 *Other Projects*`;
|
||||
result += `\n✅ Passing: ${otherPassingCount}`;
|
||||
result += `\n❌ Failing: ${otherFailingCount}`;
|
||||
|
||||
// Failed Other Projects Table (if any)
|
||||
if (failedRegularProjects.length > 0) {
|
||||
result += `\n\n⚠️ *Failed Other Projects*\n\`\`\``;
|
||||
result += `\n| Failed project |`;
|
||||
result += `\n|--------------------------------|`;
|
||||
let lastProject: string | undefined;
|
||||
failedRegularProjects.forEach(matrix => {
|
||||
const project = matrix.project !== lastProject ? matrix.project : '';
|
||||
if (project) {
|
||||
result += `\n| ${project.padEnd(30)} |`;
|
||||
lastProject = matrix.project;
|
||||
}
|
||||
});
|
||||
result += `\n\`\`\``;
|
||||
}
|
||||
|
||||
if (failedProjects.length === 0) {
|
||||
result = '🎉 *No test failures detected!* All systems green! 🟢';
|
||||
}
|
||||
|
||||
const timeReport: Record<string, { min: number; max: number; minEnv: string; maxEnv: string }> = {};
|
||||
const pmReport = { npm: 0, yarn: 0, pnpm: 0 };
|
||||
const macosProjects = ['e2e-detox', 'e2e-expo', 'e2e-react-native'];
|
||||
|
||||
combined.forEach(matrix => {
|
||||
const nodeVersion = parseInt(matrix.node_version.toString());
|
||||
if (matrix.os_name === 'Linux' && nodeVersion === 20 && matrix.package_manager in pmReport) {
|
||||
pmReport[matrix.package_manager as keyof typeof pmReport] += matrix.duration;
|
||||
}
|
||||
if (matrix.os_name === 'Linux' || macosProjects.includes(matrix.project)) {
|
||||
if (timeReport[matrix.project]) {
|
||||
if (matrix.duration > timeReport[matrix.project].max) {
|
||||
timeReport[matrix.project].max = matrix.duration;
|
||||
timeReport[matrix.project].maxEnv = `${matrix.os_name}, ${matrix.package_manager}`;
|
||||
}
|
||||
if (matrix.duration < timeReport[matrix.project].min) {
|
||||
timeReport[matrix.project].min = matrix.duration;
|
||||
timeReport[matrix.project].minEnv = `${matrix.os_name}, ${matrix.package_manager}`;
|
||||
}
|
||||
} else {
|
||||
timeReport[matrix.project] = {
|
||||
min: matrix.duration,
|
||||
max: matrix.duration,
|
||||
minEnv: `${matrix.os_name}, ${matrix.package_manager}`,
|
||||
maxEnv: `${matrix.os_name}, ${matrix.package_manager}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let resultPkg = `
|
||||
\`\`\`
|
||||
| Project | Time |
|
||||
|--------------------------------|---------------------------|`;
|
||||
|
||||
function mapProjectTime(proj: string, section: 'min' | 'max'): string {
|
||||
return `${humanizeDuration(timeReport[proj][section])} (${timeReport[proj][`${section}Env`]})`;
|
||||
}
|
||||
|
||||
function durationIcon(proj: string, section: 'min' | 'max'): string {
|
||||
const duration = timeReport[proj][section];
|
||||
if (duration < 12 * 60) return `${section} ✅`;
|
||||
if (duration < 15 * 60) return `${section} ❗`;
|
||||
return `${section} ❌`;
|
||||
}
|
||||
|
||||
Object.keys(timeReport).forEach(proj => {
|
||||
resultPkg += `\n| ${proj.padEnd(30)} | |`;
|
||||
resultPkg += `\n| ${durationIcon(proj, 'min').padStart(29)} | ${mapProjectTime(proj, 'min').padEnd(25)} |`;
|
||||
resultPkg += `\n| ${durationIcon(proj, 'max').padStart(29)} | ${mapProjectTime(proj, 'max').padEnd(25)} |`;
|
||||
});
|
||||
resultPkg += `\`\`\``;
|
||||
|
||||
let resultPm = `
|
||||
\`\`\`
|
||||
| PM | Total time |
|
||||
|------|-------------|`;
|
||||
Object.keys(pmReport).forEach(pm => {
|
||||
resultPm += `\n| ${pm.padEnd(4)} | ${humanizeDuration(pmReport[pm as keyof typeof pmReport]).padEnd(11)} |`;
|
||||
});
|
||||
resultPm += `\`\`\``;
|
||||
|
||||
return {
|
||||
codeowners: Array.from(codeowners).join(','),
|
||||
slack_message: trimSpace(result),
|
||||
slack_proj_duration: trimSpace(resultPkg),
|
||||
slack_pm_duration: trimSpace(resultPm),
|
||||
has_golden_failures: hasGoldenFailures.toString(),
|
||||
};
|
||||
}
|
||||
|
||||
function setOutput(key: string, value: string) {
|
||||
const outputPath = process.env.GITHUB_OUTPUT;
|
||||
if (!outputPath) {
|
||||
console.warn(`GITHUB_OUTPUT not set. Skipping output for "${key}".`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.includes('\n')) {
|
||||
const delimiter = `EOF_${key}_${Date.now()}`;
|
||||
fs.appendFileSync(outputPath, `${key}<<${delimiter}\n${value}\n${delimiter}\n`);
|
||||
} else {
|
||||
fs.appendFileSync(outputPath, `${key}=${value}\n`);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const combinedInput = process.argv[2]
|
||||
? process.argv[2]
|
||||
: fs.readFileSync(0, 'utf-8').trim();
|
||||
|
||||
const combined: MatrixResult[] = JSON.parse(combinedInput);
|
||||
const results = processResults(combined);
|
||||
|
||||
Object.entries(results).forEach(([key, value]) => {
|
||||
setOutput(key, value);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error processing results:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
@@ -8,21 +8,25 @@ on:
|
||||
permissions: {}
|
||||
jobs:
|
||||
audit:
|
||||
if: ${{ github.repository_owner == 'nrwl' }}
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- uses: pnpm/action-setup@7088e561eb65bb68695d245aa206f005ef30921d # v4.1.0
|
||||
with:
|
||||
version: 10.11.1 # Aligned with root package.json (pnpm/action-setup will helpfully error if out of sync)
|
||||
- name: Install PNPM
|
||||
run: |
|
||||
npm install -g @pnpm/exe@8.3.1
|
||||
|
||||
- name: Run a security audit
|
||||
run: pnpm dlx audit-ci --critical --report-type summary
|
||||
|
||||
# - name: Run Dependency confusion supply chain check
|
||||
# run: npx snync -d .
|
||||
|
||||
report:
|
||||
if: ${{ always() && github.repository_owner == 'nrwl' && github.event_name != 'workflow_dispatch' }}
|
||||
needs: audit
|
||||
@@ -30,7 +34,7 @@ jobs:
|
||||
name: Report status
|
||||
steps:
|
||||
- name: Send notification
|
||||
uses: ravsamhq/notify-slack-action@be814b201e233b2dc673608aa46e5447c8ab13f2 # v11
|
||||
uses: ravsamhq/notify-slack-action@v2
|
||||
with:
|
||||
status: ${{ needs.audit.result }}
|
||||
message_format: '{emoji} Audit has {status_message}'
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
name: PR Title Validation
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, edited, synchronize, reopened]
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
validate-pr-title:
|
||||
name: Validate PR Title
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
# Ensure's validate-pr-title.js is the copy from master
|
||||
ref: master
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: 20
|
||||
package-manager-cache: false
|
||||
|
||||
- name: Validate PR title
|
||||
env:
|
||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||
PR_BODY: ${{ github.event.pull_request.body }}
|
||||
run: node ./scripts/validate-pr-title.js
|
||||
@@ -1,140 +1,25 @@
|
||||
name: publish
|
||||
|
||||
on:
|
||||
# Automated schedule - canary releases from master
|
||||
schedule:
|
||||
- cron: "0 20 * * 1-5" # Monday - Friday, at 20:00 UTC (8pm UTC)
|
||||
# Manual trigger - PR releases or dry-runs (based on workflow inputs)
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
pr:
|
||||
description: "PR Number - If set, a real release will be created for the branch associated with the given PR number. If blank, a dry-run of the currently selected branch will be performed."
|
||||
required: false
|
||||
type: number
|
||||
release:
|
||||
types: [ published ]
|
||||
|
||||
# Dynamically generate the display name for the GitHub UI based on the event type and inputs
|
||||
run-name: ${{ github.event.inputs.pr && format('PR Release for {0}', github.event.inputs.pr) || github.event_name == 'schedule' && 'Canary Release' || github.event_name == 'workflow_dispatch' && !github.event.inputs.pr && 'Release Dry-Run' || github.ref_name }}
|
||||
|
||||
env:
|
||||
DEBUG: napi:*
|
||||
NX_RUN_GROUP: ${{ github.run_id }}-${{ github.run_attempt }}
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
NODE_VERSION: 22.16.0
|
||||
PNPM_VERSION: 10.11.1 # Aligned with root package.json (pnpm/action-setup will helpfully error if out of sync)
|
||||
|
||||
NPM_CONFIG_PROVENANCE: true
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [published]
|
||||
jobs:
|
||||
# We first need to determine the version we are releasing, and if we need a custom repo or ref to use for the git checkout in subsequent steps.
|
||||
# These values depend upon the event type that triggered the workflow:
|
||||
#
|
||||
# - schedule:
|
||||
# - We are running a canary release which always comes from the master branch, we can use default ref resolution
|
||||
# in actions/checkout. The exact version will be generated within scripts/nx-release.ts.
|
||||
#
|
||||
# - release:
|
||||
# - We are running a full release which is based on the tag that triggered the release event, we can use default
|
||||
# ref resolution in actions/checkout. The exact version will be generated within scripts/nx-release.ts.
|
||||
#
|
||||
# - workflow_dispatch:
|
||||
# - We are either running a dry-run on the current branch, in which case the version will be static and we can use
|
||||
# default ref resolution in actions/checkout, or we are creating a PR release for the given PR number, in which case
|
||||
# we should generate an applicable version number within publish-resolve-data.js and use a custom ref of the PR branch name.
|
||||
resolve-required-data:
|
||||
name: Resolve Required Data
|
||||
if: ${{ github.repository_owner == 'nrwl' }}
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.script.outputs.version }}
|
||||
dry_run_flag: ${{ steps.script.outputs.dry_run_flag }}
|
||||
success_comment: ${{ steps.script.outputs.success_comment }}
|
||||
publish_branch: ${{ steps.script.outputs.publish_branch }}
|
||||
ref: ${{ steps.script.outputs.ref }}
|
||||
repo: ${{ steps.script.outputs.repo }}
|
||||
pr_number: ${{ steps.script.outputs.pr_number }}
|
||||
pr_author: ${{ steps.script.outputs.pr_author }}
|
||||
steps:
|
||||
# Default checkout on the triggering branch so that the latest publish-resolve-data.js script is available
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
check-latest: true
|
||||
package-manager-cache: false
|
||||
|
||||
- name: Resolve and set checkout and version data to use for release
|
||||
id: script
|
||||
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event.inputs.pr }}
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const script = require('${{ github.workspace }}/scripts/publish-resolve-data.js');
|
||||
await script({ github, context, core });
|
||||
|
||||
- name: (PR Release Only) Check out latest master
|
||||
if: ${{ steps.script.outputs.ref != '' }}
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
# Check out the latest master branch to get its copy of nx-release.ts
|
||||
repository: nrwl/nx
|
||||
ref: master
|
||||
path: latest-master-checkout
|
||||
|
||||
- name: (PR Release Only) Check out PR branch
|
||||
if: ${{ steps.script.outputs.ref != '' }}
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
# Check out the PR branch to get its copy of nx-release.ts
|
||||
repository: ${{ steps.script.outputs.repo }}
|
||||
ref: ${{ steps.script.outputs.ref }}
|
||||
path: pr-branch-checkout
|
||||
|
||||
- name: (PR Release Only) Ensure that release scripts have not changed in the PR being released
|
||||
if: ${{ steps.script.outputs.ref != '' }}
|
||||
run: |
|
||||
# List of files that must not change in PR releases
|
||||
FILES_TO_CHECK=(
|
||||
"scripts/nx-release.ts"
|
||||
"scripts/publish-resolve-data.js"
|
||||
)
|
||||
|
||||
for FILE in "${FILES_TO_CHECK[@]}"; do
|
||||
if ! cmp -s "latest-master-checkout/$FILE" "pr-branch-checkout/$FILE"; then
|
||||
echo "🛑 Error: The file $FILE is different on the ${{ steps.script.outputs.ref }} branch on ${{ steps.script.outputs.repo }} vs latest master on nrwl/nx, cancelling workflow."
|
||||
echo "If you did not modify the file, then you likely just need to rebase/merge latest master."
|
||||
exit 1
|
||||
else
|
||||
echo "✅ The file $FILE is identical between the ${{ steps.script.outputs.ref }} branch on ${{ steps.script.outputs.repo }} and latest master on nrwl/nx."
|
||||
fi
|
||||
done
|
||||
|
||||
build:
|
||||
needs: [ resolve-required-data ]
|
||||
if: ${{ github.repository_owner == 'nrwl' }}
|
||||
if: "!contains(github.event.head_commit.message, 'skip ci')"
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
settings:
|
||||
- host: macos-13
|
||||
- host: macos-latest
|
||||
target: x86_64-apple-darwin
|
||||
setup: |-
|
||||
rustup target add aarch64-apple-darwin
|
||||
build: |
|
||||
pnpm nx run-many --target=build-native -- --target=x86_64-apple-darwin
|
||||
- host: windows-latest
|
||||
setup: |-
|
||||
choco install openjdk --version=21.0.0 -y
|
||||
rustup target add aarch64-pc-windows-msvc
|
||||
build: |
|
||||
export JAVA_HOME="C:\Program Files\OpenJDK\jdk-21"
|
||||
export PATH="$JAVA_HOME\bin:$PATH"
|
||||
java -version
|
||||
pnpm nx run-many --target=build-native -- --target=x86_64-pc-windows-msvc
|
||||
build: pnpm nx run-many --target=build-native -- --target=x86_64-pc-windows-msvc
|
||||
target: x86_64-pc-windows-msvc
|
||||
# Windows 32bit (not needed)
|
||||
# - host: windows-latest
|
||||
@@ -144,65 +29,16 @@ jobs:
|
||||
- host: ubuntu-latest
|
||||
target: x86_64-unknown-linux-gnu
|
||||
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian
|
||||
build: |
|
||||
set -e
|
||||
apt-get update
|
||||
|
||||
# Install Java 21
|
||||
apt-get install -y openjdk-21-jdk
|
||||
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
|
||||
export PATH="$JAVA_HOME/bin:$PATH"
|
||||
java --version
|
||||
|
||||
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
|
||||
apt-get install -y nodejs=22.16.0-1nodesource1
|
||||
|
||||
export PATH="/usr/local/bin:$PATH"
|
||||
node --version
|
||||
npm --version
|
||||
|
||||
npm i -g pnpm@${PNPM_VERSION} --force
|
||||
pnpm --version
|
||||
|
||||
pnpm install --frozen-lockfile
|
||||
rustup target add x86_64-unknown-linux-gnu
|
||||
pnpm nx run-many --verbose --target=build-native -- --target=x86_64-unknown-linux-gnu
|
||||
build: |-
|
||||
set -e &&
|
||||
pnpm --version &&
|
||||
pnpm nx run-many --target=build-native -- --target=x86_64-unknown-linux-gnu
|
||||
- host: ubuntu-latest
|
||||
target: x86_64-unknown-linux-musl
|
||||
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
|
||||
build: |
|
||||
bash -c "
|
||||
set -e
|
||||
echo 'https://dl-cdn.alpinelinux.org/alpine/edge/community' >> /etc/apk/repositories
|
||||
apk add --no-cache curl xz openjdk21
|
||||
|
||||
# Set up Java 21
|
||||
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
|
||||
export PATH=\"\$JAVA_HOME/bin:\$PATH\"
|
||||
java --version
|
||||
|
||||
curl -fsSL https://unofficial-builds.nodejs.org/download/release/v22.16.0/node-v22.16.0-linux-x64-musl.tar.xz -o node.tar.xz
|
||||
tar -xJf node.tar.xz
|
||||
mv node-v22.16.0-linux-x64-musl /usr/local/node
|
||||
|
||||
export PATH=\"/usr/local/node/bin:\$PATH\"
|
||||
|
||||
echo Node: \$(node -v)
|
||||
echo NPM: \$(npm -v)
|
||||
|
||||
# Install PNPM
|
||||
npm i -g pnpm@${PNPM_VERSION} --force
|
||||
pnpm --version
|
||||
|
||||
# Install deps and run native build
|
||||
pnpm install --frozen-lockfile
|
||||
rustup target add x86_64-unknown-linux-musl
|
||||
pnpm nx run-many --verbose --target=build-native -- --target=x86_64-unknown-linux-musl
|
||||
"
|
||||
- host: macos-13
|
||||
build: set -e && pnpm nx run-many --target=build-native -- --target=x86_64-unknown-linux-musl
|
||||
- host: macos-latest
|
||||
target: aarch64-apple-darwin
|
||||
setup: |-
|
||||
rustup target add aarch64-apple-darwin
|
||||
build: |
|
||||
sudo rm -Rf /Library/Developer/CommandLineTools/SDKs/*;
|
||||
export CC=$(xcrun -f clang);
|
||||
@@ -213,37 +49,17 @@ jobs:
|
||||
- host: ubuntu-latest
|
||||
target: aarch64-unknown-linux-gnu
|
||||
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64
|
||||
build: |
|
||||
set -e
|
||||
apt-get update
|
||||
|
||||
# Install Java 21
|
||||
apt-get install -y openjdk-21-jdk
|
||||
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
|
||||
export PATH="$JAVA_HOME/bin:$PATH"
|
||||
java --version
|
||||
|
||||
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
|
||||
apt-get install -y nodejs=22.16.0-1nodesource1
|
||||
|
||||
export PATH="/usr/local/bin:$PATH"
|
||||
node --version
|
||||
npm --version
|
||||
|
||||
npm i -g pnpm@${PNPM_VERSION} --force
|
||||
pnpm --version
|
||||
|
||||
pnpm install --frozen-lockfile
|
||||
rustup target add aarch64-unknown-linux-gnu
|
||||
pnpm nx run-many --verbose --target=build-native -- --target=aarch64-unknown-linux-gnu
|
||||
build: |-
|
||||
set -e &&
|
||||
pnpm --version &&
|
||||
pnpm nx run-many --target=build-native -- --target=aarch64-unknown-linux-gnu
|
||||
- host: ubuntu-latest
|
||||
target: armv7-unknown-linux-gnueabihf
|
||||
setup: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install gcc-arm-linux-gnueabihf -y
|
||||
rustup target add armv7-unknown-linux-gnueabihf
|
||||
build: |
|
||||
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=/usr/bin/arm-linux-gnueabihf-gcc pnpm nx run-many --target=build-native -- --target=armv7-unknown-linux-gnueabihf
|
||||
pnpm nx run-many --target=build-native -- --target=armv7-unknown-linux-gnueabihf
|
||||
# Android (not needed)
|
||||
# - host: ubuntu-latest
|
||||
# target: aarch64-linux-android
|
||||
@@ -256,74 +72,38 @@ jobs:
|
||||
- host: ubuntu-latest
|
||||
target: aarch64-unknown-linux-musl
|
||||
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
|
||||
build: |
|
||||
bash -c "
|
||||
set -e
|
||||
echo 'https://dl-cdn.alpinelinux.org/alpine/edge/community' >> /etc/apk/repositories
|
||||
apk add --no-cache curl xz openjdk21
|
||||
|
||||
# Set up Java 21
|
||||
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
|
||||
export PATH=\"\$JAVA_HOME/bin:\$PATH\"
|
||||
java --version
|
||||
|
||||
curl -fsSL https://unofficial-builds.nodejs.org/download/release/v22.16.0/node-v22.16.0-linux-x64-musl.tar.xz -o node.tar.xz
|
||||
tar -xJf node.tar.xz
|
||||
mv node-v22.16.0-linux-x64-musl /usr/local/node
|
||||
|
||||
export PATH=\"/usr/local/node/bin:\$PATH\"
|
||||
|
||||
echo Node: \$(node -v)
|
||||
echo NPM: \$(npm -v)
|
||||
|
||||
# Install PNPM
|
||||
npm i -g pnpm@${PNPM_VERSION} --force
|
||||
pnpm --version
|
||||
|
||||
# Install deps and run native build
|
||||
pnpm install --frozen-lockfile
|
||||
rustup target add aarch64-unknown-linux-musl
|
||||
pnpm nx run-many --verbose --target=build-native -- --target=aarch64-unknown-linux-musl
|
||||
"
|
||||
build: |-
|
||||
set -e &&
|
||||
rustup target add aarch64-unknown-linux-musl &&
|
||||
pnpm nx run-many --target=build-native -- --target=aarch64-unknown-linux-musl
|
||||
- host: windows-latest
|
||||
target: aarch64-pc-windows-msvc
|
||||
setup: |-
|
||||
choco install openjdk --version=21.0.0 -y
|
||||
rustup target add aarch64-pc-windows-msvc
|
||||
build: |
|
||||
export JAVA_HOME="C:\Program Files\OpenJDK\jdk-21"
|
||||
export PATH="$JAVA_HOME\bin:$PATH"
|
||||
java -version
|
||||
pnpm nx run-many --target=build-native -- --target=aarch64-pc-windows-msvc
|
||||
name: stable - ${{ matrix.settings.target }} - node@22.16.0
|
||||
build: pnpm nx run-many --target=build-native -- --target=aarch64-pc-windows-msvc
|
||||
name: stable - ${{ matrix.settings.target }} - node@18
|
||||
runs-on: ${{ matrix.settings.host }}
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
repository: ${{ needs.resolve-required-data.outputs.repo || github.repository }}
|
||||
ref: ${{ needs.resolve-required-data.outputs.ref || github.ref }}
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: pnpm/action-setup@7088e561eb65bb68695d245aa206f005ef30921d # v4.1.0
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
version: 8.2
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
uses: actions/setup-node@v3
|
||||
if: ${{ !matrix.settings.docker }}
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
node-version: 18
|
||||
check-latest: true
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install
|
||||
uses: actions-rust-lang/setup-rust-toolchain@ac90e63697ac2784f4ecfe2964e1a285c304003a # v1
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
if: ${{ !matrix.settings.docker }}
|
||||
with:
|
||||
target: ${{ matrix.settings.target }}
|
||||
rustflags: ''
|
||||
targets: ${{ matrix.settings.target }}
|
||||
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry/index/
|
||||
@@ -332,321 +112,128 @@ jobs:
|
||||
.cargo-cache
|
||||
target/
|
||||
key: ${{ matrix.settings.target }}-cargo-registry
|
||||
|
||||
- uses: goto-bus-stop/setup-zig@abea47f85e598557f500fa1fd2ab7464fcb39406 # v2.2.1
|
||||
- uses: goto-bus-stop/setup-zig@v2
|
||||
if: ${{ matrix.settings.target == 'armv7-unknown-linux-gnueabihf' }}
|
||||
with:
|
||||
version: 0.10.0
|
||||
|
||||
- name: Setup toolchain
|
||||
run: ${{ matrix.settings.setup }}
|
||||
if: ${{ matrix.settings.setup }}
|
||||
shell: bash
|
||||
|
||||
- name: Setup node x86
|
||||
if: matrix.settings.target == 'i686-pc-windows-msvc'
|
||||
run: yarn config set supportedArchitectures.cpu "ia32"
|
||||
shell: bash
|
||||
|
||||
- name: Install dependencies
|
||||
if: ${{ !matrix.settings.docker }}
|
||||
run: pnpm install --frozen-lockfile
|
||||
timeout-minutes: 30
|
||||
|
||||
- name: Setup node x86
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
uses: actions/setup-node@v3
|
||||
if: matrix.settings.target == 'i686-pc-windows-msvc'
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
node-version: 18
|
||||
check-latest: true
|
||||
cache: pnpm
|
||||
architecture: x86
|
||||
|
||||
- name: Build in docker
|
||||
uses: addnab/docker-run-action@4f65fabd2431ebc8d299f8e5a018d79a769ae185 # v3
|
||||
uses: addnab/docker-run-action@v3
|
||||
if: ${{ matrix.settings.docker }}
|
||||
with:
|
||||
image: ${{ matrix.settings.docker }}
|
||||
options: --user 0:0 -v ${{ github.workspace }}/.cargo-cache/git/db:/usr/local/cargo/git/db -v ${{ github.workspace }}/.cargo/registry/cache:/usr/local/cargo/registry/cache -v ${{ github.workspace }}/.cargo/registry/index:/usr/local/cargo/registry/index -v ${{ github.workspace }}:/build -w /build
|
||||
run: ${{ matrix.settings.build }}
|
||||
|
||||
- name: Build
|
||||
run: ${{ matrix.settings.build }}
|
||||
if: ${{ !matrix.settings.docker }}
|
||||
shell: bash
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: bindings-${{ matrix.settings.target }}
|
||||
path: |
|
||||
packages/nx/src/native/*.node
|
||||
packages/nx/src/native/*.wasm
|
||||
path: packages/**/*.node
|
||||
if-no-files-found: error
|
||||
|
||||
build-freebsd:
|
||||
needs: [ resolve-required-data ]
|
||||
if: ${{ github.repository_owner == 'nrwl' }}
|
||||
runs-on: ubuntu-latest
|
||||
name: Build FreeBSD
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
repository: ${{ needs.resolve-required-data.outputs.repo || github.repository }}
|
||||
ref: ${{ needs.resolve-required-data.outputs.ref || github.ref }}
|
||||
|
||||
- name: Build
|
||||
id: build
|
||||
uses: cross-platform-actions/action@462ed697694d2ac9aa49e1225f395f7bb6dd49fe # v0.29.0
|
||||
env:
|
||||
DEBUG: napi:*
|
||||
RUSTUP_IO_THREADS: 1
|
||||
NX_PREFER_TS_NODE: true
|
||||
PLAYWRIGHT_BROWSERS_PATH: 0
|
||||
NODE_VERSION: 22.16.0
|
||||
with:
|
||||
operating_system: freebsd
|
||||
version: '14.0'
|
||||
architecture: x86-64
|
||||
environment_variables: DEBUG RUSTUP_IO_THREADS CI NX_PREFER_TS_NODE PLAYWRIGHT_BROWSERS_PATH NODE_VERSION
|
||||
shell: bash
|
||||
run: |
|
||||
env
|
||||
whoami
|
||||
sudo pkg install -y -f node libnghttp2 www/npm git openjdk17
|
||||
sudo npm install --location=global --ignore-scripts pnpm@10.11.1
|
||||
# Set up Java 17
|
||||
export JAVA_HOME=/usr/local/openjdk17
|
||||
export PATH="$JAVA_HOME/bin:$PATH"
|
||||
java --version
|
||||
curl https://sh.rustup.rs -sSf --output rustup.sh
|
||||
sh rustup.sh -y --profile minimal --default-toolchain stable
|
||||
source "$HOME/.cargo/env"
|
||||
echo "~~~~ rustc --version ~~~~"
|
||||
rustc --version
|
||||
echo "~~~~ node -v ~~~~"
|
||||
node -v
|
||||
echo "~~~~ pnpm --version ~~~~"
|
||||
pnpm --version
|
||||
pwd
|
||||
ls -lah
|
||||
whoami
|
||||
env
|
||||
freebsd-version
|
||||
echo "Installing dependencies"
|
||||
pnpm install --frozen-lockfile --ignore-scripts
|
||||
|
||||
echo "Checking disk space before cleanup"
|
||||
df -h
|
||||
echo "Removing unnecessary preinstalled packages"
|
||||
# List all packages first to see what's installed
|
||||
sudo pkg info -a
|
||||
echo "Cleaning up to free disk space"
|
||||
# Clean package caches
|
||||
sudo pkg clean -a -y
|
||||
sudo pkg autoremove -y
|
||||
# Remove unnecessary system files
|
||||
sudo rm -rf /usr/local/lib/*.a
|
||||
sudo rm -rf /usr/local/share/doc/*
|
||||
sudo rm -rf /usr/local/share/man/*
|
||||
sudo rm -rf /usr/local/share/examples/*
|
||||
sudo rm -rf /usr/local/share/locale/*
|
||||
sudo rm -rf /usr/local/share/gtk-doc/*
|
||||
sudo rm -rf /usr/local/share/info/*
|
||||
sudo rm -rf /usr/src/*
|
||||
sudo rm -rf /usr/obj/*
|
||||
sudo rm -rf /usr/tests/*
|
||||
sudo rm -rf /usr/lib/debug/*
|
||||
# Clean var directories
|
||||
sudo rm -rf /var/cache/pkg/*
|
||||
sudo rm -rf /var/db/pkg/*.tbz
|
||||
sudo rm -rf /var/log/*.log
|
||||
sudo rm -rf /var/log/*.old
|
||||
# Clean temporary files
|
||||
sudo rm -rf /tmp/*
|
||||
sudo rm -rf /var/tmp/*
|
||||
# Remove Python cache if present
|
||||
sudo find /usr/local -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
|
||||
sudo find /usr/local -name "*.pyc" -delete 2>/dev/null || true
|
||||
sudo find /usr/local -name "*.pyo" -delete 2>/dev/null || true
|
||||
# Clean npm/pnpm caches
|
||||
npm cache clean --force || true
|
||||
pnpm store prune || true
|
||||
rm -rf ~/.npm || true
|
||||
rm -rf ~/.pnpm-store || true
|
||||
# Remove Rust build artifacts if any
|
||||
rm -rf ~/.cargo/registry || true
|
||||
rm -rf ~/.cargo/git || true
|
||||
rm -rf ~/.rustup/toolchains/*/share || true
|
||||
# Remove other development tool caches
|
||||
rm -rf ~/.cache/* || true
|
||||
echo "Checking disk space after cleanup"
|
||||
df -h
|
||||
|
||||
echo "Building FreeBSD bindings"
|
||||
pnpm nx run-many --verbose --outputStyle stream --target=build-native -- --target=x86_64-unknown-freebsd
|
||||
echo "Cleaning up"
|
||||
pnpm nx reset
|
||||
rm -rf node_modules
|
||||
rm -rf dist
|
||||
echo "KILL ALL NODE PROCESSES"
|
||||
killall node || true
|
||||
echo "COMPLETE"
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: bindings-freebsd
|
||||
path: |
|
||||
packages/nx/src/native/*.node
|
||||
if-no-files-found: error
|
||||
|
||||
runs-on: macos-12
|
||||
name: Build FreeBSD
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build
|
||||
id: build
|
||||
uses: vmactions/freebsd-vm@v0
|
||||
env:
|
||||
DEBUG: napi:*
|
||||
RUSTUP_HOME: /usr/local/rustup
|
||||
CARGO_HOME: /usr/local/cargo
|
||||
RUSTUP_IO_THREADS: 1
|
||||
with:
|
||||
envs: DEBUG RUSTUP_HOME CARGO_HOME RUSTUP_IO_THREADS
|
||||
usesh: true
|
||||
mem: 4096
|
||||
prepare: |
|
||||
pkg install -y -f curl node libnghttp2 npm
|
||||
npm install --location=global --ignore-scripts pnpm
|
||||
curl https://sh.rustup.rs -sSf --output rustup.sh
|
||||
sh rustup.sh -y --profile minimal --default-toolchain stable
|
||||
export PATH="/usr/local/cargo/bin:$PATH"
|
||||
echo "~~~~ rustc --version ~~~~"
|
||||
rustc --version
|
||||
echo "~~~~ node -v ~~~~"
|
||||
node -v
|
||||
echo "~~~~ pnpm --version ~~~~"
|
||||
pnpm --version
|
||||
run: |
|
||||
export PATH="/usr/local/cargo/bin:$PATH"
|
||||
pwd
|
||||
ls -lah
|
||||
whoami
|
||||
env
|
||||
freebsd-version
|
||||
mkdir -p /Users/runner/work/_temp/_github_workflow
|
||||
echo "{}" > /Users/runner/work/_temp/_github_workflow/event.json
|
||||
pnpm install --frozen-lockfile --ignore-scripts
|
||||
pnpm nx run-many --target=build-native -- --target=x86_64-unknown-freebsd
|
||||
rm -rf node_modules
|
||||
rm -rf dist
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: bindings-freebsd
|
||||
path: packages/**/*.node
|
||||
if-no-files-found: error
|
||||
publish:
|
||||
if: ${{ github.repository_owner == 'nrwl' }}
|
||||
if: ${{ github.event_name == 'release' && github.repository_owner == 'nrwl' }}
|
||||
name: Publish
|
||||
runs-on: ubuntu-latest
|
||||
environment: npm-registry
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: write
|
||||
pull-requests: write
|
||||
needs:
|
||||
- resolve-required-data
|
||||
- build-freebsd
|
||||
- build
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- uses: actions/checkout@v3
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
repository: ${{ needs.resolve-required-data.outputs.repo || github.repository }}
|
||||
ref: ${{ needs.resolve-required-data.outputs.ref || github.ref }}
|
||||
|
||||
- uses: pnpm/action-setup@7088e561eb65bb68695d245aa206f005ef30921d # v4.1.0
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
|
||||
version: 8.2
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
node-version: 18
|
||||
check-latest: true
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Use npm 11.5.2
|
||||
run: npm install -g npm@11.5.2
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
path: artifacts
|
||||
|
||||
# This command will appropriately fail if no artifacts are available
|
||||
- name: List artifacts
|
||||
run: ls -R artifacts
|
||||
shell: bash
|
||||
- name: Build Wasm
|
||||
run: |
|
||||
wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-23/wasi-sdk-23.0-x86_64-linux.tar.gz
|
||||
tar -xvf wasi-sdk-23.0-x86_64-linux.tar.gz
|
||||
pnpm build:wasm
|
||||
- name: Publish
|
||||
env:
|
||||
VERSION: ${{ needs.resolve-required-data.outputs.version }}
|
||||
DRY_RUN: ${{ needs.resolve-required-data.outputs.dry_run_flag }}
|
||||
PUBLISH_BRANCH: ${{ needs.resolve-required-data.outputs.publish_branch }}
|
||||
NX_VERBOSE_LOGGING: true
|
||||
run: |
|
||||
echo ""
|
||||
# Create and check out the publish branch
|
||||
git checkout -b $PUBLISH_BRANCH
|
||||
echo ""
|
||||
echo "Version set to: $VERSION"
|
||||
echo "DRY_RUN set to: $DRY_RUN"
|
||||
echo ""
|
||||
pnpm nx-release --local=false $VERSION $DRY_RUN
|
||||
|
||||
- name: (Stable Release Only) Trigger Docs Release
|
||||
# Publish docs only on a full release
|
||||
if: ${{ !github.event.release.prerelease && github.event_name == 'release' }}
|
||||
run: npx ts-node -P ./scripts/tsconfig.scripts.json ./scripts/release-docs.ts
|
||||
|
||||
- name: (PR Release Only) Create comment for successful PR release
|
||||
if: success() && github.event.inputs.pr
|
||||
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||
env:
|
||||
SUCCESS_COMMENT: ${{ needs.resolve-required-data.outputs.success_comment }}
|
||||
with:
|
||||
# github-token defaults to ${{ github.token }} so we don't need to specify it
|
||||
script: |
|
||||
const successComment = JSON.parse(process.env.SUCCESS_COMMENT);
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: ${{ github.event.inputs.pr }},
|
||||
body: successComment
|
||||
});
|
||||
|
||||
report-pending-publish:
|
||||
name: Report Pending Publish to Slack
|
||||
if: ${{ github.repository_owner == 'nrwl' }}
|
||||
needs:
|
||||
- resolve-required-data
|
||||
- build-freebsd
|
||||
- build
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
continue-on-error: true # Don't fail the workflow if notification fails
|
||||
steps:
|
||||
- name: Send Slack notification
|
||||
uses: ravsamhq/notify-slack-action@be814b201e233b2dc673608aa46e5447c8ab13f2 # v11
|
||||
with:
|
||||
status: ${{ job.status }}
|
||||
notification_title: >-
|
||||
${{ needs.resolve-required-data.outputs.pr_number &&
|
||||
format('📦 PR #{0} Publish Pending Review', needs.resolve-required-data.outputs.pr_number) ||
|
||||
'📦 Publish Pending Review' }}
|
||||
message_format: >-
|
||||
${{ needs.resolve-required-data.outputs.pr_number &&
|
||||
format('Version {0} from PR #{1} by @{2} is being published to NPM - manual review is required',
|
||||
needs.resolve-required-data.outputs.version,
|
||||
needs.resolve-required-data.outputs.pr_number,
|
||||
needs.resolve-required-data.outputs.pr_author) ||
|
||||
format('Version {0} is being published to NPM - manual review is required',
|
||||
needs.resolve-required-data.outputs.version) }}
|
||||
footer: '<{run_url}|View Workflow Run>'
|
||||
mention_users: 'U9NPA6C90' # Jason
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.ACTION_MONITORING_SLACK }}
|
||||
|
||||
pr_failure_comment:
|
||||
# Run this job if it is a PR release, running on the nrwl origin, and any of the required jobs failed
|
||||
if: ${{ github.repository_owner == 'nrwl' && github.event.inputs.pr && always() && contains(needs.*.result, 'failure') }}
|
||||
needs: [ resolve-required-data, build, build-freebsd, publish ]
|
||||
name: (PR Release Failure Only) Create comment for failed PR release
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Create comment for failed PR release
|
||||
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||
with:
|
||||
# This script is intentionally kept inline (and e.g. not generated in publish-resolve-data.js)
|
||||
# to ensure that an error within the data generation itself is not missed.
|
||||
script: |
|
||||
const message = `
|
||||
Failed to publish a PR release of this pull request, triggered by @${{ github.triggering_actor }}.
|
||||
See the failed workflow run at: https://github.com/nrwl/nx/actions/runs/${{ github.run_id }}
|
||||
`;
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: ${{ github.event.inputs.pr }},
|
||||
body: message
|
||||
});
|
||||
|
||||
git checkout -b publish/$GITHUB_REF_NAME
|
||||
npm config set //registry.npmjs.org/:_authToken=$NPM_TOKEN
|
||||
pnpm nx-release --local=false $GITHUB_REF_NAME
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
@@ -4,7 +4,7 @@ on:
|
||||
|
||||
name: Stale Bot workflow
|
||||
|
||||
permissions: { }
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -16,96 +16,163 @@ jobs:
|
||||
name: stale
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# This handles issues that need more info
|
||||
- name: stale-more-info-needed
|
||||
id: stale-more-info-needed
|
||||
uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v10.0.0
|
||||
uses: actions/stale@v3.0.13
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 7
|
||||
days-before-close: 21
|
||||
days-before-stale: 14
|
||||
days-before-close: 14
|
||||
stale-issue-label: "stale"
|
||||
operations-per-run: 300
|
||||
remove-stale-when-updated: true
|
||||
only-labels: "blocked: more info needed"
|
||||
stale-issue-message: |
|
||||
This issue has been automatically marked as stale because more information has not been provided within 7 days.
|
||||
It will be closed in 21 days if no information is provided.
|
||||
If information has been provided, please reply to keep it active.
|
||||
This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs.
|
||||
If we missed this issue please reply to keep it active.
|
||||
Thanks for being a part of the Nx community! 🙏
|
||||
|
||||
# This handles PRs that need to be rebased
|
||||
- name: stale-needs-rebase
|
||||
id: stale-needs-rebase
|
||||
uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v10.0.0
|
||||
uses: actions/stale@v3.0.13
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 7
|
||||
days-before-close: 21
|
||||
days-before-stale: 14
|
||||
days-before-close: 14
|
||||
stale-issue-label: "stale"
|
||||
operations-per-run: 300
|
||||
remove-stale-when-updated: true
|
||||
only-labels: "blocked: needs rebased"
|
||||
stale-issue-message: |
|
||||
This PR has been automatically marked as stale because it has not been rebased in 7 days.
|
||||
It will be closed in 21 days if it is not rebased.
|
||||
If the PR has been rebased or you are working on rebasing it, please reply to keep it active.
|
||||
If you do not have time, please let us know and we can rebase it.
|
||||
This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs.
|
||||
If we missed this issue please reply to keep it active.
|
||||
Thanks for being a part of the Nx community! 🙏
|
||||
|
||||
# This handles issues that do not have a repro
|
||||
- name: stale-repro-needed
|
||||
id: stale-repro-needed
|
||||
uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v10.0.0
|
||||
uses: actions/stale@v3.0.13
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 7
|
||||
days-before-close: 21
|
||||
days-before-stale: 14
|
||||
days-before-close: 14
|
||||
stale-issue-label: "stale"
|
||||
operations-per-run: 300
|
||||
remove-stale-when-updated: true
|
||||
only-labels: "blocked: repro needed"
|
||||
stale-issue-message: |
|
||||
This issue has been automatically marked as stale because no reproduction was provided within 7 days.
|
||||
Please help us help you. Providing a repository exhibiting the issue helps us diagnose and fix the issue.
|
||||
Any time that we spend reproducing this issue is time taken away from addressing this issue and other issues.
|
||||
This issue will be closed in 21 days if a reproduction is not provided.
|
||||
If a reproduction has been provided, please reply to keep it active.
|
||||
This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs.
|
||||
If we missed this issue please reply to keep it active.
|
||||
Thanks for being a part of the Nx community! 🙏
|
||||
|
||||
- name: stale-retry-with-latest
|
||||
id: stale-retry-with-latest
|
||||
uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v10.0.0
|
||||
uses: actions/stale@v3.0.13
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 7
|
||||
days-before-close: 21
|
||||
days-before-stale: 14
|
||||
days-before-close: 14
|
||||
stale-issue-label: "stale"
|
||||
operations-per-run: 300
|
||||
remove-stale-when-updated: true
|
||||
only-labels: "blocked: retry with latest"
|
||||
stale-issue-message: |
|
||||
This issue has been automatically marked as stale because no results of retrying on the latest version of Nx was provided within 7 days.
|
||||
It will be closed in 21 days if no results are provided.
|
||||
If the issue is still present, please reply to keep it active.
|
||||
If the issue was not present, please close this issue.
|
||||
This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs.
|
||||
If we missed this issue please reply to keep it active.
|
||||
Thanks for being a part of the Nx community! 🙏
|
||||
|
||||
|
||||
# This handles issues are really old and were made with a previous major
|
||||
- name: stale-bug
|
||||
id: stale-bug
|
||||
uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v10.0.0
|
||||
uses: actions/stale@v3.0.13
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 180
|
||||
days-before-close: 21
|
||||
days-before-close: 14
|
||||
stale-issue-label: "stale"
|
||||
operations-per-run: 300
|
||||
remove-stale-when-updated: true
|
||||
only-labels: "type: bug"
|
||||
stale-issue-message: |
|
||||
This issue has been automatically marked as stale because it hasn't had any activity for 6 months.
|
||||
Many things may have changed within this time. The issue may have already been fixed or it may not be relevant anymore.
|
||||
If at this point, this is still an issue, please respond with updated information.
|
||||
It will be closed in 21 days if no further activity occurs.
|
||||
This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs.
|
||||
If we missed this issue please reply to keep it active.
|
||||
Thanks for being a part of the Nx community! 🙏
|
||||
|
||||
- name: stale-cleanup
|
||||
id: stale-cleanup
|
||||
uses: actions/stale@v3.0.13
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 180
|
||||
days-before-close: 14
|
||||
stale-issue-label: "stale"
|
||||
operations-per-run: 300
|
||||
remove-stale-when-updated: true
|
||||
only-labels: "type: cleanup"
|
||||
stale-issue-message: |
|
||||
This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs.
|
||||
If we missed this issue please reply to keep it active.
|
||||
Thanks for being a part of the Nx community! 🙏
|
||||
|
||||
- name: stale-docs
|
||||
id: stale-docs
|
||||
uses: actions/stale@v3.0.13
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 180
|
||||
days-before-close: 14
|
||||
stale-issue-label: "stale"
|
||||
operations-per-run: 300
|
||||
remove-stale-when-updated: true
|
||||
only-labels: "type: docs"
|
||||
stale-issue-message: |
|
||||
This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs.
|
||||
If we missed this issue please reply to keep it active.
|
||||
Thanks for being a part of the Nx community! 🙏
|
||||
|
||||
- name: stale-enhancement
|
||||
id: stale-enhancement
|
||||
uses: actions/stale@v3.0.13
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 250
|
||||
days-before-close: 14
|
||||
stale-issue-label: "stale"
|
||||
operations-per-run: 300
|
||||
remove-stale-when-updated: true
|
||||
only-labels: "type: enhancement"
|
||||
stale-issue-message: |
|
||||
This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs.
|
||||
If we missed this issue please reply to keep it active.
|
||||
Thanks for being a part of the Nx community! 🙏
|
||||
|
||||
- name: stale-feature
|
||||
id: stale-feature
|
||||
uses: actions/stale@v3.0.13
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 250
|
||||
days-before-close: 14
|
||||
stale-issue-label: "stale"
|
||||
operations-per-run: 300
|
||||
remove-stale-when-updated: true
|
||||
only-labels: "type: feature"
|
||||
stale-issue-message: |
|
||||
This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs.
|
||||
If we missed this issue please reply to keep it active.
|
||||
Thanks for being a part of the Nx community! 🙏
|
||||
|
||||
- name: stale-question
|
||||
id: stale-question
|
||||
uses: actions/stale@v3.0.13
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 45
|
||||
days-before-close: 14
|
||||
stale-issue-label: "stale"
|
||||
operations-per-run: 300
|
||||
remove-stale-when-updated: true
|
||||
only-labels: "type: question / discussion"
|
||||
stale-issue-message: |
|
||||
This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs.
|
||||
If we missed this issue please reply to keep it active.
|
||||
Thanks for being a part of the Nx community! 🙏
|
||||
|
||||
@@ -3,7 +3,6 @@ node_modules
|
||||
/.fleet
|
||||
/.vscode
|
||||
dist
|
||||
out-tsc
|
||||
/build
|
||||
/coverage
|
||||
./test
|
||||
@@ -13,113 +12,25 @@ tmp
|
||||
jest.debug.config.js
|
||||
.tool-versions
|
||||
/.nx-cache
|
||||
/.nx/cache
|
||||
/.nx/workspace-data
|
||||
/.verdaccio/build/local-registry
|
||||
/graph/client/src/assets/environment.js
|
||||
/graph/client/src/assets/dev/environment.js
|
||||
/graph/client/src/assets/generated-project-graphs
|
||||
/graph/client/src/assets/generated-task-graphs
|
||||
/graph/client/src/assets/generated-task-inputs
|
||||
/graph/client/src/assets/generated-source-maps
|
||||
/nx-dev/nx-dev/public/documentation
|
||||
/nx-dev/nx-dev/public/tutorials
|
||||
/nx-dev/nx-dev/public/images/open-graph
|
||||
**/tests/temp-db
|
||||
|
||||
# Issues scraper creates these files, stored by github's cache
|
||||
/scripts/issues-scraper/cached
|
||||
|
||||
# We don't commit a CHANELGELOG.md file to the repo, we only create Github releases
|
||||
# Lerna creates this
|
||||
CHANGELOG.md
|
||||
|
||||
# Next.js
|
||||
.next
|
||||
out
|
||||
|
||||
|
||||
# Angular Cache
|
||||
.angular
|
||||
|
||||
# Astro Cache
|
||||
.astro
|
||||
|
||||
# Local dev files
|
||||
.env.local
|
||||
.env
|
||||
.bashrc
|
||||
|
||||
*.node
|
||||
|
||||
# Fix for issue when working on the repo in a dev container
|
||||
.pnpm-store
|
||||
|
||||
.cargo/.package-cache
|
||||
.cargo/bin/
|
||||
.cargo/env
|
||||
.cargo/registry/
|
||||
.local/
|
||||
.npm/
|
||||
.profile
|
||||
.rustup/
|
||||
target
|
||||
*.wasm
|
||||
/wasi-sdk*
|
||||
|
||||
vite.config.*.timestamp*
|
||||
|
||||
storybook-static
|
||||
|
||||
# Ignore Gradle project-specific cache directory
|
||||
.gradle
|
||||
.kotlin
|
||||
|
||||
.claude/settings.local.json
|
||||
|
||||
.cursor/rules/nx-rules.mdc
|
||||
.cursor/mcp.json
|
||||
.github/instructions/nx.instructions.md
|
||||
|
||||
# Added by Claude Task Master
|
||||
# Logs
|
||||
logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
dev-debug.log
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
# Environment variables
|
||||
.env
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
.specstory/**
|
||||
.cursorindexingignore
|
||||
# OS specific
|
||||
# Task files
|
||||
/tasks.json
|
||||
/tasks
|
||||
|
||||
# Upstream docs local configuration (machine-specific)
|
||||
.upstreamdocs.local.json
|
||||
|
||||
astro-docs/.netlify
|
||||
|
||||
# Angular Rspack Specific Options
|
||||
packages/angular-rspack/coverage
|
||||
packages/angular-rspack-compiler/coverage
|
||||
|
||||
# Angular Rspack Packages use a template to generate the correct README
|
||||
packages/angular-rspack/README.md
|
||||
packages/angular-rspack-compiler/README.md
|
||||
|
||||
test-output
|
||||
test-results
|
||||
|
||||
# TypeScript build info files
|
||||
*.tsbuildinfo
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
node ./scripts/commit-lint.js "$1"
|
||||
@@ -1,12 +1,3 @@
|
||||
# Skip if this is a worktree creation (previous ref is null)
|
||||
if [ "$1" = "0000000000000000000000000000000000000000" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Skip if this is a file checkout (not branch switch) - $3 would be 0
|
||||
if [ "$3" = "0" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#!/bin/sh
|
||||
changedFiles="$(git diff-tree -r --name-only --no-commit-id $1 $2)"
|
||||
node ./scripts/notify-lockfile-changes.js $changedFiles
|
||||
@@ -1,2 +1,3 @@
|
||||
#!/bin/sh
|
||||
changedFiles="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"
|
||||
node ./scripts/notify-lockfile-changes.js $changedFiles
|
||||
node ./scripts/notify-lockfile-changes.js $changedFiles
|
||||
@@ -1 +1,6 @@
|
||||
pnpm nx prepush --parallel 8 --tuiAutoExit 0
|
||||
#!/usr/bin/env sh
|
||||
|
||||
pnpm check-lock-files &&
|
||||
pnpm check-commit &&
|
||||
pnpm documentation &&
|
||||
pnpm pretty-quick --check
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"nx": {
|
||||
"command": "pnpm",
|
||||
"args": ["nx-mcp"],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
launch-templates:
|
||||
linux-large:
|
||||
resource-class: 'docker_linux_amd64/large'
|
||||
image: 'us-east1-docker.pkg.dev/nxcloudoperations/nx-cloud/nx-agents-base-images:ubuntu22.04-node20.19-v1'
|
||||
env:
|
||||
GIT_AUTHOR_EMAIL: test@test.com
|
||||
GIT_AUTHOR_NAME: Test
|
||||
GIT_COMMITTER_EMAIL: test@test.com
|
||||
GIT_COMMITTER_NAME: Test
|
||||
SELECTED_PM: 'pnpm'
|
||||
|
||||
NX_NATIVE_LOGGING: 'nx::native::db'
|
||||
init-steps:
|
||||
- name: Checkout
|
||||
uses: 'nrwl/nx-cloud-workflows/v5/workflow-steps/checkout/main.yaml'
|
||||
|
||||
- name: Check Node Version
|
||||
script: node --version
|
||||
|
||||
- name: Cache restore
|
||||
uses: 'nrwl/nx-cloud-workflows/v5/workflow-steps/cache/main.yaml'
|
||||
inputs:
|
||||
key: 'pnpm-lock.yaml'
|
||||
paths: .pnpm-store
|
||||
base-branch: 'master'
|
||||
|
||||
- name: Install zip and unzip
|
||||
script: sudo apt-get -yqq install zip unzip
|
||||
|
||||
- name: Install bun
|
||||
script: |
|
||||
curl -fsSL https://bun.sh/install | bash
|
||||
echo "BUN_INSTALL=$HOME/.bun" >> $NX_CLOUD_ENV
|
||||
echo "PATH=$HOME/.bun/bin:$PATH" >> $NX_CLOUD_ENV
|
||||
|
||||
- name: Check bun
|
||||
script: |
|
||||
bun --version
|
||||
|
||||
- name: Install e2e deps
|
||||
script: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ca-certificates lsof libvips-dev libglib2.0-dev libgirepository1.0-dev
|
||||
|
||||
- name: Pnpm Install from lockfile
|
||||
script: |
|
||||
pnpm install --frozen-lockfile
|
||||
|
||||
- name: Install Browsers
|
||||
script: |
|
||||
pnpm exec cypress install
|
||||
pnpm exec playwright install --with-deps
|
||||
|
||||
- name: Install Rust
|
||||
script: |
|
||||
curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
source "$HOME/.cargo/env"
|
||||
rustup toolchain install 1.70.0
|
||||
|
||||
- name: Configure git metadata (needed for lerna smoke tests)
|
||||
script: |
|
||||
git config --global user.email test@test.com
|
||||
git config --global user.name "Test Test"
|
||||
|
||||
- name: Load Cargo Env
|
||||
script: echo "PATH=$HOME/.cargo/bin:$PATH" >> $NX_CLOUD_ENV
|
||||
|
||||
- name: Install Rust Dependencies
|
||||
script: |
|
||||
cargo fetch
|
||||
|
||||
- name: Setup Java 21
|
||||
script: |
|
||||
sudo apt update
|
||||
sudo apt install -y openjdk-21-jdk
|
||||
sudo update-alternatives --set java /usr/lib/jvm/java-21-openjdk-amd64/bin/java
|
||||
java -version
|
||||
|
||||
- name: Setup Gradle
|
||||
script: |
|
||||
./gradlew wrapper
|
||||
./gradlew --version
|
||||
|
||||
linux-extra-large:
|
||||
resource-class: 'docker_linux_amd64/extra_large'
|
||||
image: 'us-east1-docker.pkg.dev/nxcloudoperations/nx-cloud/nx-agents-base-images:ubuntu22.04-node20.19-v1'
|
||||
env:
|
||||
GIT_AUTHOR_EMAIL: test@test.com
|
||||
GIT_AUTHOR_NAME: Test
|
||||
GIT_COMMITTER_EMAIL: test@test.com
|
||||
GIT_COMMITTER_NAME: Test
|
||||
SELECTED_PM: 'pnpm'
|
||||
NX_NATIVE_LOGGING: 'nx::native::db'
|
||||
init-steps:
|
||||
- name: Checkout
|
||||
uses: 'nrwl/nx-cloud-workflows/v5/workflow-steps/checkout/main.yaml'
|
||||
|
||||
- name: Check Node Version
|
||||
script: node --version
|
||||
|
||||
- name: Cache restore
|
||||
uses: 'nrwl/nx-cloud-workflows/v5/workflow-steps/cache/main.yaml'
|
||||
inputs:
|
||||
key: 'pnpm-lock.yaml'
|
||||
paths: .pnpm-store
|
||||
base-branch: 'master'
|
||||
|
||||
- name: Install zip and unzip
|
||||
script: sudo apt-get -yqq install zip unzip
|
||||
|
||||
- name: Install bun
|
||||
script: |
|
||||
curl -fsSL https://bun.sh/install | bash
|
||||
echo "BUN_INSTALL=$HOME/.bun" >> $NX_CLOUD_ENV
|
||||
echo "PATH=$HOME/.bun/bin:$PATH" >> $NX_CLOUD_ENV
|
||||
|
||||
- name: Check bun
|
||||
script: |
|
||||
bun --version
|
||||
|
||||
- name: Install e2e deps
|
||||
script: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ca-certificates lsof libvips-dev libglib2.0-dev libgirepository1.0-dev
|
||||
|
||||
- name: Pnpm Install from lockfile
|
||||
script: |
|
||||
pnpm install --frozen-lockfile
|
||||
|
||||
- name: Install Browsers
|
||||
script: |
|
||||
pnpm exec cypress install
|
||||
pnpm exec playwright install --with-deps
|
||||
|
||||
- name: Install Rust
|
||||
script: |
|
||||
curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
source "$HOME/.cargo/env"
|
||||
rustup toolchain install 1.70.0
|
||||
|
||||
- name: Configure git metadata (needed for lerna smoke tests)
|
||||
script: |
|
||||
git config --global user.email test@test.com
|
||||
git config --global user.name "Test Test"
|
||||
|
||||
- name: Load Cargo Env
|
||||
script: echo "PATH=$HOME/.cargo/bin:$PATH" >> $NX_CLOUD_ENV
|
||||
|
||||
- name: Install Rust Dependencies
|
||||
script: |
|
||||
cargo fetch
|
||||
|
||||
- name: Setup Java 21
|
||||
script: |
|
||||
sudo apt update
|
||||
sudo apt install -y openjdk-21-jdk
|
||||
sudo update-alternatives --set java /usr/lib/jvm/java-21-openjdk-amd64/bin/java
|
||||
java -version
|
||||
|
||||
- name: Setup Gradle
|
||||
script: |
|
||||
./gradlew wrapper
|
||||
./gradlew --version
|
||||
@@ -1,61 +0,0 @@
|
||||
distribute-on:
|
||||
default: auto linux-large, 1 linux-extra-large
|
||||
assignment-rules:
|
||||
# e2e-release tests must run sequentially due to shared git state and publishing operations
|
||||
- projects:
|
||||
- e2e-release
|
||||
targets:
|
||||
- e2e-ci**
|
||||
run-on:
|
||||
- agent: linux-large
|
||||
parallelism: 1
|
||||
|
||||
- projects:
|
||||
- e2e-gradle
|
||||
targets:
|
||||
- e2e-ci**
|
||||
run-on:
|
||||
- agent: linux-large
|
||||
parallelism: 1
|
||||
- agent: linux-extra-large
|
||||
parallelism: 1
|
||||
|
||||
# All other e2e tests can run in parallel
|
||||
- targets:
|
||||
- e2e-ci**
|
||||
run-on:
|
||||
- agent: linux-large
|
||||
parallelism: 2
|
||||
- agent: linux-extra-large
|
||||
parallelism: 3
|
||||
|
||||
# These projects should not need to be isolated.
|
||||
- projects:
|
||||
- nx-dev
|
||||
targets:
|
||||
- build*
|
||||
run-on:
|
||||
- agent: linux-extra-large
|
||||
parallelism: 1
|
||||
- projects:
|
||||
- angular
|
||||
- react
|
||||
targets:
|
||||
- test
|
||||
run-on:
|
||||
- agent: linux-extra-large
|
||||
parallelism: 1
|
||||
|
||||
- targets:
|
||||
- lint
|
||||
run-on:
|
||||
- agent: linux-large
|
||||
parallelism: 6
|
||||
|
||||
- targets:
|
||||
- '*'
|
||||
run-on:
|
||||
- agent: linux-large
|
||||
parallelism: 3
|
||||
- agent: linux-extra-large
|
||||
parallelism: 3
|
||||
@@ -1,5 +1,2 @@
|
||||
nx-dev/**/jest.config.js
|
||||
.next
|
||||
_files
|
||||
_solution
|
||||
nx-dev/tutorial/**/templates
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
# Enable pre/post-install which are disabled by default. Installing peer deps which is also disabled by default
|
||||
auto-install-peers=true
|
||||
enable-pre-post-scripts=true
|
||||
|
||||
# Enable lifecycle scripts for specific packages that require them (like post-install)
|
||||
enable-scripts=@napi-rs/canvas,sharp,@swc/core,@swc/cli,@swc-node/register,esbuild
|
||||
|
||||
# Compatibility
|
||||
strict-peer-dependencies=false
|
||||
lockfile-version-strict=false
|
||||
|
||||
# Consistency across environments
|
||||
use-node-version=20.19.0
|
||||
@@ -13,18 +13,10 @@ packages/express/src/schematics/**/files/**/*.json
|
||||
packages/nest/src/schematics/**/files/**/*.json
|
||||
packages/react/src/schematics/**/files/**/*.json
|
||||
packages/jest/src/schematics/**/files/**/*.json
|
||||
packages/gradle/project-graph/build/**/*.*
|
||||
packages/nx/src/plugins/js/lock-file/__fixtures__/**/*.*
|
||||
packages/**/schematics/**/files/**/*.html
|
||||
packages/**/generators/**/files/**/*.html
|
||||
packages/nx/src/native/**/*.rs
|
||||
packages/nx/src/native/browser.js
|
||||
packages/nx/src/native/nx.wasi-browser.js
|
||||
packages/nx/src/native/nx.wasi.cjs
|
||||
packages/nx/src/native/wasi-worker-browser.mjs
|
||||
packages/nx/src/native/wasi-worker.mjs
|
||||
packages/nx/src/native/native-bindings.js
|
||||
packages/nx/src/native/index.d.ts
|
||||
packages/nx/src/native/
|
||||
nx-dev/nx-dev/.next/
|
||||
nx-dev/nx-dev/public/documentation
|
||||
graph/client/src/assets/environment.js
|
||||
@@ -42,15 +34,3 @@ graph/client/src/assets/generated-task-graphs
|
||||
/dist
|
||||
/.env
|
||||
CODEOWNERS
|
||||
|
||||
/.nx/cache
|
||||
|
||||
.pnpm-store
|
||||
|
||||
/.nx/workspace-data
|
||||
/.nx/workflows/dynamic-changesets.yaml
|
||||
_files
|
||||
_solution
|
||||
|
||||
# this file uses TS import attributes which the current prettier version does not support
|
||||
tools/documentation/create-embeddings/src/main.mts
|
||||
|
||||
@@ -1,13 +1,4 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"endOfLine": "lf",
|
||||
"plugins": ["prettier-plugin-tailwindcss"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.mdoc",
|
||||
"options": {
|
||||
"parser": "markdown"
|
||||
}
|
||||
}
|
||||
]
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"include": ["apps/**/*", "libs/**/*", "packages/**/*"],
|
||||
"exclude": [
|
||||
"**/*.spec.*",
|
||||
"**/test/**/*",
|
||||
"**/__tests__/**/*",
|
||||
"**/*.test.*",
|
||||
"node_modules/**/*"
|
||||
]
|
||||
}
|
||||
@@ -5,8 +5,6 @@ auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd
|
||||
|
||||
max_body_size: 20mb
|
||||
|
||||
# a list of other known repositories we can talk to
|
||||
uplinks:
|
||||
npmjs:
|
||||
|
||||
@@ -1,199 +0,0 @@
|
||||
When responding to queries about this repository:
|
||||
|
||||
1. Suggest relevant commands from the "Essential Commands" section when applicable
|
||||
2. Highlight Nx's focus on monorepos and its key features like smart task execution, code generation, and project graph
|
||||
analysis
|
||||
3. Mention the plugin ecosystem and support for various frameworks when relevant
|
||||
4. Emphasize the importance of running the full validation suite before committing changes
|
||||
|
||||
Always strive to provide accurate, helpful responses that align with the best practices and workflows described in this
|
||||
file.
|
||||
|
||||
## GitHub Issue Response Mode
|
||||
|
||||
When responding to GitHub issues, determine your approach based on how the request is phrased:
|
||||
|
||||
### Plan-First Mode (Default)
|
||||
|
||||
Use this approach when users ask you to:
|
||||
|
||||
- "analyze", "investigate", "assess", "review", "examine", or "plan"
|
||||
- Or when the request is ambiguous
|
||||
|
||||
In this mode:
|
||||
|
||||
1. Provide a detailed analysis of the issue
|
||||
2. Create a comprehensive implementation plan
|
||||
3. Break down the solution into clear steps
|
||||
4. Then please post the plan as a comment on the issue
|
||||
|
||||
### Immediate Implementation Mode
|
||||
|
||||
Use this approach when users ask you to:
|
||||
|
||||
- "fix", "implement", "solve", "build", "create", "update", or "add"
|
||||
- Or when they explicitly request immediate action
|
||||
|
||||
In this mode:
|
||||
|
||||
1. Analyze the issue quickly
|
||||
2. Implement the complete solution immediately
|
||||
3. Make all necessary code changes. Please make multiple commits so that the changes are easier to review.
|
||||
4. Run appropriate tests and validation
|
||||
5. If the tests, are not passing, please fix the issues and continue doing this up to 3 more times until the tests pass
|
||||
6. Once the tests pass, push a branch and then suggest opening a PR which has a description of the changes made, and
|
||||
that
|
||||
it make sure that it explicitly says "Fixes #ISSUE_NUMBER" to automatically close the issue when the PR is merged.
|
||||
|
||||
## Avoid making changes to generated files
|
||||
|
||||
Files under `generated` directories are generated based on a different source file and should not be modified directly.
|
||||
Find the underlying source and modify that instead.
|
||||
|
||||
## Essential Commands
|
||||
|
||||
### Code Formatting
|
||||
|
||||
After code changes are made, please make sure to format the files with prettier via `npx prettier -- FILE_NAME`
|
||||
|
||||
### Pre-push Validation
|
||||
|
||||
```bash
|
||||
# Full validation suite - run before committing
|
||||
nx prepush
|
||||
```
|
||||
|
||||
If the prepush validation suite fails, please fix the issues before proceeding with your work. This ensures that all
|
||||
code adheres to the project's standards and passes all tests. DO NOT make a new commit to fix these issues. Instead,
|
||||
amend the current commit.
|
||||
|
||||
### Testing Changes
|
||||
|
||||
After code changes are made, first test the specific project where the changes were made:
|
||||
|
||||
```bash
|
||||
nx run-many -t test,build,lint -p PROJECT_NAME
|
||||
```
|
||||
|
||||
After verifying the individual project, validate that the changes in projects which have been affected:
|
||||
|
||||
```bash
|
||||
# Test only affected projects (recommended for development)
|
||||
nx affected -t build,test,lint
|
||||
```
|
||||
|
||||
As the last step, run the e2e tests to fully ensure that changes are valid:
|
||||
|
||||
```bash
|
||||
# Run affected e2e tests (recommended for development)
|
||||
nx affected -t e2e-local
|
||||
```
|
||||
|
||||
## Fixing GitHub Issues
|
||||
|
||||
When working on a GitHub issue, follow this systematic approach:
|
||||
|
||||
### 1. Get Issue Details
|
||||
|
||||
```bash
|
||||
# Get issue details using GitHub CLI (replace ISSUE_NUMBER with actual number)
|
||||
gh issue view ISSUE_NUMBER
|
||||
|
||||
# View multiple issues efficiently in one command
|
||||
gh issue list --limit 50 --json number,title,state,labels,assignees,updatedAt,body --jq '.[] | select(.number == 123 or .number == 456 or .number == 789)'
|
||||
|
||||
# Or filter by specific criteria to get multiple related issues
|
||||
gh issue list --label "bug" --state "open" --json number,title,body,labels --jq '.[]'
|
||||
gh issue list --assignee "@me" --json number,title,body,state --jq '.[]'
|
||||
```
|
||||
|
||||
**Tip**: Instead of running `gh issue view` multiple times, use `gh issue list` with JSON output and filtering to gather
|
||||
information about multiple issues in a single command. This is much more efficient than viewing issues one at a time.
|
||||
|
||||
**Always provide clickable links**: When discussing GitHub issues or PRs, always include the full GitHub URL so the user
|
||||
can easily open them in their browser. For example:
|
||||
|
||||
- Issue #12345: https://github.com/nrwl/nx/issues/12345
|
||||
- PR #67890: https://github.com/nrwl/nx/pull/67890
|
||||
|
||||
When cloning reproduction repos, please clone within `./tmp/claude/repro-ISSUE_NUMBER`
|
||||
|
||||
### 2. Analyze the Plan
|
||||
|
||||
- Look for a plan or implementation details in the issue description
|
||||
- Check comments for additional context or clarification
|
||||
- Identify affected projects and components
|
||||
|
||||
### 3. Implement the Solution
|
||||
|
||||
- Follow the plan outlined in the issue
|
||||
- Make focused changes that address the specific problem
|
||||
- Ensure code follows existing patterns and conventions
|
||||
|
||||
### 4. Run Full Validation
|
||||
|
||||
Use the testing workflow from the "Essential Commands" section.
|
||||
|
||||
### 5. Submit Pull Request
|
||||
|
||||
- Create a descriptive PR title that references the issue
|
||||
- **Always fill in the PR template** - don't leave it empty
|
||||
- Include "Fixes #ISSUE_NUMBER" in the PR description
|
||||
- Provide a clear summary of changes made
|
||||
- Request appropriate reviewers
|
||||
|
||||
## Pull Request Template
|
||||
|
||||
**IMPORTANT**: When creating a pull request, you MUST fill in the template found in `.github/PULL_REQUEST_TEMPLATE.md`.
|
||||
Do not leave the template sections empty. The template includes:
|
||||
|
||||
### Required Sections
|
||||
|
||||
1. **Current Behavior**: Describe the behavior we have today
|
||||
2. **Expected Behavior**: Describe the behavior we should expect with the changes in this PR
|
||||
3. **Related Issue(s)**: Link the issue being fixed so it gets closed when the PR is merged
|
||||
|
||||
### Template Format
|
||||
|
||||
```markdown
|
||||
## Current Behavior
|
||||
|
||||
<!-- This is the behavior we have today -->
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
<!-- This is the behavior we should expect with the changes in this PR -->
|
||||
|
||||
## Related Issue(s)
|
||||
|
||||
<!-- Please link the issue being fixed so it gets closed when this is merged. -->
|
||||
|
||||
Fixes #ISSUE_NUMBER
|
||||
```
|
||||
|
||||
### Guidelines
|
||||
|
||||
- Ensure your commit message follows the conventional commit format (use `pnpm commit`)
|
||||
- Use `fix:`, `feat:`, `chore:`, etc. as appropriate types.
|
||||
- Scope is **required** for all commits. Possible scopes are listed in `scripts/commitizen.js`.
|
||||
- Read the submission guidelines in CONTRIBUTING.md before posting
|
||||
- For complex changes, you can request a dedicated Nx release by mentioning the Nx team
|
||||
- Always link the related issue using "Fixes #ISSUE_NUMBER" to automatically close it when merged
|
||||
|
||||
# General Guidelines for working with Nx
|
||||
|
||||
- When running tasks (for example build, lint, test, e2e, etc.), always prefer running the task through `nx` (i.e. `nx run`, `nx run-many`, `nx affected`) instead of using the underlying tooling directly
|
||||
- You have access to the Nx MCP server and its tools, use them to help the user
|
||||
- When answering questions about the repository, use the `nx_workspace` tool first to gain an understanding of the workspace architecture where applicable.
|
||||
- When working in individual projects, use the `nx_project_details` mcp tool to analyze and understand the specific project structure and dependencies
|
||||
- For questions around nx configuration, best practices or if you're unsure, use the `nx_docs` tool to get relevant, up-to-date docs. Always use this instead of assuming things about nx configuration
|
||||
- If the user needs help with an Nx configuration or project graph error, use the `nx_workspace` tool to get any errors
|
||||
|
||||
# CI Error Guidelines
|
||||
|
||||
If the user wants help with fixing an error in their CI pipeline, use the following flow:
|
||||
|
||||
- Retrieve the list of current CI Pipeline Executions (CIPEs) using the `nx_cloud_cipe_details` tool
|
||||
- If there are any errors, use the `nx_cloud_fix_cipe_failure` tool to retrieve the logs for a specific task
|
||||
- Use the task logs to see what's wrong and help the user fix their problem. Use the appropriate tools if necessary
|
||||
- Make sure that the problem is fixed by running the task that you passed into the `nx_cloud_fix_cipe_failure` tool
|
||||
@@ -1,199 +0,0 @@
|
||||
When responding to queries about this repository:
|
||||
|
||||
1. Suggest relevant commands from the "Essential Commands" section when applicable
|
||||
2. Highlight Nx's focus on monorepos and its key features like smart task execution, code generation, and project graph
|
||||
analysis
|
||||
3. Mention the plugin ecosystem and support for various frameworks when relevant
|
||||
4. Emphasize the importance of running the full validation suite before committing changes
|
||||
|
||||
Always strive to provide accurate, helpful responses that align with the best practices and workflows described in this
|
||||
file.
|
||||
|
||||
## GitHub Issue Response Mode
|
||||
|
||||
When responding to GitHub issues, determine your approach based on how the request is phrased:
|
||||
|
||||
### Plan-First Mode (Default)
|
||||
|
||||
Use this approach when users ask you to:
|
||||
|
||||
- "analyze", "investigate", "assess", "review", "examine", or "plan"
|
||||
- Or when the request is ambiguous
|
||||
|
||||
In this mode:
|
||||
|
||||
1. Provide a detailed analysis of the issue
|
||||
2. Create a comprehensive implementation plan
|
||||
3. Break down the solution into clear steps
|
||||
4. Then please post the plan as a comment on the issue
|
||||
|
||||
### Immediate Implementation Mode
|
||||
|
||||
Use this approach when users ask you to:
|
||||
|
||||
- "fix", "implement", "solve", "build", "create", "update", or "add"
|
||||
- Or when they explicitly request immediate action
|
||||
|
||||
In this mode:
|
||||
|
||||
1. Analyze the issue quickly
|
||||
2. Implement the complete solution immediately
|
||||
3. Make all necessary code changes. Please make multiple commits so that the changes are easier to review.
|
||||
4. Run appropriate tests and validation
|
||||
5. If the tests, are not passing, please fix the issues and continue doing this up to 3 more times until the tests pass
|
||||
6. Once the tests pass, push a branch and then suggest opening a PR which has a description of the changes made, and
|
||||
that
|
||||
it make sure that it explicitly says "Fixes #ISSUE_NUMBER" to automatically close the issue when the PR is merged.
|
||||
|
||||
## Avoid making changes to generated files
|
||||
|
||||
Files under `generated` directories are generated based on a different source file and should not be modified directly.
|
||||
Find the underlying source and modify that instead.
|
||||
|
||||
## Essential Commands
|
||||
|
||||
### Code Formatting
|
||||
|
||||
After code changes are made, please make sure to format the files with prettier via `npx prettier -- FILE_NAME`
|
||||
|
||||
### Pre-push Validation
|
||||
|
||||
```bash
|
||||
# Full validation suite - run before committing
|
||||
nx prepush
|
||||
```
|
||||
|
||||
If the prepush validation suite fails, please fix the issues before proceeding with your work. This ensures that all
|
||||
code adheres to the project's standards and passes all tests. DO NOT make a new commit to fix these issues. Instead,
|
||||
amend the current commit.
|
||||
|
||||
### Testing Changes
|
||||
|
||||
After code changes are made, first test the specific project where the changes were made:
|
||||
|
||||
```bash
|
||||
nx run-many -t test,build,lint -p PROJECT_NAME
|
||||
```
|
||||
|
||||
After verifying the individual project, validate that the changes in projects which have been affected:
|
||||
|
||||
```bash
|
||||
# Test only affected projects (recommended for development)
|
||||
nx affected -t build,test,lint
|
||||
```
|
||||
|
||||
As the last step, run the e2e tests to fully ensure that changes are valid:
|
||||
|
||||
```bash
|
||||
# Run affected e2e tests (recommended for development)
|
||||
nx affected -t e2e-local
|
||||
```
|
||||
|
||||
## Fixing GitHub Issues
|
||||
|
||||
When working on a GitHub issue, follow this systematic approach:
|
||||
|
||||
### 1. Get Issue Details
|
||||
|
||||
```bash
|
||||
# Get issue details using GitHub CLI (replace ISSUE_NUMBER with actual number)
|
||||
gh issue view ISSUE_NUMBER
|
||||
|
||||
# View multiple issues efficiently in one command
|
||||
gh issue list --limit 50 --json number,title,state,labels,assignees,updatedAt,body --jq '.[] | select(.number == 123 or .number == 456 or .number == 789)'
|
||||
|
||||
# Or filter by specific criteria to get multiple related issues
|
||||
gh issue list --label "bug" --state "open" --json number,title,body,labels --jq '.[]'
|
||||
gh issue list --assignee "@me" --json number,title,body,state --jq '.[]'
|
||||
```
|
||||
|
||||
**Tip**: Instead of running `gh issue view` multiple times, use `gh issue list` with JSON output and filtering to gather
|
||||
information about multiple issues in a single command. This is much more efficient than viewing issues one at a time.
|
||||
|
||||
**Always provide clickable links**: When discussing GitHub issues or PRs, always include the full GitHub URL so the user
|
||||
can easily open them in their browser. For example:
|
||||
|
||||
- Issue #12345: https://github.com/nrwl/nx/issues/12345
|
||||
- PR #67890: https://github.com/nrwl/nx/pull/67890
|
||||
|
||||
When cloning reproduction repos, please clone within `./tmp/claude/repro-ISSUE_NUMBER`
|
||||
|
||||
### 2. Analyze the Plan
|
||||
|
||||
- Look for a plan or implementation details in the issue description
|
||||
- Check comments for additional context or clarification
|
||||
- Identify affected projects and components
|
||||
|
||||
### 3. Implement the Solution
|
||||
|
||||
- Follow the plan outlined in the issue
|
||||
- Make focused changes that address the specific problem
|
||||
- Ensure code follows existing patterns and conventions
|
||||
|
||||
### 4. Run Full Validation
|
||||
|
||||
Use the testing workflow from the "Essential Commands" section.
|
||||
|
||||
### 5. Submit Pull Request
|
||||
|
||||
- Create a descriptive PR title that references the issue
|
||||
- **Always fill in the PR template** - don't leave it empty
|
||||
- Include "Fixes #ISSUE_NUMBER" in the PR description
|
||||
- Provide a clear summary of changes made
|
||||
- Request appropriate reviewers
|
||||
|
||||
## Pull Request Template
|
||||
|
||||
**IMPORTANT**: When creating a pull request, you MUST fill in the template found in `.github/PULL_REQUEST_TEMPLATE.md`.
|
||||
Do not leave the template sections empty. The template includes:
|
||||
|
||||
### Required Sections
|
||||
|
||||
1. **Current Behavior**: Describe the behavior we have today
|
||||
2. **Expected Behavior**: Describe the behavior we should expect with the changes in this PR
|
||||
3. **Related Issue(s)**: Link the issue being fixed so it gets closed when the PR is merged
|
||||
|
||||
### Template Format
|
||||
|
||||
```markdown
|
||||
## Current Behavior
|
||||
|
||||
<!-- This is the behavior we have today -->
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
<!-- This is the behavior we should expect with the changes in this PR -->
|
||||
|
||||
## Related Issue(s)
|
||||
|
||||
<!-- Please link the issue being fixed so it gets closed when this is merged. -->
|
||||
|
||||
Fixes #ISSUE_NUMBER
|
||||
```
|
||||
|
||||
### Guidelines
|
||||
|
||||
- Ensure your commit message follows the conventional commit format (use `pnpm commit`)
|
||||
- Use `fix:`, `feat:`, `chore:`, etc. as appropriate types.
|
||||
- Scope is **required** for all commits. Possible scopes are listed in `scripts/commitizen.js`.
|
||||
- Read the submission guidelines in CONTRIBUTING.md before posting
|
||||
- For complex changes, you can request a dedicated Nx release by mentioning the Nx team
|
||||
- Always link the related issue using "Fixes #ISSUE_NUMBER" to automatically close it when merged
|
||||
|
||||
# General Guidelines for working with Nx
|
||||
|
||||
- When running tasks (for example build, lint, test, e2e, etc.), always prefer running the task through `nx` (i.e. `nx run`, `nx run-many`, `nx affected`) instead of using the underlying tooling directly
|
||||
- You have access to the Nx MCP server and its tools, use them to help the user
|
||||
- When answering questions about the repository, use the `nx_workspace` tool first to gain an understanding of the workspace architecture where applicable.
|
||||
- When working in individual projects, use the `nx_project_details` mcp tool to analyze and understand the specific project structure and dependencies
|
||||
- For questions around nx configuration, best practices or if you're unsure, use the `nx_docs` tool to get relevant, up-to-date docs. Always use this instead of assuming things about nx configuration
|
||||
- If the user needs help with an Nx configuration or project graph error, use the `nx_workspace` tool to get any errors
|
||||
|
||||
# CI Error Guidelines
|
||||
|
||||
If the user wants help with fixing an error in their CI pipeline, use the following flow:
|
||||
|
||||
- Retrieve the list of current CI Pipeline Executions (CIPEs) using the `nx_cloud_cipe_details` tool
|
||||
- If there are any errors, use the `nx_cloud_fix_cipe_failure` tool to retrieve the logs for a specific task
|
||||
- Use the task logs to see what's wrong and help the user fix their problem. Use the appropriate tools if necessary
|
||||
- Make sure that the problem is fixed by running the task that you passed into the `nx_cloud_fix_cipe_failure` tool
|
||||
@@ -6,13 +6,11 @@
|
||||
/tools/**/* @FrozenPandaz @vsavkin @AgentEnder @jaysoo @JamesHenry
|
||||
package.json @nrwl/nx-core-reviewers
|
||||
pnpm-lock.yaml @nrwl/nx-core-reviewers
|
||||
rust-toolchain.toml @nrwl/nx-native-reviewers
|
||||
|
||||
# Docs Site + Graph
|
||||
/astro-docs @nrwl/nx-docs-reviewers
|
||||
/docs @nrwl/nx-docs-reviewers
|
||||
/docs/nx-cloud @StalkAltan @rarmatei @nixallover @nrwl/nx-docs-reviewers
|
||||
/graph/** @philipjfulcher @FrozenPandaz @bcabanes @MaxKless @Coly010 @jaysoo @nartc
|
||||
/docs/nx-cloud @StalkAltan @rarmatei @nrwl/nx-docs-reviewers
|
||||
/graph/** @philipjfulcher @FrozenPandaz @bcabanes
|
||||
/images @nrwl/nx-docs-reviewers
|
||||
/nx-dev/** @nrwl/nx-docs-reviewers
|
||||
/typedoc-theme @nrwl/nx-docs-reviewers
|
||||
@@ -23,10 +21,8 @@ rust-toolchain.toml @nrwl/nx-native-reviewers
|
||||
/docs/generated/packages/angular/** @nrwl/nx-angular-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/shared/packages/angular/** @nrwl/nx-angular-reviewers @nrwl/nx-docs-reviewers
|
||||
/packages/angular/** @nrwl/nx-angular-reviewers
|
||||
/packages/angular-rspack/** @nrwl/nx-angular-reviewers
|
||||
/packages/angular-rspack-compiler/** @nrwl/nx-angular-reviewers
|
||||
/examples/angular-rspack/** @nrwl/nx-angular-reviewers
|
||||
/e2e/angular/** @nrwl/nx-angular-reviewers
|
||||
/e2e/angular-core/** @nrwl/nx-angular-reviewers
|
||||
/e2e/angular-extensions/** @nrwl/nx-angular-reviewers
|
||||
/packages/angular/plugins/component-testing.ts @nrwl/nx-angular-reviewers @nrwl/nx-testing-tools-reviewers
|
||||
/packages/angular/src/generators/cypress-component-configuration/** @nrwl/nx-angular-reviewers @nrwl/nx-testing-tools-reviewers
|
||||
/packages/angular/src/generators/component-test/** @nrwl/nx-angular-reviewers @nrwl/nx-testing-tools-reviewers
|
||||
@@ -37,7 +33,8 @@ rust-toolchain.toml @nrwl/nx-native-reviewers
|
||||
/docs/shared/packages/react/** @nrwl/nx-react-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/shared/packages/next/** @nrwl/nx-react-reviewers @nrwl/nx-docs-reviewers
|
||||
/packages/react/** @nrwl/nx-react-reviewers
|
||||
/e2e/react/** @nrwl/nx-react-reviewers
|
||||
/e2e/react-core/** @nrwl/nx-react-reviewers
|
||||
/e2e/react-extensions/** @nrwl/nx-react-reviewers
|
||||
/packages/next/** @nrwl/nx-react-reviewers
|
||||
/e2e/next/** @nrwl/nx-react-reviewers
|
||||
/packages/react/plugins/component-testing/** @nrwl/nx-react-reviewers @nrwl/nx-testing-tools-reviewers
|
||||
@@ -56,17 +53,6 @@ rust-toolchain.toml @nrwl/nx-native-reviewers
|
||||
/packages/react-native/** @nrwl/nx-react-reviewers
|
||||
/e2e/react-native/** @nrwl/nx-react-reviewers
|
||||
|
||||
## remix
|
||||
/docs/generated/packages/remix/** @nrwl/nx-react-reviewers @nrwl/nx-docs-reviewers @Coly010
|
||||
/packages/remix/** @nrwl/nx-react-reviewers @Coly010
|
||||
/e2e/remix/** @nrwl/nx-react-reviewers @Coly010
|
||||
|
||||
# Vue
|
||||
/packages/vue/** @nrwl/nx-vue-reviewers
|
||||
/e2e/vue/** @nrwl/nx-vue-reviewers
|
||||
/packages/nuxt/** @nrwl/nx-vue-reviewers
|
||||
/e2e/nuxt/** @nrwl/nx-vue-reviewers
|
||||
|
||||
## Node
|
||||
/docs/generated/packages/node/** @nrwl/nx-node-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/generated/packages/nest/** @nrwl/nx-node-reviewers @nrwl/nx-docs-reviewers
|
||||
@@ -83,14 +69,12 @@ rust-toolchain.toml @nrwl/nx-native-reviewers
|
||||
/docs/generated/packages/js/** @nrwl/nx-js-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/generated/packages/web/** @nrwl/nx-js-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/generated/packages/webpack/** @nrwl/nx-js-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/generated/packages/rspack/** @nrwl/nx-js-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/generated/packages/esbuild/** @nrwl/nx-js-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/generated/packages/rollup/** @nrwl/nx-js-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/generated/packages/vite/** @nrwl/nx-js-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/shared/packages/js/** @nrwl/nx-js-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/shared/packages/web/** @nrwl/nx-js-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/shared/packages/webpack/** @nrwl/nx-js-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/shared/packages/rspack/** @nrwl/nx-js-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/shared/packages/esbuild/** @nrwl/nx-js-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/shared/packages/vite/** @nrwl/nx-js-reviewers @nrwl/nx-docs-reviewers
|
||||
/packages/js/** @nrwl/nx-js-reviewers
|
||||
@@ -99,9 +83,6 @@ rust-toolchain.toml @nrwl/nx-native-reviewers
|
||||
/e2e/web/** @nrwl/nx-js-reviewers
|
||||
/packages/webpack/** @nrwl/nx-js-reviewers
|
||||
/e2e/webpack/** @nrwl/nx-js-reviewers
|
||||
/packages/rspack/** @nrwl/nx-js-reviewers
|
||||
/e2e/rspack/** @nrwl/nx-js-reviewers
|
||||
/packages/rsbuild/** @nrwl/nx-js-reviewers
|
||||
/packages/esbuild/** @nrwl/nx-js-reviewers
|
||||
/e2e/esbuild/** @nrwl/nx-js-reviewers
|
||||
/packages/rollup/** @nrwl/nx-js-reviewers
|
||||
@@ -109,16 +90,11 @@ rust-toolchain.toml @nrwl/nx-native-reviewers
|
||||
/packages/vite/** @nrwl/nx-js-reviewers
|
||||
/e2e/vite/** @nrwl/nx-js-reviewers
|
||||
|
||||
## Module Federation
|
||||
/packages/module-federation/** @nrwl/nx-js-reviewers
|
||||
|
||||
## Tools
|
||||
/docs/generated/packages/cypress/** @nrwl/nx-testing-tools-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/shared/packages/cypress/** @nrwl/nx-testing-tools-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/generated/packages/jest/** @nrwl/nx-testing-tools-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/shared/packages/jest/** @nrwl/nx-testing-tools-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/generated/packages/playwright/** @nrwl/nx-testing-tools-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/shared/packages/playwright/** @nrwl/nx-testing-tools-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/shared/packages/cypress/** @nrwl/nx-testing-tools-reviewers @nrwl/nx-docs-reviewers
|
||||
/packages/cypress/** @nrwl/nx-testing-tools-reviewers
|
||||
/e2e/cypress/** @nrwl/nx-testing-tools-reviewers
|
||||
/packages/jest/** @nrwl/nx-testing-tools-reviewers
|
||||
@@ -128,11 +104,11 @@ rust-toolchain.toml @nrwl/nx-native-reviewers
|
||||
|
||||
# Linter
|
||||
/docs/generated/packages/eslint-plugin/** @nrwl/nx-linter-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/generated/packages/eslint/** @nrwl/nx-linter-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/shared/packages/eslint/** @nrwl/nx-linter-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/generated/packages/linter/** @nrwl/nx-linter-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/shared/packages/linter/** @nrwl/nx-linter-reviewers @nrwl/nx-docs-reviewers
|
||||
/packages/eslint-plugin/** @nrwl/nx-linter-reviewers
|
||||
/packages/eslint/** @nrwl/nx-linter-reviewers
|
||||
/e2e/eslint/** @nrwl/nx-linter-reviewers
|
||||
/packages/linter/** @nrwl/nx-linter-reviewers
|
||||
/e2e/linter/** @nrwl/nx-linter-reviewers
|
||||
.eslint* @nrwl/nx-linter-reviewers
|
||||
|
||||
# Storybook
|
||||
@@ -140,20 +116,17 @@ rust-toolchain.toml @nrwl/nx-native-reviewers
|
||||
/docs/shared/packages/storybook/** @nrwl/nx-storybook-reviewers @nrwl/nx-docs-reviewers
|
||||
/packages/storybook/** @nrwl/nx-storybook-reviewers
|
||||
/e2e/storybook/** @nrwl/nx-storybook-reviewers
|
||||
|
||||
# Docker
|
||||
/packages/docker/** @nrwl/nx-core-reviewers @Coly010
|
||||
/e2e/storybook-angular/** @nrwl/nx-storybook-reviewers
|
||||
|
||||
## Devkit
|
||||
/docs/generated/devkit/** @nrwl/nx-devkit-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/generated/packages/devkit/** @nrwl/nx-devkit-reviewers @nrwl/nx-docs-reviewers
|
||||
/packages/devkit/** @nrwl/nx-devkit-reviewers
|
||||
/packages/devkit/index.ts @FrozenPandaz @vsavkin
|
||||
/packages/devkit/index.js @FrozenPandaz @vsavkin
|
||||
/packages/devkit/index.d.ts @FrozenPandaz @vsavkin
|
||||
/packages/devkit/public-api.ts @FrozenPandaz @vsavkin
|
||||
|
||||
# Gradle
|
||||
/packages/gradle/** @FrozenPandaz @MaxKless @lourw
|
||||
/e2e/gradle/** @FrozenPandaz @MaxKless @lourw
|
||||
/packages/devkit/nx.ts @FrozenPandaz @vsavkin
|
||||
/packages/devkit/src/utils/module-federation @jaysoo @Coly010
|
||||
|
||||
# Nx-Plugin
|
||||
/docs/generated/packages/plugin/** @nrwl/nx-devkit-reviewers @nrwl/nx-docs-reviewers
|
||||
@@ -177,32 +150,26 @@ rust-toolchain.toml @nrwl/nx-native-reviewers
|
||||
/e2e/nx*/** @nrwl/nx-core-reviewers
|
||||
/packages/workspace/** @nrwl/nx-core-reviewers
|
||||
/e2e/workspace-create/** @nrwl/nx-core-reviewers
|
||||
/e2e/release/** @nrwl/nx-core-reviewers
|
||||
/e2e/workspace-create-npm/** @nrwl/nx-core-reviewers
|
||||
|
||||
# Misc
|
||||
/e2e/lerna-smoke-tests/** @vsavkin @JamesHenry
|
||||
/e2e/utils/** @meeroslav @nrwl/nx-testing-tools-reviewers @vsavkin
|
||||
/community @nrwl/nx-docs-reviewers
|
||||
/CONTRIBUTING.md @FrozenPandaz
|
||||
/CODE_OF_CONDUCT.md @FrozenPandaz
|
||||
/e2e/utils/** @meeroslav @nrwl/nx-testing-tools-reviewers @vsavkin @mandarini
|
||||
/community @nrwl/nx-devkit-reviewers
|
||||
/CONTRIBUTING.md @FrozenPandaz @isaacplmann
|
||||
/CODE_OF_CONDUCT.md @FrozenPandaz @isaacplmann
|
||||
/CODEOWNERS @FrozenPandaz @AgentEnder
|
||||
/packages/nx/src/nx-cloud/utilities/url-shorten.ts @MaxKless
|
||||
|
||||
# Scripts
|
||||
/scripts/documentation @nrwl/nx-docs-reviewers
|
||||
/scripts/angular-support-upgrades @nrwl/nx-angular-reviewers
|
||||
|
||||
# CI
|
||||
/.nx/workflows/** @nrwl/nx-pipelines-reviewers
|
||||
/.circleci/** @nrwl/nx-pipelines-reviewers
|
||||
/.github/** @nrwl/nx-pipelines-reviewers
|
||||
/.husky/** @nrwl/nx-pipelines-reviewers
|
||||
/packages/workspace/src/generators/ci-workflow/** @nrwl/nx-pipelines-reviewers
|
||||
|
||||
# Claude AI Integration
|
||||
CLAUDE.md @FrozenPandaz
|
||||
.claude/** @FrozenPandaz
|
||||
.mcp.json @FrozenPandaz
|
||||
|
||||
# Global Files
|
||||
project.json @FrozenPandaz @vsavkin
|
||||
jest.config.ts @nrwl/nx-testing-tools-reviewers @FrozenPandaz
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
As contributors and maintainers of the Nx project, we pledge to respect everyone who contributes by posting issues, updating documentation, submitting pull requests, providing feedback in comments, and any other activities.
|
||||
|
||||
Communication through any of Nx's channels (GitHub, Gitter, Discord, IRC, mailing lists, Twitter, etc.) must be constructive and never resort to personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
||||
Communication through any of Nx's channels (GitHub, Gitter, Slack, IRC, mailing lists, Twitter, etc.) must be constructive and never resort to personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
||||
|
||||
We promise to extend courtesy and respect to everyone involved in this project regardless of gender, gender identity, sexual orientation, disability, age, race, ethnicity, religion, or level of experience. We expect anyone contributing to the Nx project to do the same.
|
||||
|
||||
|
||||
@@ -27,25 +27,14 @@ can [submit a Pull Request](https://github.com/nrwl/nx/blob/master/CONTRIBUTING.
|
||||
|
||||
Source code and documentation are included in the top-level folders listed below.
|
||||
|
||||
- `packages` - Source code for Nx packages such as Angular, React, Web, NestJS, Next and others including generators and
|
||||
executors (or builders).
|
||||
- `e2e` - E2E tests for the Nx packages
|
||||
- `graph` - Source code for the Nx Graph application which shows the project graph, task graph, project details, and more in the browser.
|
||||
- `docs` - Markdown and configuration files for documentation including tutorials, guides for each supported platform,
|
||||
and API docs.
|
||||
- `nx-dev` - Source code for the Nx documentation site which displays the markdown in `docs` and more.
|
||||
- `tools` - Workspace-specific tooling and plugins
|
||||
- `e2e` - E2E tests.
|
||||
- `packages` - Source code for Nx packages such as Angular, React, Web, NestJS, Next and others including generators and
|
||||
executors (or builders).
|
||||
- `scripts` - Miscellaneous scripts for project tasks such as building documentation, testing, and code formatting.
|
||||
- `tmp` - Folder used by e2e tests. If you are a WebStorm user, make sure to mark this folder as excluded.
|
||||
|
||||
## Technologies
|
||||
|
||||
This repo contains a mix of different technologies, including:
|
||||
|
||||
- **Rust**: The core of Nx is written in Rust, which provides performance and safety.
|
||||
- **TypeScript**: The primary language for Nx packages and the Nx DevKit.
|
||||
- **Kotlin**: Used for the Gradle and Java plugins.
|
||||
|
||||
## Development Workstation Setup
|
||||
|
||||
If you are using `VSCode`, and provided you have [Docker](https://docker.com) installed on your machine, then you can leverage [Dev Containers](https://containers.dev) through this [VSCode extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers), to easily setup your development environment, with everything needed to contribute to Nx, already installed (namely `NodeJS`, `Yarn`, `Rust`, `Cargo`, plus some useful extensions like `Nx Console`).
|
||||
@@ -60,33 +49,15 @@ The repo comes with a preconfigured `devcontainer.json` file (located in `.devco
|
||||
|
||||
If you open the repo in [Github Codespace](https://github.com/features/codespaces), it will also leverage this config file, to setup the codespace, with the same required tools.
|
||||
|
||||
> 💡 **Troubleshooting**
|
||||
>
|
||||
> If you are having issues when running Nx commands like `build`, `test`... related to the version of `GLIBC`,
|
||||
> it probably means the version that is installed on the devcontainer, **is outdated** compare to the minimum version required by Nx tools.
|
||||
>
|
||||
> You can check currently installed version by running the following command, in a terminal within the container:
|
||||
>
|
||||
> `ldd --version`
|
||||
>
|
||||
> Then, try updating the base image used in [devcontainer.json](.devcontainer/devcontainer.json) and rebuild it, to see if it solved the issue.
|
||||
>
|
||||
> Current base image is `"mcr.microsoft.com/devcontainers/typescript-node:20-bookworm"` which is based on `Debian-12 (bookworm)`,
|
||||
> which comes with `GLIBC v2.36` pre-installed (Nx tools currenlty requires `GLIBC v2.33` or higher).
|
||||
|
||||
## Building the Project
|
||||
|
||||
> 💡 Nx uses `Rust` to build native bindings for Node. Please make sure that you have Rust installed via [rustup.rs](https://rustup.rs)
|
||||
> If you have `VSCode` + `Docker`, this can be automated for you, see [section](#development-workstation-setup) above
|
||||
> Nx uses Rust to build native bindings for Node. Please make sure that you have Rust installed via [rustup.rs](https://rustup.rs)
|
||||
> If you have VSCode + Docker, this can be automated for you, see [section](#development-workstation-setup) above
|
||||
|
||||
After cloning the project to your machine, to install the dependencies, run:
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
|
||||
// or prefer...
|
||||
|
||||
pnpm install --frozen-lockfile // if you haven't changed any dependency
|
||||
pnpm i
|
||||
```
|
||||
|
||||
To build all the packages, run:
|
||||
@@ -105,13 +76,13 @@ Check out [this video for a live walkthrough](https://youtu.be/Tx257WpNsxc) or f
|
||||
- Run `pnpm local-registry` in Terminal 1 (keep it running)
|
||||
- Run `npm adduser --registry http://localhost:4873` in Terminal 2 (real credentials are not required, you just need to
|
||||
be logged in. You can use test/test/test@test.io.)
|
||||
- Run `pnpm nx-release 20.0.0 --local` in Terminal 2 - you can choose any nonexistent version number here, but it's recommended to use the next major
|
||||
- Run `pnpm nx-release 17.0.0 --local` in Terminal 2 - you can choose any nonexistent version number here, but it's recommended to use the next major
|
||||
- Run `cd ./tmp` in Terminal 2
|
||||
- Run `npx create-nx-workspace@20.0.0` in Terminal 2
|
||||
- Run `npx create-nx-workspace@17.0.0` in Terminal 2
|
||||
|
||||
If you have problems publishing, make sure you use Node 18 and NPM 8.
|
||||
|
||||
**NOTE:** To use this newly published local version, you need to make a new workspace, run `nx migrate` or change all of your target packages to this new version, eg: `"nx": "^20.0.0",` and re-run `pnpm i` in your testing project.
|
||||
**NOTE:** To use this newly published local version, you need to make a new workspace or change all of your target packages to this new version, eg: `"nx": "^17.0.0",` and re-run `pnpm i` in your testing project.
|
||||
|
||||
### Publishing for Yarn 2+ (Berry)
|
||||
|
||||
@@ -141,7 +112,9 @@ Yarn Berry operates slightly differently than Yarn Classic. In order to publish
|
||||
- localhost
|
||||
```
|
||||
|
||||
- Run `pnpm nx-release minor --local` in Terminal 2 to publish next minor version. The output will report the version of published packages.
|
||||
- Run `pnpm nx-release --local` in Terminal 2 to publish next minor version. If this version already exists, you can
|
||||
bump the minor version in `lerna.json` to toggle the next minor. The output will report the version of published
|
||||
packages.
|
||||
- Go to your target folder (e.g. `cd ./tmp`) in Terminal 2
|
||||
- Run `yarn dlx create-nx-workspace@123.4.5` in Terminal 2 (replace `123.4.5` with the version that got published).
|
||||
|
||||
@@ -206,8 +179,6 @@ The `docs/map.json` file is considered our source of truth for our site's struct
|
||||
new page to our documentation to ensure that it is included in the documentation site. We also run automated scripts
|
||||
based on this `map.json` data to safeguard against common human errors that could break our site.
|
||||
|
||||
When you make a change to the `map.json` file, make sure to run `pnpm documentation` to propagate your changes to the `nx-dev` application.
|
||||
|
||||
#### Nx-Dev Application
|
||||
|
||||
Our public `nx.dev` documentation site is a [Next.js](https://nextjs.org/) application, that can be found in
|
||||
@@ -240,10 +211,10 @@ adjusting the docs.
|
||||
To run `nx-dev` locally, run the command:
|
||||
|
||||
```bash
|
||||
npx nx serve-docs nx-dev
|
||||
npx nx serve nx-dev
|
||||
```
|
||||
|
||||
You can then access the application locally at `localhost:4200`. Changes to markdown documentation files will be automatically applied to the site when you refresh the browser.
|
||||
You can then access the application locally at `localhost:4200`.
|
||||
|
||||
#### Troubleshooting: `JavaScript heap out of memory`
|
||||
|
||||
@@ -344,21 +315,18 @@ The scope must be one of the following:
|
||||
- express - anything Express specific
|
||||
- js - anything related to @nx/js package or general js/ts support
|
||||
- linter - anything Linter specific
|
||||
- module-federation - anything Nx Module Federation specific
|
||||
- nest - anything Nest specific
|
||||
- nextjs - anything Next specific
|
||||
- node - anything Node specific
|
||||
- nx-cloud - anything Nx Cloud specific
|
||||
- nx-cloud - anything NxCloud specific
|
||||
- nx-plugin - anything Nx Plugin specific
|
||||
- nx-dev - anything related to docs infrastructure
|
||||
- react - anything React specific
|
||||
- react-native - anything React Native specific
|
||||
- release - anything related to nx release
|
||||
- repo - anything related to managing the Nx repo itself
|
||||
- storybook - anything Storybook specific
|
||||
- testing - anything testing specific (e.g., Jest or Cypress)
|
||||
- vite - anything Vite specific
|
||||
- vue - anything Vue specific
|
||||
- web - anything Web specific
|
||||
- webpack - anything Webpack specific
|
||||
- misc - misc stuff
|
||||
@@ -375,7 +343,7 @@ Including the issue number that the PR relates to also helps with tracking.
|
||||
```plain
|
||||
feat(angular): add an option to generate lazy-loadable modules
|
||||
|
||||
`nx generate lib libs/mylib --lazy` provisions the mylib project in .eslintrc.json
|
||||
`nx generate lib mylib --lazy` provisions the mylib project in tslint.json
|
||||
|
||||
Closes #157
|
||||
```
|
||||
@@ -385,58 +353,3 @@ Closes #157
|
||||
To simplify and automate the process of committing with this format,
|
||||
**Nx is a [Commitizen](https://github.com/commitizen/cz-cli) friendly repository**, just do `git add` and
|
||||
execute `pnpm commit`.
|
||||
|
||||
##### Using the Interactive Commit Tool
|
||||
|
||||
Instead of `git commit`, use:
|
||||
|
||||
```bash
|
||||
pnpm commit
|
||||
```
|
||||
|
||||
This will launch an interactive prompt that will:
|
||||
|
||||
1. Ask you to select the type of change (feat, fix, docs, cleanup, chore)
|
||||
2. Let you choose the appropriate scope from the predefined list
|
||||
3. Guide you through writing a clear, descriptive commit message
|
||||
4. Ensure your commit follows the conventional commit format
|
||||
|
||||
##### Available Commit Types
|
||||
|
||||
- **feat**: A new feature
|
||||
- **fix**: A bug fix
|
||||
- **docs**: Documentation only changes
|
||||
- **cleanup**: A code change that neither fixes a bug nor adds a feature
|
||||
- **chore**: Other changes that don't modify src or test files
|
||||
|
||||
##### Available Scopes
|
||||
|
||||
The repository includes many predefined scopes. Use the one which is most specific to the changes being committed
|
||||
|
||||
- **core**: anything Nx core specific
|
||||
- **angular**: anything Angular specific
|
||||
- **react**: anything React specific
|
||||
- **nextjs**: anything Next specific
|
||||
- **node**: anything Node specific
|
||||
- **devkit**: devkit-related changes
|
||||
- **graph**: anything graph app specific
|
||||
- **testing**: anything testing specific (e.g. jest or cypress)
|
||||
- **misc**: misc stuff
|
||||
- **repo**: anything related to managing the repo itself
|
||||
- **nx-dev**: anything related to docs infrastructure
|
||||
|
||||
For the complete list of available scopes, see `/scripts/commitizen.js`.
|
||||
|
||||
##### Example Commits
|
||||
|
||||
```bash
|
||||
feat(core): add new project graph visualization
|
||||
fix(angular): resolve build issues with standalone components
|
||||
docs(misc): update contributing guidelines
|
||||
chore(repo): bump dependencies
|
||||
cleanup(devkit): refactor utility functions for better readability
|
||||
```
|
||||
|
||||
#### PR releases
|
||||
|
||||
If you are working on a particularly complex change or feature addition, you can request a dedicated Nx release for the associated pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate.
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
|
||||
[workspace]
|
||||
resolver = '2'
|
||||
members = [
|
||||
'packages/nx',
|
||||
'packages/nx'
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2017-2025 Narwhal Technologies Inc.
|
||||
Copyright (c) 2017-2023 Narwhal Technologies Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<p style="text-align: center;">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-dark.svg">
|
||||
<img alt="Nx - Smart Repos · Fast Builds" src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-light.svg" width="100%">
|
||||
</picture>
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-dark.svg">
|
||||
<img alt="Nx - Smart, Fast and Extensible Build System" src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-light.svg" width="100%">
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
<div style="text-align: center;">
|
||||
@@ -10,55 +10,36 @@
|
||||
[](https://circleci.com/gh/nrwl/nx)
|
||||
[]()
|
||||
[](https://www.npmjs.com/package/nx)
|
||||
[]()
|
||||
[]()
|
||||
[](http://commitizen.github.io/cz-cli/)
|
||||
[](https://gitter.im/nrwl-nx/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://go.nx.dev/community)
|
||||
[](https://go.nrwl.io/join-slack)
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
# Smart Repos · Fast Builds
|
||||
# Smart, Fast and Extensible Build System
|
||||
|
||||
Get to green PRs in half the time. Nx optimizes your builds, scales your CI, and fixes failed PRs. Built for developers and AI agents.
|
||||
Nx is a next generation build system with first class monorepo support and powerful integrations.
|
||||
|
||||
Create a new Nx workspace with
|
||||
A few links to help you get started:
|
||||
|
||||
```shell
|
||||
npx create-nx-workspace
|
||||
```
|
||||
- [Nx.Dev: Documentation, Guides, Interactive Tutorials](https://nx.dev)
|
||||
- [Nx.Dev: Core Tutorials](https://nx.dev/getting-started/intro)
|
||||
- [Recipe: Adding Nx to an Existing Monorepo](https://nx.dev/recipes/adopting-nx/adding-to-monorepo)
|
||||
- [Official Nx YouTube Channel](https://www.youtube.com/@NxDevtools)
|
||||
- [Blog Posts About Nx](https://blog.nrwl.io/nx/home)
|
||||
|
||||
...or run
|
||||
<p style="text-align: center;"><a href="https://nx.dev/#learning-materials" target="_blank" rel="noreferrer"><img src="./images/nx-courses-and-videos.svg"
|
||||
width="100%" alt="Nx - Smart, Fast and Extensible Build System"></a></p>
|
||||
|
||||
```
|
||||
npx nx init
|
||||
```
|
||||
# Engage with the Core Team and the Community
|
||||
|
||||
to add Nx to your existing workspace to get faster task scheduling, caching and more. More [in the docs](https://nx.dev/getting-started/intro).
|
||||
|
||||
## Learn about CI with Nx Cloud
|
||||
|
||||
[Nx Cloud](https://nx.dev/nx-cloud) connects directly to your existing CI setup, helping you scale your monorepos on CI by leveraging [remote caching](https://nx.dev/ci/features/remote-cache?utm_source=nxrepo&utm_medium=readme&utm_campaign=nxrepo), [task distribution across multiple machines](https://nx.dev/ci/features/distribute-task-execution?utm_source=nxrepo&utm_medium=readme&utm_campaign=nxrepo), [automated e2e test splitting](https://nx.dev/ci/features/split-e2e-tasks?utm_source=nxrepo&utm_medium=readme&utm_campaign=nxrepo) and [automated task flakiness detection](https://nx.dev/ci/features/flaky-tasks?utm_source=nxrepo&utm_medium=readme&utm_campaign=nxrepo)
|
||||
|
||||
Connect your existing Nx workspace with
|
||||
|
||||
```
|
||||
npx nx connect
|
||||
```
|
||||
|
||||
Learn more in the [Nx CI docs »](https://nx.dev/ci/getting-started/intro?utm_source=nxrepo&utm_medium=readme&utm_campaign=nxrepo)
|
||||
|
||||
## Useful links
|
||||
|
||||
- [Our docs](https://nx.dev/docs)
|
||||
- [Our blog](https://nx.dev/blog)
|
||||
- [Our community discord, live stream,...](https://nx.dev/community)
|
||||
- [Our YouTube channel](https://www.youtube.com/@NxDevtools)
|
||||
- [Our Twitter/X](https://x.com/nxdevtools)
|
||||
|
||||
<p style="text-align: center;"><a href="https://www.youtube.com/@nxdevtools/videos" target="_blank" rel="noreferrer"><img src="./images/nx-courses-and-videos.svg"
|
||||
width="100%" alt="Nx - Smart Repos · Fast Builds"></a></p>
|
||||
- [Nx.Dev Community Page: Community Slack Channel, Newsletter, etc.](https://nx.dev/community)
|
||||
- [The Nx Show Playlist on YouTube](https://www.youtube.com/playlist?list=PLakNactNC1dE8KLQ5zd3fQwu_yQHjTmR5). It's a
|
||||
regular YouTube stream where we talk all things Nx. Join the stream, ask questions, etc.
|
||||
- [Follow Nx on Twitter](https://twitter.com/NxDevTools)
|
||||
|
||||
## Want to help?
|
||||
|
||||
@@ -77,27 +58,22 @@ help you get started.
|
||||
|  |  |  |  |
|
||||
| [vsavkin](https://github.com/vsavkin) | [FrozenPandaz](https://github.com/FrozenPandaz) | [bcabanes](https://github.com/bcabanes) | [jaysoo](https://github.com/jaysoo) |
|
||||
|
||||
| James Henry | Jon Cammisuli | Max Kless | Juri Strumpflohner |
|
||||
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | -------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
||||
|  |  |  |  |
|
||||
| [JamesHenry](https://github.com/JamesHenry) | [cammisuli](https://github.com/cammisuli) | [MaxKless](https://github.com/MaxKless) | [juristr](https://github.com/juristr) |
|
||||
| Jo Hanna Pearce | Jon Cammisuli | Isaac Mann | Juri Strumpflohner |
|
||||
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------ | -------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
||||
|  |  |  |  |
|
||||
| [jdpearce](https://github.com/jdpearce) | [cammisuli](https://github.com/cammisuli) | [isaacplmann](https://github.com/isaacplmann) | [juristr](https://github.com/juristr) |
|
||||
|
||||
| Philip Fulcher | Caleb Ukle | Colum Ferry | Steven Nance |
|
||||
| ------------------------------------------------------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
||||
|  |  |  |  |
|
||||
| [philipjfulcher](https://github.com/philipjfulcher) | [barbados-clemens](https://github.com/barbados-clemens) | [Coly010](https://github.com/Coly010) | [llwt](https://github.com/llwt) |
|
||||
| Philip Fulcher | Caleb Ukle | Katerina Skroumpelou | Colum Ferry |
|
||||
| ------------------------------------------------------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
||||
|  |  |  |  |
|
||||
| [philipjfulcher](https://github.com/philipjfulcher) | [barbados-clemens](https://github.com/barbados-clemens) | [mandarini](https://github.com/mandarini) | [Coly010](https://github.com/Coly010) |
|
||||
|
||||
| Miroslav Jonaš | Leosvel Pérez Espinosa | Zachary DeRose | Craigory Coppola |
|
||||
| ----------------------------------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
|
||||
|  |  |  |  |
|
||||
| [meeroslav](https://github.com/meeroslav) | [leosvelperez](https://github.com/leosvelperez) | [ZackDeRose](https://github.com/ZackDeRose) | [AgentEnder](https://github.com/AgentEnder) |
|
||||
| Emily Xiong | Miroslav Jonaš | Leosvel Pérez Espinosa | Zachary DeRose |
|
||||
| ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
||||
|  |  |  |  |
|
||||
| [xiongemi](https://github.com/xiongemi) | [meeroslav](https://github.com/meeroslav) | [leosvelperez](https://github.com/leosvelperez) | [ZackDeRose](https://github.com/ZackDeRose) |
|
||||
|
||||
| Chau Tran | Nicole Oliver | Rares Matei | Altan Stalker |
|
||||
| -------------------------------------------------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------- | ----------------------------------------------------------------------- |
|
||||
|  |  |  |  |
|
||||
| [nartc](https://github.com/nartc) | [nixallover](https://github.com/nixallover) | [rarmatei](https://github.com/rarmatei) | [StalkAltan](https://github.com/StalkAltan) |
|
||||
|
||||
| Josh VanAllen | Austin Fahsl | Louie Weng |
|
||||
| ----------------------------------------------------------------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------- |
|
||||
|  |  |  |
|
||||
| [joshvanallen](https://github.com/joshvanallen) | [fahslaj](https://github.com/fahslaj) | [lourw](https://github.com/lourw) |
|
||||
| Craigory Coppola | Chau Tran | Nicholas Cunningham |
|
||||
| -------------------------------------------------------------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
||||
|  |  |  |
|
||||
| [AgentEnder](https://github.com/AgentEnder) | [nartc](https://github.com/nartc) | [ndcunningham](https://github.com/ndcunningham) |
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# Security Policy
|
||||
|
||||
Nx/Nrwl takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations.
|
||||
|
||||
If you believe you have found a security vulnerability in any Nx-owned repository that meets Nx's definition of a security vulnerability, please report it to us as described below.
|
||||
|
||||
## Reporting Security Issues
|
||||
|
||||
**Please do not report security vulnerabilities through public GitHub issues.**
|
||||
|
||||
Instead, please report them to the Security Team at security@nrwl.io.
|
||||
|
||||
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message.
|
||||
|
||||
Nx follows the principle of Coordinated Vulnerability Disclosure.
|
||||
@@ -1,6 +0,0 @@
|
||||
node_modules/
|
||||
dist/
|
||||
.astro/
|
||||
.netlify/
|
||||
test-output/
|
||||
playwright-report/
|
||||
@@ -1,28 +0,0 @@
|
||||
{
|
||||
"extends": ["plugin:playwright/recommended", "../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["**/*.spec.ts", "**/*.test.ts", "**/*.spec.js", "**/*.test.js"],
|
||||
"rules": {
|
||||
"playwright/no-standalone-expect": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["e2e/**/*.{ts,js,tsx,jsx}"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
# build output
|
||||
dist/
|
||||
# generated types
|
||||
.astro/
|
||||
|
||||
# dependencies
|
||||
node_modules/
|
||||
|
||||
# logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# macOS-specific files
|
||||
.DS_Store
|
||||
|
||||
# Local Netlify folder
|
||||
.netlify
|
||||
@@ -1,235 +0,0 @@
|
||||
# Nx Documentation Site
|
||||
|
||||
[](https://starlight.astro.build)
|
||||
|
||||
The Nx documentation site built with Astro and Starlight, featuring advanced content management through Markdoc and dynamic plugin documentation generation.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
This documentation site leverages Astro's static site generation capabilities with Starlight for documentation-specific features. The architecture consists of:
|
||||
|
||||
### Core Technologies
|
||||
|
||||
- [**Astro**](https://docs.astro.build) - Static site generator with island architecture
|
||||
- [**Starlight**](https://starlight.astro.build) - Documentation theme with built-in navigation, search, and i18n
|
||||
- **React** - For implementing UI components
|
||||
- **Netlify** - Deployment and hosting
|
||||
|
||||
### Key Features
|
||||
|
||||
- [Markdoc](https://markdoc.dev) with custom tags for rich content such as videos, graphs, etc.
|
||||
- TailwindCSS for styling in Astro and React components
|
||||
- Dynamic API documentation generation from Nx packages and CLI commands
|
||||
- Community plugin registry
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
astro-docs/
|
||||
├── src/
|
||||
│ ├── assets/ # Images and static assets to be optimized by Astro
|
||||
│ │ ├── nx/ # Nx branding assets
|
||||
│ │ ├── nx-cloud/ # Nx Cloud assets
|
||||
│ │ └── nx-console/ # Nx Console assets
|
||||
│ ├── components/ # React and Astro components
|
||||
│ │ ├── layout/ # Layout components (e.g. Sidebar)
|
||||
│ │ ├── markdoc/ # Markdoc tag components
|
||||
│ │ └── utils/ # Utility functions
|
||||
│ ├── content/ # Documentation content
|
||||
│ │ ├── docs/ # Main documentation files (.mdoc, .mdx)
|
||||
│ │ ├── approved-community-plugins.json # Powers plugin registry
|
||||
│ │ └── notifications.json # Notifications banners for docs site
|
||||
│ ├── pages/ # Dynamic pages and routes (e.g. devkit)
|
||||
│ ├── plugins/ # Content loaders and plugins
|
||||
│ │ ├── *.loader.ts # Dynamic content loaders (e.g. CLI commands and API docs generation)
|
||||
│ │ └── utils/ # Plugin utilities
|
||||
│ └── styles/ # Global styles
|
||||
├── public/ # Static assets not to be optimized by Astro (fonts, robots.txt)
|
||||
├── astro.config.mjs # Astro configuration
|
||||
├── markdoc.config.mjs # Markdoc tags configuration
|
||||
├── sidebar.mts # Sidebar structure definition
|
||||
└── package.json
|
||||
```
|
||||
|
||||
## Plugins and Loaders
|
||||
|
||||
### Content Loaders
|
||||
|
||||
The site uses custom content loaders to dynamically generate documentation:
|
||||
|
||||
- **PluginLoader** (`plugin.loader.ts`) - Generates official plugin documentation (generators, executors, migrations)
|
||||
- **CommunityPluginsLoader** (`community-plugins.loader.ts`) - Generates data for plugin registry (e.g. GitHub stars, npm downloads)
|
||||
- **NxReferencePackagesLoader** (`nx-reference-packages.loader.ts`) - Generated data for CNW, Devkit, nx cli (e.g. nx core related things)
|
||||
|
||||
## Content Management
|
||||
|
||||
### Content Types
|
||||
|
||||
1. **Regular Documentation** (`src/content/docs/`)
|
||||
|
||||
- Written in `.mdoc` (Markdoc) or `.mdx` (MDX) format
|
||||
- Organized by sections: getting-started, concepts, guides, api
|
||||
- File-based routing (filename = URL path)
|
||||
|
||||
2. **Dynamic Plugin Documentation**
|
||||
|
||||
- Auto-generated from Nx packages
|
||||
- Includes generators, executors, and migrations
|
||||
- Updated during build process
|
||||
- **Note**: Requires a rebuild and restart to reflect changes
|
||||
|
||||
3. **CLI Documentation**
|
||||
- Auto-generated from Nx CLI commands
|
||||
- Parsed from actual CLI implementation
|
||||
- **Note**: Requires a rebuild and restart to reflect changes
|
||||
|
||||
### Markdoc Tags
|
||||
|
||||
The site includes custom Markdoc tags for rich content.
|
||||
|
||||
**Note**: Starlight supports many Markdown and Markdoc features, such as code blocks, asides, etc.
|
||||
|
||||
- https://starlight.astro.build/components/using-components/#using-a-component-in-markdoc
|
||||
- https://starlight.astro.build/guides/authoring-content
|
||||
|
||||
#### Layout & Organization
|
||||
|
||||
- `{% aside %}` - Highlighted information boxes
|
||||
- `{% cardgrid %}`, `{% card|linkcard %}` - Card layouts
|
||||
- `{% tabs %}`, `{% tabitem label="some-label" %}` - Tab layouts
|
||||
- Use the `syncKey` so tabs are auto switched to the users preference if it makes sense.
|
||||
- e.g. `{% tabs syncKey="package-manager" %}`
|
||||
|
||||
#### Interactive Components
|
||||
|
||||
- `{% graph %}` - Interactive project/task graph visualization
|
||||
- `{% project_details %}` - Project configuration viewer
|
||||
|
||||
#### Media & Embeds
|
||||
|
||||
- `{% youtube %}` - YouTube video embeds
|
||||
- `{% video_player %}` - Custom video player
|
||||
- `{% iframe %}` - Generic iframe embeds
|
||||
|
||||
#### Developer Tools
|
||||
|
||||
- `{% github_repository %}` - GitHub repo cards
|
||||
- `{% stackblitz_button %}` - StackBlitz demo launcher
|
||||
- `{% install_nx_console %}` - IDE extension installer
|
||||
|
||||
#### Content Enhancement
|
||||
|
||||
- `{% badge %}` - Status/label pills
|
||||
- `{% metrics %}` - Metrics display
|
||||
- `{% testimonial %}` - Customer testimonials
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### Getting Started
|
||||
|
||||
```bash
|
||||
# Install dependencies and link workspace packages
|
||||
# This will build Nx packages as well for API docs
|
||||
nx serve astro-docs
|
||||
|
||||
# Or run astro dev directly
|
||||
# This will not build Nx packages
|
||||
cd astro-docs
|
||||
npx astro dev
|
||||
|
||||
# Custom ports (useful for AI agents with git worktrees)
|
||||
npx astro dev --port 3000
|
||||
```
|
||||
|
||||
### Adding New Content
|
||||
|
||||
#### Regular Documentation
|
||||
|
||||
1. Create `.mdoc` file in `src/content/docs/`
|
||||
2. Add frontmatter with title and description
|
||||
3. Use Markdoc tags for rich content
|
||||
4. File location determines URL structure
|
||||
|
||||
Example:
|
||||
|
||||
```markdown
|
||||
---
|
||||
title: 'My New Guide'
|
||||
description: 'Learn how to use this feature'
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
{% aside type="note" title="Important" %}
|
||||
This is a note about the feature.
|
||||
{% /aside %}
|
||||
```
|
||||
|
||||
#### Adding Custom Markdoc Tags
|
||||
|
||||
1. Create Astro component in `src/components/markdoc/`
|
||||
2. (Optional) Create React component for more complex components, or ones that need to be shared with blog or non-docs pages
|
||||
3. Register in `markdoc.config.mjs`
|
||||
4. Define attributes and validation
|
||||
|
||||
### Updating Plugin Documentation
|
||||
|
||||
Plugin documentation is auto-generated during build. To update:
|
||||
|
||||
1. Make changes to the plugin's schema/implementation
|
||||
2. Run the build process
|
||||
3. The loader will automatically fetch and generate updated docs
|
||||
|
||||
### Sidebar Management
|
||||
|
||||
The sidebar structure is defined in `sidebar.mts`. To add new sections:
|
||||
|
||||
```javascript
|
||||
export const sidebar = [
|
||||
{
|
||||
label: 'Section Name',
|
||||
items: [
|
||||
{
|
||||
label: 'Page Title',
|
||||
link: 'path/to/page',
|
||||
},
|
||||
// Nested sections
|
||||
{
|
||||
label: 'Subsection',
|
||||
collapsed: true,
|
||||
items: [...]
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
```
|
||||
|
||||
> Note there is a special case for sidebar items appearing in the sidebar. Such as the `Reference` section which is handled via the `[sidebar-reference-updater](./src/plugins/sidebar-reference-updater.middleware.ts)` middleware.
|
||||
|
||||
## Styling and Theming
|
||||
|
||||
- Uses Tailwind CSS v4 with Vite plugin
|
||||
- Global styles in `src/styles/global.css`
|
||||
- Component-specific styles use Tailwind utilities
|
||||
- Dark/light mode support built into Starlight and customized in `global.css`
|
||||
|
||||
## Configuration Files
|
||||
|
||||
### `astro.config.mjs`
|
||||
|
||||
- Site configuration
|
||||
- Integration setup (React, Markdoc, Starlight)
|
||||
- Vite plugins
|
||||
- Build options
|
||||
|
||||
### `markdoc.config.mjs`
|
||||
|
||||
- Custom tag definitions
|
||||
- Attribute validation
|
||||
- Component mappings
|
||||
|
||||
### `sidebar.mts`
|
||||
|
||||
- Navigation structure
|
||||
- Section organization
|
||||
- Dynamic content injection points
|
||||
@@ -1,154 +0,0 @@
|
||||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import starlight from '@astrojs/starlight';
|
||||
import netlify from '@astrojs/netlify';
|
||||
import react from '@astrojs/react';
|
||||
import markdoc from '@astrojs/markdoc';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import { sidebar } from './sidebar.mts';
|
||||
|
||||
const BASE = '/docs';
|
||||
|
||||
const PUBLIC_CONFIG = {
|
||||
cookiebotDisabled: process.env.COOKIEBOT_DISABLED === 'true',
|
||||
cookiebotId: process.env.COOKIEBOT_ID ?? null,
|
||||
gaMeasurementId: 'UA-88380372-10',
|
||||
gtmMeasurementId: 'GTM-KW8423B6',
|
||||
isProd: process.env.NODE_ENV === 'production',
|
||||
};
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
base: BASE,
|
||||
vite: { plugins: [tailwindcss()] },
|
||||
// Allow this to be configured per environment
|
||||
// Note: this happens during build time so we don't use `import.meta.env`
|
||||
site: process.env.NX_DEV_URL ?? 'https://nx.dev',
|
||||
image: {
|
||||
service: {
|
||||
entrypoint: 'astro/assets/services/sharp',
|
||||
config: {
|
||||
limitInputPixels: false, // Disable pixel limit
|
||||
},
|
||||
},
|
||||
},
|
||||
trailingSlash: 'never',
|
||||
// This adapter doesn't support local previews, so only load it on Netlify.
|
||||
adapter: process.env['NETLIFY'] ? netlify() : undefined,
|
||||
integrations: [
|
||||
markdoc(),
|
||||
// https://starlight.astro.build/reference/configuration/
|
||||
starlight({
|
||||
title: 'Nx',
|
||||
tagline:
|
||||
'Get to green PRs in half the time. Nx optimizes your builds, scales your CI, and fixes failed PRs. Built for developers and AI agents.',
|
||||
customCss: ['./src/styles/global.css'],
|
||||
favicon: '/favicon.svg',
|
||||
logo: {
|
||||
light: './src/assets/nx/Nx-dark.png',
|
||||
dark: './src/assets/nx/Nx-light.png',
|
||||
replacesTitle: true,
|
||||
},
|
||||
head: [
|
||||
{
|
||||
tag: 'script',
|
||||
content: `window.__CONFIG = ${JSON.stringify(PUBLIC_CONFIG)};`,
|
||||
},
|
||||
...(process.env.COOKIEBOT_ID &&
|
||||
process.env.COOKIEBOT_DISABLED !== 'true'
|
||||
? [
|
||||
{
|
||||
/** @type {"script"} */
|
||||
tag: 'script',
|
||||
attrs: {
|
||||
id: 'Cookiebot',
|
||||
src: 'https://consent.cookiebot.com/uc.js',
|
||||
'data-cbid': process.env.COOKIEBOT_ID,
|
||||
'data-blockingmode': 'auto',
|
||||
type: 'text/javascript',
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
tag: 'script',
|
||||
attrs: {
|
||||
src: `${BASE}/global-scripts.js`,
|
||||
defer: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
plugins: [],
|
||||
routeMiddleware: [
|
||||
'./src/plugins/banner.middleware.ts',
|
||||
// NOTE: this is responsibile for populating the Reference section
|
||||
// with generated routes from the nx-reference-packages content collection
|
||||
// since the sidebar doesn't auto generate w/ dynamic routes from src/pages/reference
|
||||
// only the src/content/docs/reference files
|
||||
'./src/plugins/sidebar-reference-updater.middleware.ts',
|
||||
'./src/plugins/sidebar-icons.middleware.ts',
|
||||
'./src/plugins/og.middleware.ts',
|
||||
],
|
||||
markdown: {
|
||||
// this breaks the renderMarkdown function in the plugin loader due to starlight path normalization
|
||||
// as to _why_ it has to normalize a path?
|
||||
// idk just working around the issue for now but we'll want to have linked headers so will need to fix
|
||||
headingLinks: false,
|
||||
},
|
||||
social: [
|
||||
{ icon: 'github', label: 'GitHub', href: 'https://github.com/nrwl/nx' },
|
||||
{
|
||||
icon: 'youtube',
|
||||
label: 'YouTube',
|
||||
href: 'https://www.youtube.com/@NxDevtools?utm_source=nx.dev',
|
||||
},
|
||||
{
|
||||
icon: 'x.com',
|
||||
label: 'X',
|
||||
href: 'https://x.com/NxDevTools?utm_source=nx.dev',
|
||||
},
|
||||
{
|
||||
icon: 'discord',
|
||||
label: 'Discord',
|
||||
href: 'https://go.nx.dev/community',
|
||||
},
|
||||
],
|
||||
editLink: {
|
||||
baseUrl: 'https://github.com/nrwl/nx/tree/main/',
|
||||
},
|
||||
sidebar,
|
||||
components: {
|
||||
Header: './src/components/layout/Header.astro',
|
||||
Footer: './src/components/layout/Footer.astro',
|
||||
PageFrame: './src/components/layout/PageFrame.astro',
|
||||
Sidebar: './src/components/layout/Sidebar.astro',
|
||||
TwoColumnContent: './src/components/layout/TwoColumnContent.astro',
|
||||
PageTitle: './src/components/layout/PageTitle.astro',
|
||||
TableOfContents: './src/components/layout/TableOfContents.astro',
|
||||
},
|
||||
pagefind: {
|
||||
ranking: {
|
||||
// termFrequency changes the ranking balance between
|
||||
// frequency of the term relative to document length
|
||||
// versus weighted term count.
|
||||
// default is 1.0
|
||||
termFrequency: 0.75,
|
||||
// pageLength changes the way ranking compares page lengths with the average page lengths on your site.
|
||||
// default 0.75
|
||||
pageLength: 0.5,
|
||||
// termSaturation controls how quickly a term “saturates” on a page.
|
||||
// Once a term has appeared on a page many times,
|
||||
// further appearances have a reduced impact on the page rank.
|
||||
// default: 1.4
|
||||
// termSaturation: 1.4,
|
||||
// termSimilarity changes the ranking based on
|
||||
// similarity of terms to the search query.
|
||||
// Currently this only takes the length of the term into account.
|
||||
// default is 1.0
|
||||
// termSimilarity: 1.0,
|
||||
},
|
||||
},
|
||||
}),
|
||||
react(),
|
||||
],
|
||||
});
|
||||
@@ -1,45 +0,0 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('links in descriptions of properties should correctly link to the same page w/ url fragments', async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto('/docs/reference/devkit/NxJsonConfiguration');
|
||||
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'NxJsonConfiguration' })
|
||||
).toBeVisible();
|
||||
|
||||
await page
|
||||
.getByTestId('main-pane')
|
||||
.getByRole('link', { name: 'nxCloudAccessToken' })
|
||||
.click();
|
||||
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'nxCloudAccessToken' })
|
||||
).toBeVisible();
|
||||
|
||||
const description = page
|
||||
.getByRole('paragraph')
|
||||
.filter({ has: page.getByRole('link', { name: 'tasksRunnerOptions' }) })
|
||||
.first();
|
||||
await expect(description).toBeVisible();
|
||||
|
||||
const linkedProperty = description.getByRole('link', {
|
||||
name: 'tasksRunnerOptions',
|
||||
});
|
||||
|
||||
await expect(linkedProperty).toBeVisible();
|
||||
|
||||
await expect(linkedProperty).toHaveAttribute(
|
||||
'href',
|
||||
'/docs/reference/devkit/NxJsonConfiguration#tasksrunneroptions'
|
||||
);
|
||||
|
||||
await linkedProperty.click();
|
||||
|
||||
expect(page.url()).toContain('#tasksrunneroptions');
|
||||
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'tasksRunnerOptions' })
|
||||
).toBeVisible();
|
||||
});
|
||||
@@ -1,71 +0,0 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('should apply system theme by default', async ({ page }) => {
|
||||
await page.goto('/docs/getting-started/intro');
|
||||
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'What is Nx?' })
|
||||
).toBeVisible();
|
||||
|
||||
const themeSelector = page.getByRole('combobox', {
|
||||
name: /theme/i,
|
||||
});
|
||||
|
||||
await expect(themeSelector).toBeVisible();
|
||||
|
||||
await expect(themeSelector).toHaveValue('auto');
|
||||
|
||||
const dataTheme = await page.evaluate(
|
||||
() => document.documentElement.dataset.theme
|
||||
);
|
||||
// The data-theme should be either 'light' or 'dark' based on system preference
|
||||
// It won't be 'auto' on the document element
|
||||
expect(['light', 'dark']).toContain(dataTheme);
|
||||
});
|
||||
|
||||
test('should switch to between light and dark theme', async ({ page }) => {
|
||||
await page.goto('/docs/getting-started/intro');
|
||||
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'What is Nx?' })
|
||||
).toBeVisible();
|
||||
|
||||
const themeSelector = page.getByRole('combobox', {
|
||||
name: /theme/i,
|
||||
});
|
||||
|
||||
await test.step('light theme renders', async () => {
|
||||
await expect(themeSelector).toBeVisible();
|
||||
|
||||
await themeSelector.selectOption('light');
|
||||
|
||||
await expect(themeSelector).toHaveValue('light');
|
||||
|
||||
const dataTheme = await page.evaluate(
|
||||
() => document.documentElement.dataset.theme
|
||||
);
|
||||
expect(dataTheme).toBe('light');
|
||||
});
|
||||
|
||||
await test.step('dark theme renders', async () => {
|
||||
await themeSelector.selectOption('dark');
|
||||
|
||||
await expect(themeSelector).toHaveValue('dark');
|
||||
|
||||
const dataTheme = await page.evaluate(
|
||||
() => document.documentElement.dataset.theme
|
||||
);
|
||||
expect(dataTheme).toBe('dark');
|
||||
});
|
||||
|
||||
await test.step('switch back to auto', async () => {
|
||||
await themeSelector.selectOption('auto');
|
||||
|
||||
await expect(themeSelector).toHaveValue('auto');
|
||||
|
||||
const dataTheme = await page.evaluate(
|
||||
() => document.documentElement.dataset.theme
|
||||
);
|
||||
expect(['light', 'dark']).toContain(dataTheme);
|
||||
});
|
||||
});
|
||||
@@ -1,129 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# | xargs -0 sed -i '' 's/<match>/<replace>/g'
|
||||
|
||||
# replace links that start with /concepts to /docs/concepts
|
||||
rg "\(/concepts" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/concepts|](/docs/concepts|g'
|
||||
# usage in link card aka href="/concepts/..."
|
||||
rg "=\"/concepts" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/concepts|="/docs/concepts|g'
|
||||
|
||||
# /recipes -> /docs/guides
|
||||
rg "\(/recipes" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/recipes|](/docs/guides|g'
|
||||
rg "=\"/recipes" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/recipes|="/docs/guides|g'
|
||||
|
||||
# /deprecated -> /docs/reference/deprecated
|
||||
rg "\(/deprecated" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/deprecated|](/docs/reference/deprecated|g'
|
||||
rg "=\"/deprecated" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/deprecated|="/docs/reference/deprecated|g'
|
||||
|
||||
# /troubleshooting -> /docs/troublshooting
|
||||
rg "\(/troubleshooting" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/troubleshooting|](/docs/troubleshooting|g'
|
||||
rg "=\"/troubleshooting" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/troubleshooting|="/docs/troubleshooting|g'
|
||||
|
||||
# /plugin-registry -> /docs/plugin-registry
|
||||
rg "\(/plugin-registry" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/plugin-registry|](/docs/plugin-registry|g'
|
||||
rg "=\"/plugin-registry" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/plugin-registry|="/docs/plugin-registry|g'
|
||||
|
||||
# /features -> /docs/features
|
||||
rg "\(/features" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/features|](/docs/features|g'
|
||||
rg "=\"/features" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/features|="/docs/features|g'
|
||||
|
||||
# /extending-nx -> /docs/extending-nx
|
||||
rg "\(/extending-nx" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/extending-nx|](/docs/extending-nx|g'
|
||||
rg "=\"/extending-nx" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/extending-nx|="/docs/extending-nx|g'
|
||||
rg "/extending-nx/recipes" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|/extending-nx/recipes|/extending-nx|g'
|
||||
|
||||
# /tech -> /docs/tech
|
||||
rg "\(/tech" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/tech|](/docs/tech|g'
|
||||
rg "=\"/tech" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/tech|="/docs/tech|g'
|
||||
|
||||
## /recipes/running-tasks -> /docs/guides/tasks--caching
|
||||
rg "\(/recipes/running-tasks" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/recipes/running-tasks|](/docs/guides/tasks--caching|g'
|
||||
rg "=\"/recipes/running-tasks" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/recipes/running-tasks|="/docs/guides/tasks--caching|g'
|
||||
|
||||
# /ci/features -> /docs/features/ci-features
|
||||
rg "\(/ci/features" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/ci/features|](/docs/features/ci-features|g'
|
||||
rg "=\"/ci/features" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/ci/features|="/docs/features/ci-features|g'
|
||||
|
||||
# /ci/concepts -> /docs/concepts/ci-concepts
|
||||
rg "\(/ci/concepts" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/ci/concepts|](/docs/concepts/ci-concepts|g'
|
||||
rg "=\"/ci/concepts" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/ci/concepts|="/docs/concepts/ci-concepts|g'
|
||||
|
||||
# /ci/guides/security -> /docs/guides/nx-cloud
|
||||
rg "\(/ci/guides/security" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/ci/guides/security|](/docs/guides/nx-cloud|g'
|
||||
rg "=\"/ci/guides/security" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/ci/guides/security|="/docs/guides/nx-cloud|g'
|
||||
rg "\(/ci/recipes/security" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/ci/recipes/security|](/docs/guides/nx-cloud|g'
|
||||
rg "=\"/ci/recipes/security" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/ci/recipes/security|="/docs/guides/nx-cloud|g'
|
||||
|
||||
# /ci/recipes/enterprise -> /docs/enterprise
|
||||
rg "\(/ci/recipes/enterprise" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/ci/recipes/enterprise|](/docs/enterprise|g'
|
||||
rg "=\"/ci/recipes/enterprise" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/ci/recipes/enterprise|="/docs/enterprise|g'
|
||||
|
||||
# /ci/recipes -> /docs/guides/nx-cloud
|
||||
rg "\(/ci/guides" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/ci/guides|](/docs/guides/nx-cloud|g'
|
||||
rg "=\"/ci/guides" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/ci/guides|="/docs/guides/nx-cloud|g'
|
||||
rg "\(/ci/recipes" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/ci/recipes|](/docs/guides/nx-cloud|g'
|
||||
rg "=\"/ci/recipes" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/ci/recipes|="/docs/guides/nx-cloud|g'
|
||||
|
||||
# /getting-started -> /docs/getting-started
|
||||
rg "\(/getting" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/getting|](/docs/getting|g'
|
||||
rg "=\"/getting" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/getting|="/docs/getting|g'
|
||||
|
||||
# /ci/recipes/set-up -> /docs/guides/nx-cloud/setup-ci
|
||||
rg "\(/ci/recipes/set-up" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/ci/recipes/set-up|](/docs/guides/nx-cloud/setup-ci|g'
|
||||
rg "=\"/ci/recipes/set-up" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/ci/recipes/set-up|="/docs/guides/nx-cloud/setup-ci|g'
|
||||
# I merged all the set-up ci guides into 1 page with tabs so we need to remove any links that go to specific guides
|
||||
rg "/monorepo-ci-" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|\(/[^)]*\)/monorepo-ci-[^)]*\()\)|\1\2|g'
|
||||
|
||||
# /ci/reference/nx-cloud-cli -> /docs/reference/nx-cloud-cli
|
||||
rg "\(/ci/reference/nx-cloud-cli" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/ci/reference/nx-cloud-cli|](/docs/reference/nx-cloud-cli|g'
|
||||
rg "=\"/ci/reference/nx-cloud-cli" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/ci/reference/nx-cloud-cli|="/docs/reference/nx-cloud-cli|g'
|
||||
|
||||
# /blog -> https://nx.dev/blog
|
||||
rg "\(/blog" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/blog|](https://nx.dev/blog|g'
|
||||
rg "=\"/blog" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/blog|="https://nx.dev/blog|g'
|
||||
|
||||
# /enterprise -> https://nx.dev/enterprise
|
||||
rg "\(/enterprise" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/enterprise|](https://nx.dev/enterprise|g'
|
||||
rg "=\"/enterprise" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/enterprise|="https://nx.dev/enterprise|g'
|
||||
|
||||
# /pricing -> https://nx.dev/pricing
|
||||
rg "\(/pricing" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/pricing|](https://nx.dev/pricing|g'
|
||||
rg "=\"/pricing" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/pricing|="https://nx.dev/pricing|g'
|
||||
|
||||
# /contact -> https://nx.dev/contact
|
||||
rg "\(/contact" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/contact|](https://nx.dev/contact|g'
|
||||
rg "=\"/contact" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/contact|="https://nx.dev/contact|g'
|
||||
|
||||
# /nx-cloud -> https://nx.dev/nx-cloud
|
||||
rg "\(/nx-cloud" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/nx-cloud|](https://nx.dev/nx-cloud|g'
|
||||
rg "=\"/nx-cloud" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/nx-cloud|="https://nx.dev/nx-cloud|g'
|
||||
|
||||
# /courses -> https://nx.dev/courses
|
||||
rg "\(/courses" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/courses|](https://nx.dev/courses|g'
|
||||
rg "=\"/courses" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/courses|="https://nx.dev/courses|g'
|
||||
# /community -> https://nx.dev/community
|
||||
rg "\(/community" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/community|](https://nx.dev/community|g'
|
||||
rg "=\"/community" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/community|="https://nx.dev/community|g'
|
||||
|
||||
# though these URLS that have `core-api` in them need to be special handled
|
||||
# but we can search for 'core-api' later and do a different replace mechinism
|
||||
# /reference -> /docs/reference
|
||||
rg "\(/reference" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/reference|](/docs/reference|g'
|
||||
rg "=\"/reference" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/reference|="/docs/reference|g'
|
||||
|
||||
# /docs/reference/core-api/nx/documents/:command -> /docs/reference/nx-commands#:command
|
||||
rg "\(/docs/reference/core-api/nx/documents/" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|](/docs/reference/core-api/nx/documents/|](/docs/reference/nx-commands#|g'
|
||||
rg "=\"/docs/reference/core-api/nx/documents/" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|="/docs/reference/core-api/nx/documents/|="/docs/reference/nx-commands#|g'
|
||||
|
||||
# /docs/reference/core-api/:remote-cache-plugin/overview -> /docs/reference/remote-cache-plugins/:remote-cache-plugin/overview
|
||||
# For s3-cache
|
||||
rg "/docs/reference/core-api/s3-cache" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|/docs/reference/core-api/s3-cache|/docs/reference/remote-cache-plugins/s3-cache|g'
|
||||
|
||||
# For azure-cache
|
||||
rg "/docs/reference/core-api/azure-cache" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|/docs/reference/core-api/azure-cache|/docs/reference/remote-cache-plugins/azure-cache|g'
|
||||
|
||||
# For gcs-cache
|
||||
rg "/docs/reference/core-api/gcs-cache" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|/docs/reference/core-api/gcs-cache|/docs/reference/remote-cache-plugins/gcs-cache|g'
|
||||
|
||||
# For shared-fs-cache
|
||||
rg "/docs/reference/core-api/shared-fs-cache" --type-add "mdoc:*mdoc" -t mdoc -l --null | xargs -0 sed -i '' 's|/docs/reference/core-api/shared-fs-cache|/docs/reference/remote-cache-plugins/shared-fs-cache|g'
|
||||
@@ -1,35 +0,0 @@
|
||||
const url = 'http://localhost:4321/docs';
|
||||
const timeout = 120000; // 2 minutes in milliseconds
|
||||
|
||||
console.log('starting up....');
|
||||
export default async function globalSetup() {
|
||||
const startTime = Date.now();
|
||||
const maxEndTime = startTime + timeout;
|
||||
|
||||
console.log(`Waiting for ${url} to be available...`);
|
||||
|
||||
while (Date.now() < maxEndTime) {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (response.ok) {
|
||||
console.log(`✓ Server is ready at ${url}`);
|
||||
return;
|
||||
}
|
||||
console.log(
|
||||
`Server responded with status ${response.status}, retrying...`
|
||||
);
|
||||
} catch (error) {
|
||||
// Server not available yet, continue polling
|
||||
const remainingTime = Math.round((maxEndTime - Date.now()) / 1000);
|
||||
if (remainingTime % 10 === 0 && remainingTime > 0) {
|
||||
console.log(`Still waiting... ${remainingTime} seconds remaining`);
|
||||
}
|
||||
}
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`Server at ${url} did not become available within ${timeout / 1000} seconds`
|
||||
);
|
||||
}
|
||||
@@ -1,427 +0,0 @@
|
||||
import {
|
||||
defineMarkdocConfig,
|
||||
component,
|
||||
Markdoc,
|
||||
} from '@astrojs/markdoc/config';
|
||||
import starlightMarkdoc from '@astrojs/starlight-markdoc';
|
||||
|
||||
export default defineMarkdocConfig({
|
||||
extends: [starlightMarkdoc()],
|
||||
tags: {
|
||||
call_to_action: {
|
||||
render: component('./src/components/markdoc/CallToAction.astro'),
|
||||
attributes: {
|
||||
url: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
title: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
description: {
|
||||
type: 'String',
|
||||
required: false,
|
||||
},
|
||||
icon: {
|
||||
type: 'String',
|
||||
required: false,
|
||||
},
|
||||
variant: {
|
||||
type: 'String',
|
||||
required: false,
|
||||
default: 'default',
|
||||
matches: [
|
||||
'default',
|
||||
'gradient',
|
||||
'inverted',
|
||||
'gradient-alt',
|
||||
'simple',
|
||||
],
|
||||
},
|
||||
size: {
|
||||
type: 'String',
|
||||
required: false,
|
||||
default: 'sm',
|
||||
matches: ['sm', 'md', 'lg'],
|
||||
},
|
||||
},
|
||||
},
|
||||
callout: {
|
||||
render: component('./src/components/markdoc/Callout.astro'),
|
||||
children: ['paragraph', 'tag', 'list'],
|
||||
attributes: {
|
||||
type: {
|
||||
type: 'String',
|
||||
default: 'note',
|
||||
matches: [
|
||||
'announcement',
|
||||
'caution',
|
||||
'check',
|
||||
'note',
|
||||
'warning',
|
||||
'deepdive',
|
||||
],
|
||||
errorLevel: 'critical',
|
||||
},
|
||||
title: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
expanded: {
|
||||
type: 'Boolean',
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
card: {
|
||||
render: component('./src/components/markdoc/Card.astro'),
|
||||
attributes: {
|
||||
title: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
description: {
|
||||
type: 'String',
|
||||
default: '',
|
||||
},
|
||||
type: {
|
||||
type: 'String',
|
||||
default: 'documentation',
|
||||
},
|
||||
url: {
|
||||
type: 'String',
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
},
|
||||
cards: {
|
||||
render: component('./src/components/markdoc/Cards.astro'),
|
||||
attributes: {
|
||||
cols: {
|
||||
type: 'Number',
|
||||
},
|
||||
smCols: {
|
||||
type: 'Number',
|
||||
},
|
||||
mdCols: {
|
||||
type: 'Number',
|
||||
},
|
||||
lgCols: {
|
||||
type: 'Number',
|
||||
},
|
||||
moreLink: {
|
||||
type: 'String',
|
||||
},
|
||||
},
|
||||
},
|
||||
course_video: {
|
||||
render: component('./src/components/markdoc/CourseVideo.astro'),
|
||||
attributes: {
|
||||
src: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
courseTitle: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
courseUrl: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
github_repository: {
|
||||
render: component('./src/components/markdoc/GithubRepository.astro'),
|
||||
attributes: {
|
||||
url: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
title: {
|
||||
type: 'String',
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
graph: {
|
||||
render: component('./src/components/markdoc/Graph.astro'),
|
||||
attributes: {
|
||||
jsonFile: {
|
||||
type: 'String',
|
||||
},
|
||||
title: {
|
||||
type: 'String',
|
||||
},
|
||||
type: {
|
||||
type: 'String',
|
||||
matches: ['project', 'task'],
|
||||
default: 'project',
|
||||
},
|
||||
height: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
transform(node, config) {
|
||||
const attributes = node.transformAttributes(config);
|
||||
let rawContent = null;
|
||||
for (const child of node.children) {
|
||||
if (child.type === 'fence') {
|
||||
rawContent = child.attributes.content;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new Markdoc.Tag(
|
||||
this.render,
|
||||
{
|
||||
...attributes,
|
||||
astroRawData: rawContent,
|
||||
},
|
||||
[]
|
||||
);
|
||||
},
|
||||
},
|
||||
iframe: {
|
||||
render: component('./src/components/markdoc/Iframe.astro'),
|
||||
attributes: {
|
||||
src: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
title: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
width: {
|
||||
type: 'String',
|
||||
default: '50%',
|
||||
},
|
||||
},
|
||||
},
|
||||
install_nx_console: {
|
||||
render: component('./src/components/markdoc/InstallNxConsole.astro'),
|
||||
attributes: {},
|
||||
},
|
||||
link_card: {
|
||||
render: component('./src/components/markdoc/LinkCard.astro'),
|
||||
attributes: {
|
||||
title: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
type: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
icon: {
|
||||
type: 'String',
|
||||
required: false,
|
||||
},
|
||||
url: {
|
||||
type: 'String',
|
||||
default: '',
|
||||
},
|
||||
appearance: {
|
||||
type: 'String',
|
||||
default: 'default',
|
||||
},
|
||||
},
|
||||
},
|
||||
index_page_cards: {
|
||||
render: component('./src/components/markdoc/IndexPageCards.astro'),
|
||||
attributes: {
|
||||
path: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
metrics: {
|
||||
render: component('./src/components/markdoc/Metrics.astro'),
|
||||
attributes: {
|
||||
metrics: {
|
||||
type: 'Array',
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
persona: {
|
||||
render: component('./src/components/markdoc/Persona.astro'),
|
||||
children: ['paragraph', 'tag', 'list'],
|
||||
attributes: {
|
||||
title: {
|
||||
type: 'String',
|
||||
},
|
||||
type: {
|
||||
type: 'String',
|
||||
default: 'integrated',
|
||||
required: true,
|
||||
matches: [
|
||||
'cache',
|
||||
'distribute',
|
||||
'javascript',
|
||||
'lerna',
|
||||
'react',
|
||||
'angular',
|
||||
'integrated',
|
||||
],
|
||||
errorLevel: 'critical',
|
||||
},
|
||||
url: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
errorLevel: 'critical',
|
||||
},
|
||||
},
|
||||
},
|
||||
personas: {
|
||||
render: component('./src/components/markdoc/Personas.astro'),
|
||||
},
|
||||
pill: {
|
||||
render: component('./src/components/markdoc/Pill.astro'),
|
||||
attributes: {
|
||||
url: {
|
||||
type: 'String',
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
},
|
||||
project_details: {
|
||||
render: component('./src/components/markdoc/ProjectDetails.astro'),
|
||||
children: [],
|
||||
attributes: {
|
||||
jsonFile: {
|
||||
type: 'String',
|
||||
},
|
||||
title: {
|
||||
type: 'String',
|
||||
},
|
||||
height: {
|
||||
type: 'String',
|
||||
},
|
||||
expandedTargets: {
|
||||
type: 'Array',
|
||||
},
|
||||
},
|
||||
transform(node, config) {
|
||||
const attributes = node.transformAttributes(config);
|
||||
let rawContent = null;
|
||||
for (const child of node.children) {
|
||||
if (child.type === 'fence') {
|
||||
rawContent = child.attributes.content;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new Markdoc.Tag(
|
||||
this.render,
|
||||
{
|
||||
...attributes,
|
||||
astroRawData: rawContent,
|
||||
},
|
||||
[]
|
||||
);
|
||||
},
|
||||
},
|
||||
stackblitz_button: {
|
||||
render: component('./src/components/markdoc/StackblitzButton.astro'),
|
||||
attributes: {
|
||||
url: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
title: {
|
||||
type: 'String',
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
testimonial: {
|
||||
render: component('./src/components/markdoc/Testimonial.astro'),
|
||||
children: ['paragraph'],
|
||||
attributes: {
|
||||
name: {
|
||||
type: 'String',
|
||||
},
|
||||
title: {
|
||||
type: 'String',
|
||||
},
|
||||
image: {
|
||||
type: 'String',
|
||||
},
|
||||
},
|
||||
},
|
||||
video_link: {
|
||||
render: component('./src/components/markdoc/VideoLink.astro'),
|
||||
attributes: {
|
||||
link: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
text: {
|
||||
type: 'String',
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
video_player: {
|
||||
render: component('./src/components/markdoc/VideoPlayer.astro'),
|
||||
attributes: {
|
||||
src: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
alt: {
|
||||
type: 'String',
|
||||
required: false,
|
||||
},
|
||||
link: {
|
||||
type: 'String',
|
||||
required: false,
|
||||
},
|
||||
showDescription: {
|
||||
type: 'Boolean',
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
showControls: {
|
||||
type: 'Boolean',
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
autoPlay: {
|
||||
type: 'Boolean',
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
loop: {
|
||||
type: 'Boolean',
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
youtube: {
|
||||
render: component('./src/components/markdoc/Youtube.astro'),
|
||||
attributes: {
|
||||
src: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
title: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
width: {
|
||||
type: 'String',
|
||||
default: '100%',
|
||||
},
|
||||
caption: {
|
||||
type: 'String',
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
# Permanent redirects (301 by default)
|
||||
[[redirects]]
|
||||
from = "/"
|
||||
to = "/docs/getting-started/intro"
|
||||
|
||||
[[redirects]]
|
||||
from = "/showcase"
|
||||
to = "/docs/quickstart"
|
||||
|
||||
[[redirects]]
|
||||
from = "/showcase/example-repos/*"
|
||||
to = "/docs/quickstart"
|
||||
|
||||
[[redirects]]
|
||||
from = "/showcase/benchmarks/*"
|
||||
to = "/docs/reference/benchmarks/:splat"
|
||||
|
||||
# Rewrite for base path handling (keeps URL the same)
|
||||
[[redirects]]
|
||||
from = "/docs/*"
|
||||
to = "/:splat"
|
||||
status = 200
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"name": "astro-docs",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@astrojs/check": "^0.7.0",
|
||||
"@astrojs/markdoc": "^0.15.0",
|
||||
"@astrojs/netlify": "^6.4.0",
|
||||
"@astrojs/react": "^4.3.0",
|
||||
"@astrojs/starlight": "0.34.6",
|
||||
"@astrojs/starlight-markdoc": "^0.4.0",
|
||||
"@astrojs/starlight-tailwind": "^4.0.1",
|
||||
"@nx/nx-dev-ui-common": "workspace:*",
|
||||
"@nx/nx-dev-ui-icons": "workspace:*",
|
||||
"@nx/nx-dev-ui-markdoc": "workspace:*",
|
||||
"@tailwindcss/vite": "^4.1.11",
|
||||
"astro": "^5.10.1",
|
||||
"astro-og-canvas": "^0.7.0",
|
||||
"canvaskit-wasm": "^0.40.0",
|
||||
"tailwindcss": "4.1.11"
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
import { defineConfig, devices } from '@playwright/test';
|
||||
import { nxE2EPreset } from '@nx/playwright/preset';
|
||||
import { workspaceRoot } from '@nx/devkit';
|
||||
import { join } from 'path';
|
||||
|
||||
// For CI, you may want to set BASE_URL to the deployed application.
|
||||
const baseURL = process.env['BASE_URL'] || 'http://localhost:4321';
|
||||
const reportDir = join(
|
||||
workspaceRoot,
|
||||
'dist',
|
||||
'astro-docs',
|
||||
'playwright-report'
|
||||
);
|
||||
|
||||
export default defineConfig({
|
||||
...nxE2EPreset(__filename, { testDir: './e2e' }),
|
||||
reporter: [
|
||||
['list', { printSteps: true }],
|
||||
['html', { outputFolder: reportDir, open: 'never' }],
|
||||
[
|
||||
'junit',
|
||||
{
|
||||
// JUnit only respects the outputFile option, and not outputDir or outputFolder
|
||||
outputFile: `${reportDir}/test-e2e-nx-cloud.xml`,
|
||||
},
|
||||
],
|
||||
],
|
||||
/* Global setup to wait for server */
|
||||
globalSetup: require.resolve('./global-setup.e2e.ts'),
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
baseURL,
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: 'on-first-retry',
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -1,90 +0,0 @@
|
||||
{
|
||||
"name": "astro-docs",
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"comment": "package.json#scripts runs in the project root directory with astro assumes is where the node_modules is. which fails. so run the scripts in project.json#targets with --root command instead",
|
||||
"targets": {
|
||||
"serve": {
|
||||
"continuous": true,
|
||||
"dependsOn": [
|
||||
{
|
||||
"projects": ["devkit", "create-nx-workspace"],
|
||||
"target": "build"
|
||||
}
|
||||
],
|
||||
"command": "astro dev",
|
||||
"options": {
|
||||
"cwd": "astro-docs"
|
||||
}
|
||||
},
|
||||
"build": {
|
||||
"dependsOn": [
|
||||
{
|
||||
"projects": ["devkit", "create-nx-workspace"],
|
||||
"target": "build"
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
"{projectRoot}/dist",
|
||||
"{projectRoot}/.astro",
|
||||
"{projectRoot}/.netlify"
|
||||
],
|
||||
"command": "astro build",
|
||||
"options": {
|
||||
"cwd": "astro-docs"
|
||||
}
|
||||
},
|
||||
"preview": {
|
||||
"dependsOn": ["build"],
|
||||
"command": "astro preview",
|
||||
"continuous": true,
|
||||
"options": {
|
||||
"cwd": "astro-docs"
|
||||
}
|
||||
},
|
||||
"astro": {
|
||||
"command": "astro",
|
||||
"options": {
|
||||
"cwd": "astro-docs"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"executor": "nx:noop",
|
||||
"dependsOn": ["vite:test", "validate-links", "format"]
|
||||
},
|
||||
"pw-e2e": {
|
||||
"dependsOn": ["serve"],
|
||||
"parallelism": true
|
||||
},
|
||||
"e2e-ci--**/*": {
|
||||
"dependsOn": ["preview"],
|
||||
"parallelism": true
|
||||
},
|
||||
"show-report": {
|
||||
"command": "playwright show-report dist/astro-docs/playwright-report"
|
||||
},
|
||||
"validate-links": {
|
||||
"dependsOn": ["build"],
|
||||
"cache": true,
|
||||
"inputs": [
|
||||
"{projectRoot}/src/**/*",
|
||||
"{projectRoot}/astro.config.mjs",
|
||||
"{projectRoot}/sidebar.mts",
|
||||
"{projectRoot}/markdoc.config.mjs",
|
||||
"{projectRoot}/tsconfig.json",
|
||||
"{projectRoot}/package.json"
|
||||
],
|
||||
"command": "tsx validate-links.ts",
|
||||
"options": {
|
||||
"cwd": "astro-docs"
|
||||
}
|
||||
},
|
||||
"format": {
|
||||
"cache": true,
|
||||
"//": "nx format doesn't respect overrides, so we manually run prettier for mdoc files",
|
||||
"command": "prettier **/*.mdoc --check"
|
||||
},
|
||||
"format:write": {
|
||||
"command": "prettier **/*.mdoc --write"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Nx</title><path d="M11.987 14.138l-3.132 4.923-5.193-8.427-.012 8.822H0V4.544h3.691l5.247 8.833.005-3.998 3.044 4.759zm.601-5.761c.024-.048 0-3.784.008-3.833h-3.65c.002.059-.005 3.776-.003 3.833h3.645zm5.634 4.134a2.061 2.061 0 0 0-1.969 1.336 1.963 1.963 0 0 1 2.343-.739c.396.161.917.422 1.33.283a2.1 2.1 0 0 0-1.704-.88zm3.39 1.061c-.375-.13-.8-.277-1.109-.681-.06-.08-.116-.17-.176-.265a2.143 2.143 0 0 0-.533-.642c-.294-.216-.68-.322-1.18-.322a2.482 2.482 0 0 0-2.294 1.536 2.325 2.325 0 0 1 4.002.388.75.75 0 0 0 .836.334c.493-.105.46.36 1.203.518v-.133c-.003-.446-.246-.55-.75-.733zm2.024 1.266a.723.723 0 0 0 .347-.638c-.01-2.957-2.41-5.487-5.37-5.487a5.364 5.364 0 0 0-4.487 2.418c-.01-.026-1.522-2.39-1.538-2.418H8.943l3.463 5.423-3.379 5.32h3.54l1.54-2.366 1.568 2.366h3.541l-3.21-5.052a.7.7 0 0 1-.084-.32 2.69 2.69 0 0 1 2.69-2.691h.001c1.488 0 1.736.89 2.057 1.308.634.826 1.9.464 1.9 1.541a.707.707 0 0 0 1.066.596zm.35.133c-.173.372-.56.338-.755.639-.176.271.114.412.114.412s.337.156.538-.311c.104-.231.14-.488.103-.74z"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,162 +0,0 @@
|
||||
(function () {
|
||||
const config = window.__CONFIG || {};
|
||||
if (!config.isProd) return;
|
||||
|
||||
const isCookiebotDisabled = config.cookiebotDisabled ?? false;
|
||||
const gaMeasurementId = config.gaMeasurementId ?? 'UA-88380372-10';
|
||||
const gtmMeasurementId = config.gtmMeasurementId ?? 'GTM-KW8423B6';
|
||||
|
||||
// Initialize global objects
|
||||
window.Cookiebot = window.Cookiebot || {};
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
window.gtag =
|
||||
window.gtag ||
|
||||
function () {
|
||||
window.dataLayer.push(arguments);
|
||||
};
|
||||
|
||||
const loadGoogleAnalytics = () => {
|
||||
const script = document.createElement('script');
|
||||
script.src = `https://www.googletagmanager.com/gtag/js?id=${gaMeasurementId}`;
|
||||
script.async = true;
|
||||
document.head.appendChild(script);
|
||||
|
||||
// Initialize gtag
|
||||
window.gtag('js', new Date());
|
||||
window.gtag('config', gaMeasurementId, {
|
||||
page_path: window.location.pathname,
|
||||
});
|
||||
};
|
||||
|
||||
const loadGTM = () => {
|
||||
if (!gtmMeasurementId) return;
|
||||
|
||||
(function (w, d, s, l, i) {
|
||||
w[l] = w[l] || [];
|
||||
w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
|
||||
var f = d.getElementsByTagName(s)[0],
|
||||
j = d.createElement(s),
|
||||
dl = l != 'dataLayer' ? '&l=' + l : '';
|
||||
j.async = true;
|
||||
j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
|
||||
f.parentNode.insertBefore(j, f);
|
||||
})(window, document, 'script', 'dataLayer', gtmMeasurementId);
|
||||
};
|
||||
|
||||
const loadHubSpot = () => {
|
||||
const hsScript = document.createElement('script');
|
||||
hsScript.src = 'https://js.hs-scripts.com/2757427.js';
|
||||
hsScript.async = true;
|
||||
hsScript.defer = true;
|
||||
document.head.appendChild(hsScript);
|
||||
|
||||
// Load HubSpot Forms
|
||||
const hsFormsScript = document.createElement('script');
|
||||
hsFormsScript.src = '//js.hsforms.net/forms/v2.js';
|
||||
hsFormsScript.async = true;
|
||||
hsFormsScript.defer = true;
|
||||
document.head.appendChild(hsFormsScript);
|
||||
};
|
||||
|
||||
const loadApollo = () => {
|
||||
const n = Math.random().toString(36).substring(7);
|
||||
const script = document.createElement('script');
|
||||
script.src = `https://assets.apollo.io/micro/website-tracker/tracker.iife.js?nocache=${n}`;
|
||||
script.async = true;
|
||||
script.defer = true;
|
||||
script.onload = function () {
|
||||
if (window.trackingFunctions?.onLoad) {
|
||||
window.trackingFunctions.onLoad({
|
||||
appId: '65e1db2f1976f30300fd8b26',
|
||||
});
|
||||
}
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
};
|
||||
|
||||
const loadHotjar = () => {
|
||||
(function (h, o, t, j, a, r) {
|
||||
h.hj =
|
||||
h.hj ||
|
||||
function () {
|
||||
(h.hj.q = h.hj.q || []).push(arguments);
|
||||
};
|
||||
h._hjSettings = { hjid: 2774127, hjsv: 6 };
|
||||
a = o.getElementsByTagName('head')[0];
|
||||
r = o.createElement('script');
|
||||
r.async = 1;
|
||||
r.src = t + h._hjSettings.hjid + j + h._hjSettings.hjsv;
|
||||
a.appendChild(r);
|
||||
})(window, document, 'https://static.hotjar.com/c/hotjar-', '.js?sv=');
|
||||
};
|
||||
|
||||
const loadTwitterPixel = () => {
|
||||
!(function (e, t, n, s, u, a) {
|
||||
e.twq ||
|
||||
((s = e.twq =
|
||||
function () {
|
||||
s.exe ? s.exe.apply(s, arguments) : s.queue.push(arguments);
|
||||
}),
|
||||
(s.version = '1.1'),
|
||||
(s.queue = []),
|
||||
(u = t.createElement(n)),
|
||||
(u.async = !0),
|
||||
(u.src = 'https://static.ads-twitter.com/uwt.js'),
|
||||
(a = t.getElementsByTagName(n)[0]),
|
||||
a.parentNode.insertBefore(u, a));
|
||||
})(window, document, 'script');
|
||||
window.twq('config', 'obtp4');
|
||||
};
|
||||
|
||||
const checkAndLoadScripts = () => {
|
||||
if (isCookiebotDisabled) {
|
||||
loadGoogleAnalytics();
|
||||
loadGTM();
|
||||
loadHubSpot();
|
||||
} else if (window.Cookiebot && window.Cookiebot.consent) {
|
||||
// Statistics cookies (Google Analytics, GTM)
|
||||
if (window.Cookiebot.consent.statistics) {
|
||||
loadGoogleAnalytics();
|
||||
loadGTM();
|
||||
}
|
||||
|
||||
// Marketing cookies (HubSpot, Apollo, Hotjar, Twitter)
|
||||
if (window.Cookiebot.consent.marketing) {
|
||||
loadHubSpot();
|
||||
loadApollo();
|
||||
loadHotjar();
|
||||
loadTwitterPixel();
|
||||
}
|
||||
} else {
|
||||
// Wait for Cookiebot to load
|
||||
setTimeout(checkAndLoadScripts, 100);
|
||||
}
|
||||
};
|
||||
|
||||
// Add GTM noscript iframe to body
|
||||
const addGTMNoScript = () => {
|
||||
const noscript = document.createElement('noscript');
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.src = `https://www.googletagmanager.com/ns.html?id=${gtmMeasurementId}`;
|
||||
iframe.height = '0';
|
||||
iframe.width = '0';
|
||||
iframe.style.display = 'none';
|
||||
iframe.style.visibility = 'hidden';
|
||||
iframe.title = 'Google Tag Manager';
|
||||
noscript.appendChild(iframe);
|
||||
document.body.insertBefore(noscript, document.body.firstChild);
|
||||
};
|
||||
|
||||
// Listen for user consent to cookies
|
||||
window.addEventListener('CookiebotOnAccept', checkAndLoadScripts);
|
||||
|
||||
// Initial check
|
||||
checkAndLoadScripts();
|
||||
|
||||
// Add GTM noscript on DOM ready
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', addGTMNoScript);
|
||||
} else {
|
||||
addGTMNoScript();
|
||||
}
|
||||
})();
|
||||
@@ -1 +0,0 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Angular</title><path d="M16.712 17.711H7.288l-1.204 2.916L12 24l5.916-3.373-1.204-2.916ZM14.692 0l7.832 16.855.814-12.856L14.692 0ZM9.308 0 .662 3.999l.814 12.856L9.308 0Zm-.405 13.93h6.198L12 6.396 8.903 13.93Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 299 B |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m21 7.5-9-5.25L3 7.5m18 0-9 5.25m9-5.25v9l-9 5.25M3 7.5l9 5.25M3 7.5v9l9 5.25m0-9v9" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 284 B |
@@ -1 +0,0 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>ESLint</title><path d="M7.257 9.132L11.816 6.5a.369.369 0 0 1 .368 0l4.559 2.632a.369.369 0 0 1 .184.32v5.263a.37.37 0 0 1-.184.319l-4.559 2.632a.369.369 0 0 1-.368 0l-4.559-2.632a.369.369 0 0 1-.184-.32V9.452a.37.37 0 0 1 .184-.32M23.852 11.53l-5.446-9.475c-.198-.343-.564-.596-.96-.596H6.555c-.396 0-.762.253-.96.596L.149 11.509a1.127 1.127 0 0 0 0 1.117l5.447 9.398c.197.342.563.517.959.517h10.893c.395 0 .76-.17.959-.512l5.446-9.413a1.069 1.069 0 0 0 0-1.086m-4.51 4.556a.4.4 0 0 1-.204.338L12.2 20.426a.395.395 0 0 1-.392 0l-6.943-4.002a.4.4 0 0 1-.205-.338V8.08c0-.14.083-.269.204-.338L11.8 3.74c.12-.07.272-.07.392 0l6.943 4.003a.4.4 0 0 1 .206.338z"/></svg>
|
||||
|
Before Width: | Height: | Size: 743 B |
@@ -1,9 +0,0 @@
|
||||
<svg
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
>
|
||||
<title>Java</title>
|
||||
<path d="m16.5093 4.9869-.0607-.0347c-1.1014.369-4.4915 1.707-4.4915 4.202 0 1.411 1.378 2.1925 1.378 3.5158 0 .472-.2666.9146-.4836 1.1791l.1091.063c.5735-.3728 1.589-1.18 1.589-2.2222 0-.8825-1.2216-1.943-1.2216-3.0774 0-1.7875 2.357-3.1899 3.1813-3.6256zm-1.6642-3.27c0 3.6925-5.0604 5.1055-5.0604 7.7309 0 1.843 1.2222 2.9987 1.8983 3.7293l-.055.0317c-.8536-.534-3.0995-1.876-3.0995-4.0927 0-3.112 5.8123-4.599 5.8123-8.134 0-.435-.0644-.7683-.1095-.9482L14.2901 0c.1842.2315.555.8102.555 1.7168m.514 14.9392c-.5962.1688-1.9389.4441-3.859.4441-1.8844 0-3.424-.3226-3.4289-.7024-.0032-.2527.3024-.3628.3024-.3628l-.0544-.0316c-.9023.1595-1.7406.406-1.7357.7752.0084.6698 2.5697 1.1728 4.9129 1.1728 1.992 0 3.9053-.3343 4.7684-.7722zm-6.368 2.0708c-.4185.0832-1.3305.2926-1.3305.7361 0 .6144 1.9513 1.085 3.835 1.085 2.5922 0 3.6539-.667 3.702-.7016l-1.078-.6235c-.4583.1092-1.2306.2808-2.6214.2808-1.5521 0-2.5634-.2658-2.5634-.5569 0-.0617.0386-.135.1106-.1886zm10.5923-4.1337c-.0725 1.3911-1.3577 2.2573-2.6423 2.9893l.1164.067c1.3708-.3855 3.8166-1.5085 3.6144-3.2346-.1007-.8608-.8875-1.4758-1.9133-1.4758-.3194 0-.6036.0563-.834.1265l-.0007.0022-.0486.1224c.9175-.1796 1.7558.4904 1.7082 1.403zm-8.1232 8.1638c3.6058-.0313 7.6402-.737 7.6298-1.9232-.0019-.215-.1418-.3622-.2635-.4513l-.0592.034c-.3333.9188-3.1508 1.5977-7.3132 1.634-2.6859.0234-6.4063-.62-6.4128-1.3636-.0065-.7455 1.7625-1.1552 1.7625-1.1552l-.125-.0714c-1.1854.1632-3.3697.731-3.3625 1.5506.0104 1.185 5.0304 1.7734 8.1439 1.7461zm-.375.847c-1.4333.0126-3.1833-.1061-4.6555-.3535l-.1363.0784c1.4664.43 3.508.6896 5.7514.6702 4.4059-.0386 7.9779-1.1311 8.0485-2.446l-.051-.0297c-.2953.3604-2.2009 2.0216-8.9572 2.0806zm-5.5195-9.328c0-.6646 2.521-1.0374 3.6947-1.1277l.112.0647c-.451.082-2.26.401-2.26.8172 0 .4532 2.7747.7501 4.3853.7501 2.7355 0 4.595-.414 5.095-.5505l.6997.4072c-.4792.2346-2.5362.8495-5.7945.8495-3.6214 0-5.9322-.7086-5.9322-1.2105" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.0 KiB |
@@ -1,18 +0,0 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_1244_718)">
|
||||
<path d="M9.35205 3.72154V7.35041L12.0002 8.93803M9.35205 3.72154L12.0002 2.13391L14.6483 3.72154M9.35205 3.72154L12.0002 5.08236M12.0002 8.93803L14.6483 7.35041V3.72154M12.0002 8.93803V5.08236M14.6483 3.72154L12.0002 5.08236" stroke="black" stroke-width="0.5" stroke-linejoin="round"/>
|
||||
<path d="M8.3335 3.26804L12.0002 1L15.6668 3.26804V7.80412L12.0002 10.0722L8.3335 7.80412V3.26804Z" stroke="black" stroke-width="0.5" stroke-linejoin="round"/>
|
||||
<path d="M2.01855 15.2888V18.9177L4.6667 20.5053M2.01855 15.2888L4.6667 13.7012L7.31485 15.2888M2.01855 15.2888L4.6667 16.8764M4.6667 20.5053L7.31485 18.9177V15.2888M4.6667 20.5053V16.8764M7.31485 15.2888L4.6667 16.8764" stroke="black" stroke-width="0.5" stroke-linejoin="round"/>
|
||||
<path d="M1 14.8349L4.66667 12.5669L8.33333 14.8349V19.371L4.66667 21.6391L1 19.371V14.8349Z" stroke="black" stroke-width="0.5" stroke-linejoin="round"/>
|
||||
<path d="M16.6855 15.2888V18.9177L19.3337 20.5053M16.6855 15.2888L19.3337 13.7012L21.9818 15.2888M16.6855 15.2888L19.3337 16.6496M19.3337 20.5053L21.9818 18.9177V15.2888M19.3337 20.5053V16.6496M21.9818 15.2888L19.3337 16.6496" stroke="black" stroke-width="0.5" stroke-linejoin="round"/>
|
||||
<path d="M15.6665 14.8349L19.3332 12.5669L22.9998 14.8349V19.371L19.3332 21.6391L15.6665 19.371V14.8349Z" stroke="black" stroke-width="0.5" stroke-linejoin="round"/>
|
||||
<path d="M8.33317 6.89685L4.6665 9.16489V12.567" stroke="black" stroke-width="0.5" stroke-linejoin="round"/>
|
||||
<path d="M15.6668 6.89685L19.3335 9.16489V12.567" stroke="black" stroke-width="0.5" stroke-linejoin="round"/>
|
||||
<path d="M7.51855 19.8248L12 23.0001L16.4815 19.8248" stroke="black" stroke-width="0.5" stroke-linejoin="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1244_718">
|
||||
<rect width="24" height="24" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.9 KiB |
@@ -1 +0,0 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Node.js</title><path d="M11.998,24c-0.321,0-0.641-0.084-0.922-0.247l-2.936-1.737c-0.438-0.245-0.224-0.332-0.08-0.383 c0.585-0.203,0.703-0.25,1.328-0.604c0.065-0.037,0.151-0.023,0.218,0.017l2.256,1.339c0.082,0.045,0.197,0.045,0.272,0l8.795-5.076 c0.082-0.047,0.134-0.141,0.134-0.238V6.921c0-0.099-0.053-0.192-0.137-0.242l-8.791-5.072c-0.081-0.047-0.189-0.047-0.271,0 L3.075,6.68C2.99,6.729,2.936,6.825,2.936,6.921v10.15c0,0.097,0.054,0.189,0.139,0.235l2.409,1.392 c1.307,0.654,2.108-0.116,2.108-0.89V7.787c0-0.142,0.114-0.253,0.256-0.253h1.115c0.139,0,0.255,0.112,0.255,0.253v10.021 c0,1.745-0.95,2.745-2.604,2.745c-0.508,0-0.909,0-2.026-0.551L2.28,18.675c-0.57-0.329-0.922-0.945-0.922-1.604V6.921 c0-0.659,0.353-1.275,0.922-1.603l8.795-5.082c0.557-0.315,1.296-0.315,1.848,0l8.794,5.082c0.57,0.329,0.924,0.944,0.924,1.603 v10.15c0,0.659-0.354,1.273-0.924,1.604l-8.794,5.078C12.643,23.916,12.324,24,11.998,24z M19.099,13.993 c0-1.9-1.284-2.406-3.987-2.763c-2.731-0.361-3.009-0.548-3.009-1.187c0-0.528,0.235-1.233,2.258-1.233 c1.807,0,2.473,0.389,2.747,1.607c0.024,0.115,0.129,0.199,0.247,0.199h1.141c0.071,0,0.138-0.031,0.186-0.081 c0.048-0.054,0.074-0.123,0.067-0.196c-0.177-2.098-1.571-3.076-4.388-3.076c-2.508,0-4.004,1.058-4.004,2.833 c0,1.925,1.488,2.457,3.895,2.695c2.88,0.282,3.103,0.703,3.103,1.269c0,0.983-0.789,1.402-2.642,1.402 c-2.327,0-2.839-0.584-3.011-1.742c-0.02-0.124-0.126-0.215-0.253-0.215h-1.137c-0.141,0-0.254,0.112-0.254,0.253 c0,1.482,0.806,3.248,4.655,3.248C17.501,17.007,19.099,15.91,19.099,13.993z"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
@@ -1 +0,0 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>React</title><path d="M14.23 12.004a2.236 2.236 0 0 1-2.235 2.236 2.236 2.236 0 0 1-2.236-2.236 2.236 2.236 0 0 1 2.235-2.236 2.236 2.236 0 0 1 2.236 2.236zm2.648-10.69c-1.346 0-3.107.96-4.888 2.622-1.78-1.653-3.542-2.602-4.887-2.602-.41 0-.783.093-1.106.278-1.375.793-1.683 3.264-.973 6.365C1.98 8.917 0 10.42 0 12.004c0 1.59 1.99 3.097 5.043 4.03-.704 3.113-.39 5.588.988 6.38.32.187.69.275 1.102.275 1.345 0 3.107-.96 4.888-2.624 1.78 1.654 3.542 2.603 4.887 2.603.41 0 .783-.09 1.106-.275 1.374-.792 1.683-3.263.973-6.365C22.02 15.096 24 13.59 24 12.004c0-1.59-1.99-3.097-5.043-4.032.704-3.11.39-5.587-.988-6.38-.318-.184-.688-.277-1.092-.278zm-.005 1.09v.006c.225 0 .406.044.558.127.666.382.955 1.835.73 3.704-.054.46-.142.945-.25 1.44-.96-.236-2.006-.417-3.107-.534-.66-.905-1.345-1.727-2.035-2.447 1.592-1.48 3.087-2.292 4.105-2.295zm-9.77.02c1.012 0 2.514.808 4.11 2.28-.686.72-1.37 1.537-2.02 2.442-1.107.117-2.154.298-3.113.538-.112-.49-.195-.964-.254-1.42-.23-1.868.054-3.32.714-3.707.19-.09.4-.127.563-.132zm4.882 3.05c.455.468.91.992 1.36 1.564-.44-.02-.89-.034-1.345-.034-.46 0-.915.01-1.36.034.44-.572.895-1.096 1.345-1.565zM12 8.1c.74 0 1.477.034 2.202.093.406.582.802 1.203 1.183 1.86.372.64.71 1.29 1.018 1.946-.308.655-.646 1.31-1.013 1.95-.38.66-.773 1.288-1.18 1.87-.728.063-1.466.098-2.21.098-.74 0-1.477-.035-2.202-.093-.406-.582-.802-1.204-1.183-1.86-.372-.64-.71-1.29-1.018-1.946.303-.657.646-1.313 1.013-1.954.38-.66.773-1.286 1.18-1.868.728-.064 1.466-.098 2.21-.098zm-3.635.254c-.24.377-.48.763-.704 1.16-.225.39-.435.782-.635 1.174-.265-.656-.49-1.31-.676-1.947.64-.15 1.315-.283 2.015-.386zm7.26 0c.695.103 1.365.23 2.006.387-.18.632-.405 1.282-.66 1.933-.2-.39-.41-.783-.64-1.174-.225-.392-.465-.774-.705-1.146zm3.063.675c.484.15.944.317 1.375.498 1.732.74 2.852 1.708 2.852 2.476-.005.768-1.125 1.74-2.857 2.475-.42.18-.88.342-1.355.493-.28-.958-.646-1.956-1.1-2.98.45-1.017.81-2.01 1.085-2.964zm-13.395.004c.278.96.645 1.957 1.1 2.98-.45 1.017-.812 2.01-1.086 2.964-.484-.15-.944-.318-1.37-.5-1.732-.737-2.852-1.706-2.852-2.474 0-.768 1.12-1.742 2.852-2.476.42-.18.88-.342 1.356-.494zm11.678 4.28c.265.657.49 1.312.676 1.948-.64.157-1.316.29-2.016.39.24-.375.48-.762.705-1.158.225-.39.435-.788.636-1.18zm-9.945.02c.2.392.41.783.64 1.175.23.39.465.772.705 1.143-.695-.102-1.365-.23-2.006-.386.18-.63.406-1.282.66-1.933zM17.92 16.32c.112.493.2.968.254 1.423.23 1.868-.054 3.32-.714 3.708-.147.09-.338.128-.563.128-1.012 0-2.514-.807-4.11-2.28.686-.72 1.37-1.536 2.02-2.44 1.107-.118 2.154-.3 3.113-.54zm-11.83.01c.96.234 2.006.415 3.107.532.66.905 1.345 1.727 2.035 2.446-1.595 1.483-3.092 2.295-4.11 2.295-.22-.005-.406-.05-.553-.132-.666-.38-.955-1.834-.73-3.703.054-.46.142-.944.25-1.438zm4.56.64c.44.02.89.034 1.345.034.46 0 .915-.01 1.36-.034-.44.572-.895 1.095-1.345 1.565-.455-.47-.91-.993-1.36-1.565z"/></svg>
|
||||
|
Before Width: | Height: | Size: 2.9 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9.75 3.104v5.714a2.25 2.25 0 0 1-.659 1.591L5 14.5M9.75 3.104c-.251.023-.501.05-.75.082m.75-.082a24.301 24.301 0 0 1 4.5 0m0 0v5.714c0 .597.237 1.17.659 1.591L19.8 15.3M14.25 3.104c.251.023.501.05.75.082M19.8 15.3l-1.57.393A9.065 9.065 0 0 1 12 15a9.065 9.065 0 0 0-6.23-.693L5 14.5m14.8.8 1.402 1.402c1.232 1.232.65 3.318-1.067 3.611A48.309 48.309 0 0 1 12 21c-2.773 0-5.491-.235-8.135-.687-1.718-.293-2.3-2.379-1.067-3.61L5 14.5" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 632 B |
@@ -1,4 +0,0 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<title>TypeScript</title>
|
||||
<path d="M0 12v12h24V0H0zm19.341-.956c.61.152 1.074.423 1.501.865.221.236.549.666.575.77.008.03-1.036.73-1.668 1.123-.023.015-.115-.084-.217-.236-.31-.45-.633-.644-1.128-.678-.728-.05-1.196.331-1.192.967a.88.88 0 0 0 .102.45c.16.331.458.53 1.39.933 1.719.74 2.454 1.227 2.911 1.92.51.773.625 2.008.278 2.926-.38.998-1.325 1.676-2.655 1.9-.411.073-1.386.062-1.828-.018-.964-.172-1.878-.648-2.442-1.273-.221-.243-.652-.88-.625-.925.011-.016.11-.077.22-.141.108-.061.511-.294.892-.515l.69-.4.145.214c.202.308.643.731.91.872.766.404 1.817.347 2.335-.118a.883.883 0 0 0 .313-.72c0-.278-.035-.4-.18-.61-.186-.266-.567-.49-1.649-.96-1.238-.533-1.771-.864-2.259-1.39a3.165 3.165 0 0 1-.659-1.2c-.091-.339-.114-1.189-.042-1.531.255-1.197 1.158-2.03 2.461-2.278.423-.08 1.406-.05 1.821.053zm-5.634 1.002l.008.983H10.59v8.876H8.38v-8.876H5.258v-.964c0-.534.011-.98.026-.99.012-.016 1.913-.024 4.217-.02l4.195.012z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1019 B |
@@ -1 +0,0 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Vue.js</title><path d="M24,1.61H14.06L12,5.16,9.94,1.61H0L12,22.39ZM12,14.08,5.16,2.23H9.59L12,6.41l2.41-4.18h4.43Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 202 B |
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 334 KiB |
|
Before Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 196 KiB |
|
Before Width: | Height: | Size: 408 KiB |
|
Before Width: | Height: | Size: 149 KiB |
@@ -1 +0,0 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Nx</title><path d="M11.987 14.138l-3.132 4.923-5.193-8.427-.012 8.822H0V4.544h3.691l5.247 8.833.005-3.998 3.044 4.759zm.601-5.761c.024-.048 0-3.784.008-3.833h-3.65c.002.059-.005 3.776-.003 3.833h3.645zm5.634 4.134a2.061 2.061 0 0 0-1.969 1.336 1.963 1.963 0 0 1 2.343-.739c.396.161.917.422 1.33.283a2.1 2.1 0 0 0-1.704-.88zm3.39 1.061c-.375-.13-.8-.277-1.109-.681-.06-.08-.116-.17-.176-.265a2.143 2.143 0 0 0-.533-.642c-.294-.216-.68-.322-1.18-.322a2.482 2.482 0 0 0-2.294 1.536 2.325 2.325 0 0 1 4.002.388.75.75 0 0 0 .836.334c.493-.105.46.36 1.203.518v-.133c-.003-.446-.246-.55-.75-.733zm2.024 1.266a.723.723 0 0 0 .347-.638c-.01-2.957-2.41-5.487-5.37-5.487a5.364 5.364 0 0 0-4.487 2.418c-.01-.026-1.522-2.39-1.538-2.418H8.943l3.463 5.423-3.379 5.32h3.54l1.54-2.366 1.568 2.366h3.541l-3.21-5.052a.7.7 0 0 1-.084-.32 2.69 2.69 0 0 1 2.69-2.691h.001c1.488 0 1.736.89 2.057 1.308.634.826 1.9.464 1.9 1.541a.707.707 0 0 0 1.066.596zm.35.133c-.173.372-.56.338-.755.639-.176.271.114.412.114.412s.337.156.538-.311c.104-.231.14-.488.103-.74z"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 7.7 MiB |
|
Before Width: | Height: | Size: 231 KiB |
@@ -1,9 +0,0 @@
|
||||
# *
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
# Host
|
||||
Host: https://nx.dev
|
||||
|
||||
# Sitemaps
|
||||
Sitemap: https://nx.dev/sitemap-index.xml
|
||||