Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 53851d85e0 |
@@ -1,5 +1,5 @@
|
||||
[build]
|
||||
target-dir = 'dist/target'
|
||||
target-dir = 'build/target'
|
||||
|
||||
[target.x86_64-unknown-linux-musl]
|
||||
rustflags = [
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"nx-mcp": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "nx-mcp@latest"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,7 @@
|
||||
#
|
||||
# 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
|
||||
*.gif,*.mp4,*.webp,*.avif,*.png,*.jpeg,*.jpg,*.tiff filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
|
||||
@@ -4,14 +4,12 @@ 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:
|
||||
@@ -59,26 +57,13 @@ jobs:
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
with:
|
||||
version: 10.11.1
|
||||
version: 9.8.0
|
||||
run_install: false
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Cache Rust toolchain and cargo registry
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/bin/
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cargo-
|
||||
- name: Install project dependencies
|
||||
run: |
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm playwright install --with-deps
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
@@ -89,14 +74,6 @@ jobs:
|
||||
distribution: temurin
|
||||
java-version: 17
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
|
||||
- name: Install project dependencies
|
||||
run: |
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm playwright install --with-deps
|
||||
|
||||
- name: Check Documentation
|
||||
run: pnpm nx documentation
|
||||
timeout-minutes: 20
|
||||
@@ -117,7 +94,7 @@ jobs:
|
||||
pnpm nx run-many -t check-imports check-commit check-lock-files check-codeowners --parallel=1 --no-dte &
|
||||
pids+=($!)
|
||||
|
||||
pnpm nx affected --targets=lint,test,build,e2e,e2e-ci,format-native,lint-native &
|
||||
pnpm nx affected --targets=lint,test,build,e2e,e2e-ci,format-native &
|
||||
pids+=($!)
|
||||
|
||||
for pid in "${pids[@]}"; do
|
||||
@@ -166,100 +143,10 @@ jobs:
|
||||
|
||||
- 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"
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew >/dev/null
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install applesimutils >/dev/null
|
||||
xcrun simctl shutdown all && xcrun simctl erase all
|
||||
timeout-minutes: 20
|
||||
|
||||
- name: Save Homebrew Cache
|
||||
uses: actions/cache@v4
|
||||
@@ -272,35 +159,17 @@ jobs:
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
with:
|
||||
version: 10.11.1
|
||||
version: 9.8.0
|
||||
run_install: false
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Cache Rust toolchain and cargo registry
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/bin/
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cargo-
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Install project dependencies
|
||||
run: |
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm playwright install --with-deps
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Set SHAs
|
||||
uses: nrwl/nx-set-shas@v4
|
||||
with:
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
name: Claude Code
|
||||
|
||||
env:
|
||||
PNPM_HOME: ~/.pnpm
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
pull_request_review_comment:
|
||||
types: [created]
|
||||
issues:
|
||||
types: [opened, assigned]
|
||||
pull_request_review:
|
||||
types: [submitted]
|
||||
|
||||
jobs:
|
||||
claude:
|
||||
if: |
|
||||
contains(fromJson('["AgentEnder", "barbados-clemens", "Cammisuli", "Coly010", "FrozenPandaz", "isaacplmann", "JamesHenry", "jaysoo", "leosvelperez", "mandarini", "MaxKless", "meeroslav", "nartc", "ndcunningham", "philipjfulcher", "vsavkin", "xiongemi"]'), github.actor) &&
|
||||
((github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
||||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
|
||||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
||||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))))
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
issues: write
|
||||
actions: read
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 250
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ca-certificates lsof libvips-dev libglib2.0-dev libgirepository1.0-dev
|
||||
|
||||
- name: Install Chrome
|
||||
uses: browser-actions/setup-chrome@v1
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
with:
|
||||
version: 10.11.1
|
||||
run_install: false
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
.cargo-cache
|
||||
target/
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cargo-
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 17
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
|
||||
- name: Install project dependencies
|
||||
run: |
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm playwright install --with-deps
|
||||
|
||||
- name: Run Claude Code
|
||||
id: claude
|
||||
uses: anthropics/claude-code-action@beta
|
||||
timeout-minutes: 90
|
||||
with:
|
||||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
allowed_tools: "Bash,Edit,Read,Write,Glob,Grep,LS,MultiEdit,NotebookRead,NotebookEdit"
|
||||
|
||||
@@ -19,14 +19,12 @@ 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
|
||||
- windows-latest
|
||||
node_version:
|
||||
- 20
|
||||
- 22
|
||||
@@ -37,9 +35,9 @@ jobs:
|
||||
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.
|
||||
- os: windows-latest
|
||||
node_version: 22
|
||||
# - os: windows-latest
|
||||
# node_version: 23
|
||||
|
||||
name: Cache install (${{ matrix.os }}, node v${{ matrix.node_version }})
|
||||
@@ -47,13 +45,12 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
filter: tree:0
|
||||
fetch-depth: 1
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
with:
|
||||
version: 10.11.1
|
||||
version: 9.8.0
|
||||
run_install: false
|
||||
|
||||
- name: Set node
|
||||
@@ -62,17 +59,13 @@ jobs:
|
||||
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
|
||||
- name: Cache node_modules
|
||||
id: cache-modules
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.path }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
lookup-only: true
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-modules-${{ matrix.node_version }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
|
||||
- name: Ensure Python setuptools Installed on Macos
|
||||
if: ${{ matrix.os == 'macos-latest' }}
|
||||
@@ -80,9 +73,8 @@ jobs:
|
||||
run: brew install python-setuptools
|
||||
|
||||
- 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' }}
|
||||
@@ -114,7 +106,6 @@ jobs:
|
||||
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 }}
|
||||
@@ -122,8 +113,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
filter: tree:0
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Process matrix data
|
||||
id: process-json
|
||||
@@ -138,7 +128,6 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 200 # <- cap each job to 200 minutes
|
||||
strategy:
|
||||
matrix: ${{fromJson(needs.prepare-matrix.outputs.matrix)}} # Load matrix from previous job
|
||||
fail-fast: false
|
||||
@@ -148,8 +137,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
filter: tree:0
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Prepare dir for output
|
||||
run: mkdir -p outputs
|
||||
@@ -157,7 +145,7 @@ jobs:
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
with:
|
||||
version: 10.11.1
|
||||
version: 9.8.0
|
||||
run_install: false
|
||||
|
||||
- name: Use Node.js ${{ matrix.node_version }}
|
||||
@@ -166,27 +154,15 @@ jobs:
|
||||
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@v1
|
||||
- name: Cache node_modules
|
||||
id: cache-modules
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
bun-version: latest
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-modules-${{ matrix.node_version }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
|
||||
- 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' }}
|
||||
@@ -225,116 +201,26 @@ 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' }}
|
||||
- name: Run e2e tests
|
||||
id: e2e-run
|
||||
run: pnpm nx run ${{ matrix.project }}:e2e-local
|
||||
shell: bash
|
||||
timeout-minutes: ${{ matrix.os_timeout }}
|
||||
@@ -351,33 +237,6 @@ jobs:
|
||||
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_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
|
||||
|
||||
- name: Save matrix config in file
|
||||
if: ${{ always() }}
|
||||
@@ -387,13 +246,9 @@ 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 }')
|
||||
) | jq --argjson delta $delta -c '. + { "status": "${{ steps.e2e-run.outcome}}", "duration": $delta }')
|
||||
echo "$matrix" > 'outputs/matrix.json'
|
||||
|
||||
- name: Upload matrix config
|
||||
@@ -413,23 +268,15 @@ jobs:
|
||||
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() && github.repository_owner == 'nrwl' }}
|
||||
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@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
filter: tree:0
|
||||
|
||||
- name: Prepare dir for output
|
||||
run: mkdir -p outputs
|
||||
|
||||
@@ -441,45 +288,172 @@ jobs:
|
||||
- name: Join and stringify matrix configs
|
||||
id: combine-json
|
||||
run: |
|
||||
combined=$(jq -sc . outputs/*/matrix.json)
|
||||
combined=$((jq -s . outputs/*/matrix.json) | 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@v7
|
||||
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} |`
|
||||
lastProject = matrix.project;
|
||||
});
|
||||
result += `\`\`\``;
|
||||
core.setOutput('SLACK_MESSAGE', trimSpace(result));
|
||||
console.log(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 === 20) {
|
||||
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@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@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 +462,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@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 +477,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@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 }}
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
uses: pnpm/action-setup@v4
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 10.11.1
|
||||
version: 9.8.0
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10.11.1
|
||||
version: 9.8.0
|
||||
|
||||
- name: Use Node.js ${{ matrix.node_version }}
|
||||
uses: actions/setup-node@v3
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
type MatrixDataProject = {
|
||||
name: string,
|
||||
codeowners: string,
|
||||
is_golden?: boolean, // true if this is a golden project, false otherwise
|
||||
};
|
||||
|
||||
type MatrixDataOS = {
|
||||
@@ -20,63 +19,58 @@ type MatrixData = {
|
||||
setup: MatrixDataOS[],
|
||||
}
|
||||
|
||||
export type MatrixItem = {
|
||||
// TODO: Extract Slack groups into named groups for easier maintenance
|
||||
const matrixData: MatrixData = {
|
||||
coreProjects: [
|
||||
{ name: 'e2e-lerna-smoke-tests', codeowners: 'S04TNCVEETS' },
|
||||
{ name: 'e2e-js', codeowners: 'S04SJ6HHP0X' },
|
||||
{ name: 'e2e-nx-init', codeowners: 'S04SYHYKGNP' },
|
||||
{ name: 'e2e-nx', codeowners: 'S04SYHYKGNP' },
|
||||
{ name: 'e2e-release', codeowners: 'S04SYHYKGNP' },
|
||||
{ name: 'e2e-workspace-create', codeowners: 'S04SYHYKGNP' }
|
||||
],
|
||||
projects: [
|
||||
{ name: 'e2e-angular', codeowners: 'S04SS457V38' },
|
||||
{ name: 'e2e-cypress', codeowners: 'S04T16BTJJY' },
|
||||
{ name: 'e2e-detox', codeowners: 'S04TNCNJG5N' },
|
||||
{ name: 'e2e-esbuild', codeowners: 'S04SJ6HHP0X' },
|
||||
{ name: 'e2e-expo', codeowners: 'S04TNCNJG5N' },
|
||||
{ name: 'e2e-gradle', codeowners: 'S04TNCNJG5N' },
|
||||
{ name: 'e2e-jest', codeowners: 'S04T16BTJJY' },
|
||||
{ name: 'e2e-eslint', codeowners: 'S04SYJGKSCT' },
|
||||
{ name: 'e2e-next', codeowners: 'S04TNCNJG5N' },
|
||||
{ name: 'e2e-node', codeowners: 'S04SJ6HHP0X' },
|
||||
{ name: 'e2e-plugin', codeowners: 'S04SYHYKGNP' },
|
||||
{ name: 'e2e-react', codeowners: 'S04TNCNJG5N' },
|
||||
{ name: 'e2e-react-native', codeowners: 'S04TNCNJG5N' },
|
||||
{ name: 'e2e-web', codeowners: 'S04SJ6PL98X' },
|
||||
{ name: 'e2e-rollup', codeowners: 'S04SJ6PL98X' },
|
||||
{ name: 'e2e-storybook', codeowners: 'S04SVQ8H0G5' },
|
||||
{ name: 'e2e-playwright', codeowners: 'S04SVQ8H0G5' },
|
||||
{ name: 'e2e-remix', codeowners: 'S04SVQ8H0G5' },
|
||||
{ name: 'e2e-rspack', codeowners: 'S04SJ6HHP0X' },
|
||||
{ name: 'e2e-vite', codeowners: 'S04SJ6PL98X' },
|
||||
{ name: 'e2e-vue', codeowners: 'S04SJ6PL98X' },
|
||||
{ name: 'e2e-nuxt', codeowners: 'S04SJ6PL98X' },
|
||||
{ name: 'e2e-webpack', 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'] },
|
||||
{ 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<{
|
||||
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-angular', codeowners: 'S04SS457V38' },
|
||||
{ name: 'e2e-expo', codeowners: 'S04TNCNJG5N' },
|
||||
{ name: 'e2e-next', codeowners: 'S04TNCNJG5N' },
|
||||
{ name: 'e2e-plugin', codeowners: 'S04SYHYKGNP' },
|
||||
{ name: 'e2e-react', codeowners: 'S04TNCNJG5N' },
|
||||
{ name: 'e2e-react-native', 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> = [];
|
||||
os_timeout: number
|
||||
}> = [];
|
||||
|
||||
function addMatrixCombo(project: MatrixDataProject, nodeVersion: number | string, pm: number, os: number) {
|
||||
matrix.push({
|
||||
@@ -87,7 +81,6 @@ function addMatrixCombo(project: MatrixDataProject, nodeVersion: number | string
|
||||
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
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10.11.1 # Aligned with root package.json (pnpm/action-setup will helpfully error if out of sync)
|
||||
version: 9.8.0 # Aligned with root package.json (pnpm/action-setup will helpfully error if out of sync)
|
||||
|
||||
- name: Run a security audit
|
||||
run: pnpm dlx audit-ci --critical --report-type summary
|
||||
|
||||
@@ -21,8 +21,8 @@ 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)
|
||||
NODE_VERSION: 20.19.0
|
||||
PNPM_VERSION: 9.8.0 # Aligned with root package.json (pnpm/action-setup will helpfully error if out of sync)
|
||||
|
||||
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.
|
||||
@@ -123,13 +123,9 @@ jobs:
|
||||
settings:
|
||||
- host: macos-13
|
||||
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: |-
|
||||
rustup target add aarch64-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)
|
||||
@@ -140,54 +136,23 @@ 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
|
||||
|
||||
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
|
||||
build: |-
|
||||
set -e &&
|
||||
npm i -g pnpm@9.8.0 --force &&
|
||||
pnpm --version &&
|
||||
pnpm install --frozen-lockfile &&
|
||||
pnpm nx run-many --verbose --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
|
||||
|
||||
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
|
||||
"
|
||||
build: |-
|
||||
set -e &&
|
||||
npm i -g pnpm@9.8.0 --force &&
|
||||
pnpm --version &&
|
||||
pnpm install --frozen-lockfile &&
|
||||
pnpm nx run-many --verbose --target=build-native -- --target=x86_64-unknown-linux-musl
|
||||
- host: macos-13
|
||||
target: aarch64-apple-darwin
|
||||
setup: |-
|
||||
rustup target add aarch64-apple-darwin
|
||||
build: |
|
||||
sudo rm -Rf /Library/Developer/CommandLineTools/SDKs/*;
|
||||
export CC=$(xcrun -f clang);
|
||||
@@ -198,29 +163,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
|
||||
|
||||
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
|
||||
build: |-
|
||||
set -e &&
|
||||
npm i -g pnpm@9.8.0 --force &&
|
||||
pnpm --version &&
|
||||
pnpm install --frozen-lockfile &&
|
||||
pnpm nx run-many --verbose --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
|
||||
# Android (not needed)
|
||||
@@ -235,36 +188,17 @@ 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
|
||||
|
||||
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 &&
|
||||
npm i -g pnpm@9.8.0 --force &&
|
||||
pnpm --version &&
|
||||
pnpm install --frozen-lockfile &&
|
||||
pnpm nx run-many --verbose --target=build-native -- --target=aarch64-unknown-linux-musl
|
||||
- host: windows-latest
|
||||
target: aarch64-pc-windows-msvc
|
||||
setup: |-
|
||||
rustup target add aarch64-pc-windows-msvc
|
||||
build: pnpm nx run-many --target=build-native -- --target=aarch64-pc-windows-msvc
|
||||
name: stable - ${{ matrix.settings.target }} - node@22.16.0
|
||||
name: stable - ${{ matrix.settings.target }} - node@18
|
||||
runs-on: ${{ matrix.settings.host }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -348,8 +282,8 @@ jobs:
|
||||
with:
|
||||
name: bindings-${{ matrix.settings.target }}
|
||||
path: |
|
||||
packages/nx/src/native/*.node
|
||||
packages/nx/src/native/*.wasm
|
||||
packages/**/*.node
|
||||
packages/**/*.wasm
|
||||
if-no-files-found: error
|
||||
|
||||
build-freebsd:
|
||||
@@ -372,18 +306,17 @@ jobs:
|
||||
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
|
||||
environment_variables: DEBUG RUSTUP_IO_THREADS CI NX_PREFER_TS_NODE PLAYWRIGHT_BROWSERS_PATH
|
||||
shell: bash
|
||||
run: |
|
||||
env
|
||||
whoami
|
||||
sudo pkg install -y -f node libnghttp2 www/npm git
|
||||
sudo npm install --location=global --ignore-scripts pnpm@10.11.1
|
||||
sudo npm install --location=global --ignore-scripts pnpm@9.8.0
|
||||
curl https://sh.rustup.rs -sSf --output rustup.sh
|
||||
sh rustup.sh -y --profile minimal --default-toolchain stable
|
||||
source "$HOME/.cargo/env"
|
||||
@@ -398,11 +331,8 @@ jobs:
|
||||
whoami
|
||||
env
|
||||
freebsd-version
|
||||
echo "Installing dependencies"
|
||||
pnpm install --frozen-lockfile --ignore-scripts
|
||||
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
|
||||
@@ -414,8 +344,7 @@ jobs:
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: bindings-freebsd
|
||||
path: |
|
||||
packages/nx/src/native/*.node
|
||||
path: packages/**/*.node
|
||||
if-no-files-found: error
|
||||
|
||||
publish:
|
||||
@@ -474,7 +403,6 @@ jobs:
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@ node_modules
|
||||
/.idea
|
||||
/.fleet
|
||||
/.vscode
|
||||
/.cursor
|
||||
dist
|
||||
/build
|
||||
/coverage
|
||||
@@ -35,7 +36,6 @@ CHANGELOG.md
|
||||
.next
|
||||
out
|
||||
|
||||
|
||||
# Angular Cache
|
||||
.angular
|
||||
|
||||
@@ -72,40 +72,3 @@ 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
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
node ./scripts/commit-lint.js "$1"
|
||||
@@ -1,12 +1,2 @@
|
||||
# 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
|
||||
|
||||
changedFiles="$(git diff-tree -r --name-only --no-commit-id $1 $2)"
|
||||
node ./scripts/notify-lockfile-changes.js $changedFiles
|
||||
node ./scripts/notify-lockfile-changes.js $changedFiles
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
pnpm nx prepush --parallel 8 --tuiAutoExit 0
|
||||
pnpm check-lock-files
|
||||
pnpm check-commit
|
||||
pnpm documentation
|
||||
pnpm pretty-quick --check
|
||||
pnpm nx format-native nx
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"nx": {
|
||||
"command": "pnpm",
|
||||
"args": ["nx-mcp"],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
launch-templates:
|
||||
linux-large:
|
||||
resource-class: 'docker_linux_amd64/large'
|
||||
linux-medium:
|
||||
resource-class: 'docker_linux_amd64/medium+'
|
||||
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
|
||||
|
||||
@@ -1,25 +1,14 @@
|
||||
distribute-on:
|
||||
default: auto linux-large, 1 linux-extra-large
|
||||
default: auto linux-medium, 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
|
||||
|
||||
# All other e2e tests can run in parallel
|
||||
- targets:
|
||||
- e2e-ci**
|
||||
run-on:
|
||||
- agent: linux-large
|
||||
parallelism: 2
|
||||
- agent: linux-medium
|
||||
parallelism: 1
|
||||
- agent: linux-extra-large
|
||||
parallelism: 3
|
||||
parallelism: 1
|
||||
|
||||
# These projects should not need to be isolated.
|
||||
- projects:
|
||||
- nx-dev
|
||||
targets:
|
||||
@@ -27,25 +16,17 @@ assignment-rules:
|
||||
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
|
||||
- agent: linux-medium
|
||||
parallelism: 6
|
||||
|
||||
- targets:
|
||||
- '*'
|
||||
run-on:
|
||||
- agent: linux-large
|
||||
- agent: linux-medium
|
||||
parallelism: 3
|
||||
- agent: linux-extra-large
|
||||
parallelism: 3
|
||||
|
||||
@@ -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
|
||||
@@ -51,6 +51,3 @@ CODEOWNERS
|
||||
/.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,10 +0,0 @@
|
||||
{
|
||||
"include": ["apps/**/*", "libs/**/*", "packages/**/*"],
|
||||
"exclude": [
|
||||
"**/*.spec.*",
|
||||
"**/test/**/*",
|
||||
"**/__tests__/**/*",
|
||||
"**/*.test.*",
|
||||
"node_modules/**/*"
|
||||
]
|
||||
}
|
||||
@@ -5,7 +5,7 @@ auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd
|
||||
|
||||
max_body_size: 20mb
|
||||
max_body_size: 15mb
|
||||
|
||||
# a list of other known repositories we can talk to
|
||||
uplinks:
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
When responding to queries about this repository:
|
||||
|
||||
1. Use the `nx_workspace` mcp tool for understanding the workspace architecture when appropriate
|
||||
2. When working in projects, use the `nx_project` mcp tool to analyze and understand the specific project structure and
|
||||
dependencies
|
||||
3. Suggest relevant commands from the "Essential Commands" section when applicable
|
||||
4. Highlight Nx's focus on monorepos and its key features like smart task execution, code generation, and project graph
|
||||
analysis
|
||||
5. Mention the plugin ecosystem and support for various frameworks when relevant
|
||||
6. 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
|
||||
@@ -6,13 +6,12 @@
|
||||
/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
|
||||
rust-toolchain @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
|
||||
/graph/** @philipjfulcher @FrozenPandaz @bcabanes @MaxKless @xiongemi
|
||||
/images @nrwl/nx-docs-reviewers
|
||||
/nx-dev/** @nrwl/nx-docs-reviewers
|
||||
/typedoc-theme @nrwl/nx-docs-reviewers
|
||||
@@ -138,9 +137,6 @@ rust-toolchain.toml @nrwl/nx-native-reviewers
|
||||
/packages/storybook/** @nrwl/nx-storybook-reviewers
|
||||
/e2e/storybook/** @nrwl/nx-storybook-reviewers
|
||||
|
||||
# Docker
|
||||
/packages/docker/** @nrwl/nx-core-reviewers @Coly010
|
||||
|
||||
## Devkit
|
||||
/docs/generated/devkit/** @nrwl/nx-devkit-reviewers @nrwl/nx-docs-reviewers
|
||||
/docs/generated/packages/devkit/** @nrwl/nx-devkit-reviewers @nrwl/nx-docs-reviewers
|
||||
@@ -149,8 +145,8 @@ rust-toolchain.toml @nrwl/nx-native-reviewers
|
||||
/packages/devkit/public-api.ts @FrozenPandaz @vsavkin
|
||||
|
||||
# Gradle
|
||||
/packages/gradle/** @FrozenPandaz @MaxKless
|
||||
/e2e/gradle/** @FrozenPandaz @MaxKless
|
||||
/packages/gradle/** @FrozenPandaz @MaxKless @xiongemi
|
||||
/e2e/gradle/** @FrozenPandaz @MaxKless @xiongemi
|
||||
|
||||
# Nx-Plugin
|
||||
/docs/generated/packages/plugin/** @nrwl/nx-devkit-reviewers @nrwl/nx-docs-reviewers
|
||||
@@ -178,10 +174,10 @@ rust-toolchain.toml @nrwl/nx-native-reviewers
|
||||
|
||||
# Misc
|
||||
/e2e/lerna-smoke-tests/** @vsavkin @JamesHenry
|
||||
/e2e/utils/** @meeroslav @nrwl/nx-testing-tools-reviewers @vsavkin
|
||||
/e2e/utils/** @meeroslav @nrwl/nx-testing-tools-reviewers @vsavkin @mandarini
|
||||
/community @nrwl/nx-docs-reviewers
|
||||
/CONTRIBUTING.md @FrozenPandaz
|
||||
/CODE_OF_CONDUCT.md @FrozenPandaz
|
||||
/CONTRIBUTING.md @FrozenPandaz @isaacplmann
|
||||
/CODE_OF_CONDUCT.md @FrozenPandaz @isaacplmann
|
||||
/CODEOWNERS @FrozenPandaz @AgentEnder
|
||||
/packages/nx/src/nx-cloud/utilities/url-shorten.ts @MaxKless
|
||||
|
||||
@@ -195,11 +191,6 @@ rust-toolchain.toml @nrwl/nx-native-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
|
||||
|
||||
@@ -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`).
|
||||
@@ -344,7 +333,6 @@ 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
|
||||
@@ -386,57 +374,6 @@ 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,7 +1,7 @@
|
||||
<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%">
|
||||
<img alt="Nx - Smart Monorepos · Fast CI" src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-light.svg" width="100%">
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
|
||||
<hr>
|
||||
|
||||
# Smart Repos · Fast Builds
|
||||
# Smart Monorepos · Fast CI
|
||||
|
||||
An AI-first build platform that connects everything from your editor to CI. Helping you deliver fast, without breaking things.
|
||||
Build system, optimized for monorepos, with AI-powered architectural awareness and advanced CI capabilities.
|
||||
|
||||
Create a new Nx workspace with
|
||||
|
||||
@@ -35,7 +35,7 @@ npx create-nx-workspace
|
||||
npx nx init
|
||||
```
|
||||
|
||||
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).
|
||||
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#try-nx-yourself).
|
||||
|
||||
## Learn about CI with Nx Cloud
|
||||
|
||||
@@ -58,7 +58,7 @@ Learn more in the [Nx CI docs »](https://nx.dev/ci/intro?utm_source=nxrepo
|
||||
- [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>
|
||||
width="100%" alt="Nx - Smart Monorepos · Fast CI"></a></p>
|
||||
|
||||
## Want to help?
|
||||
|
||||
@@ -82,17 +82,17 @@ help you get started.
|
||||
|  |  |  |  |
|
||||
| [JamesHenry](https://github.com/JamesHenry) | [cammisuli](https://github.com/cammisuli) | [isaacplmann](https://github.com/isaacplmann) | [juristr](https://github.com/juristr) |
|
||||
|
||||
| Philip Fulcher | Caleb Ukle | Colum Ferry | Emily Xiong |
|
||||
| ------------------------------------------------------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
||||
|  |  |  |  |
|
||||
| [philipjfulcher](https://github.com/philipjfulcher) | [barbados-clemens](https://github.com/barbados-clemens) | [Coly010](https://github.com/Coly010) | [xiongemi](https://github.com/xiongemi) |
|
||||
| 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 | Nicholas Cunningham | Max Kless |
|
||||
| -------------------------------------------------------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------- |
|
||||
|  |  |  |
|
||||
| [nartc](https://github.com/nartc) | [ndcunningham](https://github.com/ndcunningham) | [MaxKless](https://github.com/MaxKless) |
|
||||
| Craigory Coppola | Chau Tran | Nicholas Cunningham | Max Kless |
|
||||
| -------------------------------------------------------------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------- |
|
||||
|  |  |  |  |
|
||||
| [AgentEnder](https://github.com/AgentEnder) | [nartc](https://github.com/nartc) | [ndcunningham](https://github.com/ndcunningham) | [MaxKless](https://github.com/MaxKless) |
|
||||
|
||||
@@ -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,54 +0,0 @@
|
||||
# Starlight Starter Kit: Basics
|
||||
|
||||
[](https://starlight.astro.build)
|
||||
|
||||
```
|
||||
pnpm create astro@latest -- --template starlight
|
||||
```
|
||||
|
||||
[](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics)
|
||||
[](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics)
|
||||
[](https://app.netlify.com/start/deploy?repository=https://github.com/withastro/starlight&create_from_path=examples/basics)
|
||||
[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fwithastro%2Fstarlight%2Ftree%2Fmain%2Fexamples%2Fbasics&project-name=my-starlight-docs&repository-name=my-starlight-docs)
|
||||
|
||||
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
|
||||
|
||||
## 🚀 Project Structure
|
||||
|
||||
Inside of your Astro + Starlight project, you'll see the following folders and files:
|
||||
|
||||
```
|
||||
.
|
||||
├── public/
|
||||
├── src/
|
||||
│ ├── assets/
|
||||
│ ├── content/
|
||||
│ │ ├── docs/
|
||||
│ └── content.config.ts
|
||||
├── astro.config.mjs
|
||||
├── package.json
|
||||
└── tsconfig.json
|
||||
```
|
||||
|
||||
Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name.
|
||||
|
||||
Images can be added to `src/assets/` and embedded in Markdown with a relative link.
|
||||
|
||||
Static assets, like favicons, can be placed in the `public/` directory.
|
||||
|
||||
## 🧞 Commands
|
||||
|
||||
All commands are run from the root of the project, from a terminal:
|
||||
|
||||
| Command | Action |
|
||||
| :--------------------- | :----------------------------------------------- |
|
||||
| `pnpm install` | Installs dependencies |
|
||||
| `pnpm dev` | Starts local dev server at `localhost:4321` |
|
||||
| `pnpm build` | Build your production site to `./dist/` |
|
||||
| `pnpm preview` | Preview your build locally, before deploying |
|
||||
| `pnpm astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||
| `pnpm astro -- --help` | Get help using the Astro CLI |
|
||||
|
||||
## 👀 Want to learn more?
|
||||
|
||||
Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat).
|
||||
@@ -1,70 +0,0 @@
|
||||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import starlight from '@astrojs/starlight';
|
||||
import netlify from '@astrojs/netlify';
|
||||
import linkValidator from 'starlight-links-validator';
|
||||
import react from '@astrojs/react';
|
||||
import markdoc from '@astrojs/markdoc';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import { sidebar } from './sidebar.mts';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
vite: { plugins: [tailwindcss()] },
|
||||
site: 'https://docs.nx.dev',
|
||||
adapter: netlify(),
|
||||
integrations: [
|
||||
markdoc(),
|
||||
starlight({
|
||||
title: 'Nx',
|
||||
tagline:
|
||||
'An AI-first build platform that connects everything from your editor to CI. Helping you deliver fast, without breaking things.',
|
||||
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,
|
||||
},
|
||||
plugins: [
|
||||
// linkValidator(),
|
||||
],
|
||||
routeMiddleware: ['./src/plugins/banner.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: {
|
||||
Footer: './src/components/layout/Footer.astro',
|
||||
PageFrame: './src/components/layout/PageFrame.astro',
|
||||
Sidebar: './src/components/layout/Sidebar.astro',
|
||||
TwoColumnContent: './src/components/layout/TwoColumnContent.astro',
|
||||
},
|
||||
}),
|
||||
react(),
|
||||
],
|
||||
});
|
||||
@@ -1,378 +0,0 @@
|
||||
import { defineMarkdocConfig, component } 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'],
|
||||
},
|
||||
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',
|
||||
required: true,
|
||||
},
|
||||
smCols: {
|
||||
type: 'Number',
|
||||
required: true,
|
||||
},
|
||||
mdCols: {
|
||||
type: 'Number',
|
||||
required: true,
|
||||
},
|
||||
lgCols: {
|
||||
type: 'Number',
|
||||
required: true,
|
||||
},
|
||||
moreLink: {
|
||||
type: 'String',
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
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'),
|
||||
children: [],
|
||||
attributes: {
|
||||
jsonFile: {
|
||||
type: 'String',
|
||||
},
|
||||
title: {
|
||||
type: 'String',
|
||||
},
|
||||
type: {
|
||||
type: 'String',
|
||||
matches: ['project', 'task'],
|
||||
default: 'project',
|
||||
},
|
||||
height: {
|
||||
type: 'String',
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
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',
|
||||
},
|
||||
},
|
||||
},
|
||||
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',
|
||||
},
|
||||
},
|
||||
},
|
||||
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,20 +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",
|
||||
"tailwindcss": "4.1.11"
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
{
|
||||
"name": "astro-docs",
|
||||
"targets": {
|
||||
"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",
|
||||
"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"
|
||||
}
|
||||
],
|
||||
"command": "astro build",
|
||||
"options": {
|
||||
"cwd": "astro-docs"
|
||||
}
|
||||
},
|
||||
"astro": {
|
||||
"command": "astro",
|
||||
"options": {
|
||||
"cwd": "astro-docs"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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: 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 |
@@ -1,4 +0,0 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://<YOUR SITE>/sitemap-index.xml
|
||||
@@ -1,196 +0,0 @@
|
||||
import type { StarlightUserConfig } from '@astrojs/starlight/types';
|
||||
import { getPluginItems } from './src/plugins/utils/plugin-mappings';
|
||||
export const sidebar: StarlightUserConfig['sidebar'] = [
|
||||
{
|
||||
label: 'Getting Started',
|
||||
collapsed: false,
|
||||
autogenerate: { directory: 'getting-started', collapsed: true },
|
||||
},
|
||||
{
|
||||
label: 'Features',
|
||||
collapsed: false,
|
||||
autogenerate: { directory: 'features', collapsed: true },
|
||||
},
|
||||
{
|
||||
label: 'Guides',
|
||||
collapsed: true,
|
||||
autogenerate: { directory: 'guides', collapsed: true },
|
||||
},
|
||||
{
|
||||
label: 'Concepts',
|
||||
collapsed: true,
|
||||
autogenerate: { directory: 'concepts', collapsed: true },
|
||||
},
|
||||
{
|
||||
label: 'Technologies',
|
||||
collapsed: false,
|
||||
// manually type the tech routes due to complexity of order and structure
|
||||
items: [
|
||||
{
|
||||
label: 'TypeScript',
|
||||
collapsed: true,
|
||||
items: getPluginItems('js', 'typescript'),
|
||||
},
|
||||
{
|
||||
label: 'Angular',
|
||||
collapsed: true,
|
||||
items: [
|
||||
...getPluginItems('angular'),
|
||||
// TODO: angular rspack and rsbuild are special cases
|
||||
//
|
||||
// label: 'Angular Rspack',
|
||||
// link: '/technologies/angular/angular-rspack/',
|
||||
// items: getPluginItems('angular-rspack', 'angular'),
|
||||
// },
|
||||
// {
|
||||
// label: 'Angular Rsbuild',
|
||||
// link: '/technologies/angular/angular-rsbuild/',
|
||||
// items: getPluginItems('angular-rsbuild', 'angular'),
|
||||
// },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'React',
|
||||
collapsed: true,
|
||||
items: [
|
||||
...getPluginItems('react'),
|
||||
{
|
||||
label: 'Next',
|
||||
items: getPluginItems('next', 'react'),
|
||||
},
|
||||
{
|
||||
label: 'Remix',
|
||||
items: getPluginItems('remix', 'react'),
|
||||
},
|
||||
{
|
||||
label: 'React Native',
|
||||
items: getPluginItems('react-native', 'react'),
|
||||
},
|
||||
{
|
||||
label: 'Expo',
|
||||
items: getPluginItems('expo', 'react'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Vue',
|
||||
collapsed: true,
|
||||
items: [
|
||||
...getPluginItems('vue'),
|
||||
{
|
||||
label: 'Nuxt',
|
||||
items: getPluginItems('nuxt', 'vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Node.js',
|
||||
collapsed: true,
|
||||
items: [
|
||||
...getPluginItems('node'),
|
||||
{
|
||||
label: 'Express',
|
||||
items: getPluginItems('express', 'node'),
|
||||
},
|
||||
{
|
||||
label: 'Nest',
|
||||
items: getPluginItems('nest', 'node'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Java',
|
||||
collapsed: true,
|
||||
// when we have maven this will change to not have gradle as the top docs for Java
|
||||
items: getPluginItems('gradle', 'java'),
|
||||
},
|
||||
{
|
||||
label: 'Module Federation',
|
||||
collapsed: true,
|
||||
items: getPluginItems('module-federation'),
|
||||
},
|
||||
{
|
||||
label: 'ESLint',
|
||||
collapsed: true,
|
||||
items: [
|
||||
...getPluginItems('eslint'),
|
||||
{
|
||||
label: 'ESLint Plugin',
|
||||
items: getPluginItems('eslint-plugin', 'eslint'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Build Tools',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
label: 'Webpack',
|
||||
items: getPluginItems('webpack', 'build-tools'),
|
||||
},
|
||||
{
|
||||
label: 'Vite',
|
||||
items: getPluginItems('vite', 'build-tools'),
|
||||
},
|
||||
{
|
||||
label: 'Rollup',
|
||||
items: getPluginItems('rollup', 'build-tools'),
|
||||
},
|
||||
{
|
||||
label: 'ESBuild',
|
||||
items: getPluginItems('esbuild', 'build-tools'),
|
||||
},
|
||||
{
|
||||
label: 'Rspack',
|
||||
items: getPluginItems('rspack', 'build-tools'),
|
||||
},
|
||||
{
|
||||
label: 'Rsbuild',
|
||||
items: getPluginItems('rsbuild', 'build-tools'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Test Tools',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
label: 'Cypress',
|
||||
items: getPluginItems('cypress', 'test-tools'),
|
||||
},
|
||||
{
|
||||
label: 'Jest',
|
||||
items: getPluginItems('jest', 'test-tools'),
|
||||
},
|
||||
{
|
||||
label: 'Playwright',
|
||||
items: getPluginItems('playwright', 'test-tools'),
|
||||
},
|
||||
{
|
||||
label: 'Storybook',
|
||||
items: getPluginItems('storybook', 'test-tools'),
|
||||
},
|
||||
{
|
||||
label: 'Detox',
|
||||
items: getPluginItems('detox', 'test-tools'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Enterprise',
|
||||
collapsed: true,
|
||||
autogenerate: { directory: 'enterprise', collapsed: true },
|
||||
},
|
||||
{
|
||||
label: 'Reference',
|
||||
collapsed: false,
|
||||
autogenerate: { directory: 'references', collapsed: true },
|
||||
},
|
||||
{
|
||||
label: 'Troubleshooting',
|
||||
collapsed: false,
|
||||
autogenerate: { directory: 'troubleshooting', collapsed: true },
|
||||
},
|
||||
];
|
||||
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 334 KiB |
|
Before Width: | Height: | Size: 78 KiB |
@@ -1,233 +0,0 @@
|
||||
{
|
||||
"project": {
|
||||
"name": "myreactapp",
|
||||
"type": "app",
|
||||
"data": {
|
||||
"root": "apps/myreactapp",
|
||||
"targets": {
|
||||
"build": {
|
||||
"options": {
|
||||
"cwd": "apps/myreactapp",
|
||||
"command": "vite build"
|
||||
},
|
||||
"cache": true,
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": [
|
||||
"production",
|
||||
"^production",
|
||||
{
|
||||
"externalDependencies": ["vite"]
|
||||
}
|
||||
],
|
||||
"outputs": ["{workspaceRoot}/dist/apps/myreactapp"],
|
||||
"executor": "nx:run-commands",
|
||||
"configurations": {},
|
||||
"metadata": {
|
||||
"technologies": ["vite"]
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"options": {
|
||||
"cwd": "apps/myreactapp",
|
||||
"command": "vite serve",
|
||||
"continuous": true
|
||||
},
|
||||
"executor": "nx:run-commands",
|
||||
"configurations": {},
|
||||
"metadata": {
|
||||
"technologies": ["vite"]
|
||||
}
|
||||
},
|
||||
"preview": {
|
||||
"options": {
|
||||
"cwd": "apps/myreactapp",
|
||||
"command": "vite preview"
|
||||
},
|
||||
"executor": "nx:run-commands",
|
||||
"configurations": {},
|
||||
"metadata": {
|
||||
"technologies": ["vite"]
|
||||
}
|
||||
},
|
||||
"serve-static": {
|
||||
"executor": "@nx/web:file-server",
|
||||
"options": {
|
||||
"buildTarget": "build",
|
||||
"continuous": true
|
||||
},
|
||||
"configurations": {}
|
||||
},
|
||||
"test": {
|
||||
"options": {
|
||||
"cwd": "apps/myreactapp",
|
||||
"command": "vitest run"
|
||||
},
|
||||
"cache": true,
|
||||
"inputs": [
|
||||
"default",
|
||||
"^production",
|
||||
{
|
||||
"externalDependencies": ["vitest"]
|
||||
}
|
||||
],
|
||||
"outputs": ["{workspaceRoot}/coverage/apps/myreactapp"],
|
||||
"executor": "nx:run-commands",
|
||||
"configurations": {},
|
||||
"metadata": {
|
||||
"technologies": ["vite"]
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"cache": true,
|
||||
"options": {
|
||||
"cwd": "apps/myreactapp",
|
||||
"command": "eslint ."
|
||||
},
|
||||
"inputs": [
|
||||
"default",
|
||||
"{workspaceRoot}/.eslintrc.json",
|
||||
"{workspaceRoot}/apps/myreactapp/.eslintrc.json",
|
||||
"{workspaceRoot}/tools/eslint-rules/**/*",
|
||||
{
|
||||
"externalDependencies": ["eslint"]
|
||||
}
|
||||
],
|
||||
"executor": "nx:run-commands",
|
||||
"configurations": {},
|
||||
"metadata": {
|
||||
"technologies": ["eslint"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "myreactapp",
|
||||
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "apps/myreactapp/src",
|
||||
"projectType": "application",
|
||||
"tags": [],
|
||||
"implicitDependencies": [],
|
||||
"metadata": {
|
||||
"technologies": ["react"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"sourceMap": {
|
||||
"root": ["apps/myreactapp/project.json", "nx/core/project-json"],
|
||||
"targets": ["apps/myreactapp/project.json", "nx/core/project-json"],
|
||||
"targets.build": ["apps/myreactapp/vite.config.ts", "@nx/vite/plugin"],
|
||||
"targets.build.command": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.build.options": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.build.cache": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.build.dependsOn": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.build.inputs": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.build.outputs": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.build.options.cwd": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.serve": ["apps/myreactapp/vite.config.ts", "@nx/vite/plugin"],
|
||||
"targets.serve.command": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.serve.options": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.serve.options.cwd": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.preview": ["apps/myreactapp/vite.config.ts", "@nx/vite/plugin"],
|
||||
"targets.preview.command": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.preview.options": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.preview.options.cwd": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.serve-static": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.serve-static.executor": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.serve-static.options": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.serve-static.options.buildTarget": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.test": ["apps/myreactapp/vite.config.ts", "@nx/vite/plugin"],
|
||||
"targets.test.command": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.test.options": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.test.cache": ["apps/myreactapp/vite.config.ts", "@nx/vite/plugin"],
|
||||
"targets.test.inputs": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.test.outputs": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.test.options.cwd": [
|
||||
"apps/myreactapp/vite.config.ts",
|
||||
"@nx/vite/plugin"
|
||||
],
|
||||
"targets.lint": ["apps/myreactapp/project.json", "@nx/eslint/plugin"],
|
||||
"targets.lint.command": [
|
||||
"apps/myreactapp/project.json",
|
||||
"@nx/eslint/plugin"
|
||||
],
|
||||
"targets.lint.cache": ["apps/myreactapp/project.json", "@nx/eslint/plugin"],
|
||||
"targets.lint.options": [
|
||||
"apps/myreactapp/project.json",
|
||||
"@nx/eslint/plugin"
|
||||
],
|
||||
"targets.lint.inputs": [
|
||||
"apps/myreactapp/project.json",
|
||||
"@nx/eslint/plugin"
|
||||
],
|
||||
"targets.lint.options.cwd": [
|
||||
"apps/myreactapp/project.json",
|
||||
"@nx/eslint/plugin"
|
||||
],
|
||||
"name": ["apps/myreactapp/project.json", "nx/core/project-json"],
|
||||
"$schema": ["apps/myreactapp/project.json", "nx/core/project-json"],
|
||||
"sourceRoot": ["apps/myreactapp/project.json", "nx/core/project-json"],
|
||||
"projectType": ["apps/myreactapp/project.json", "nx/core/project-json"],
|
||||
"tags": ["apps/myreactapp/project.json", "nx/core/project-json"]
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 173 KiB |
|
Before Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 334 KiB |
|
Before Width: | Height: | Size: 172 KiB |
@@ -1,64 +0,0 @@
|
||||
{
|
||||
"projects": [
|
||||
{
|
||||
"name": "app1",
|
||||
"type": "app",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"test": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "app2",
|
||||
"type": "app",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"test": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lib",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"test": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"taskId": "lib:test",
|
||||
"taskGraphs": {
|
||||
"lib:test": {
|
||||
"roots": ["app1:test", "app2:test", "lib:test"],
|
||||
"tasks": {
|
||||
"app1:test": {
|
||||
"id": "app1:test",
|
||||
"target": { "project": "app1", "target": "test" },
|
||||
"projectRoot": "apps/app1",
|
||||
"overrides": {}
|
||||
},
|
||||
"app2:test": {
|
||||
"id": "app2:test",
|
||||
"target": { "project": "app2", "target": "test" },
|
||||
"projectRoot": "apps/app2",
|
||||
"overrides": {}
|
||||
},
|
||||
"lib:test": {
|
||||
"id": "lib:test",
|
||||
"target": { "project": "lib", "target": "test" },
|
||||
"projectRoot": "libs/lib",
|
||||
"overrides": {}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"app1:test": ["lib:test"],
|
||||
"app2:test": ["lib:test"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
{
|
||||
"projects": [
|
||||
{
|
||||
"name": "app1",
|
||||
"type": "app",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"test": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "app2",
|
||||
"type": "app",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"test": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lib",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"test": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"taskId": "lib:test",
|
||||
"taskGraphs": {
|
||||
"lib:test": {
|
||||
"roots": ["app1:test", "app2:test", "lib:test"],
|
||||
"tasks": {
|
||||
"app1:test": {
|
||||
"id": "app1:test",
|
||||
"target": { "project": "app1", "target": "test" },
|
||||
"projectRoot": "apps/app1",
|
||||
"overrides": {}
|
||||
},
|
||||
"app2:test": {
|
||||
"id": "app2:test",
|
||||
"target": { "project": "app2", "target": "test" },
|
||||
"projectRoot": "apps/app2",
|
||||
"overrides": {}
|
||||
},
|
||||
"lib:test": {
|
||||
"id": "lib:test",
|
||||
"target": { "project": "lib", "target": "test" },
|
||||
"projectRoot": "libs/lib",
|
||||
"overrides": {}
|
||||
}
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 196 KiB |
|
Before Width: | Height: | Size: 408 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 15 KiB |
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"projects": [
|
||||
{
|
||||
"name": "lib",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"test": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"taskId": "lib:test",
|
||||
"taskGraphs": {
|
||||
"lib:test": {
|
||||
"roots": ["lib:test"],
|
||||
"tasks": {
|
||||
"lib:test": {
|
||||
"id": "lib:test",
|
||||
"target": { "project": "lib", "target": "test" },
|
||||
"projectRoot": "libs/lib",
|
||||
"overrides": {}
|
||||
}
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 112 KiB |
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"projects": [
|
||||
{
|
||||
"name": "app1",
|
||||
"type": "app",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"test": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "app2",
|
||||
"type": "app",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"test": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lib",
|
||||
"type": "lib",
|
||||
"data": {
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"test": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"app1": [{ "source": "app1", "target": "lib", "type": "static" }],
|
||||
"app2": [{ "source": "app2", "target": "lib", "type": "static" }],
|
||||
"lib": []
|
||||
},
|
||||
"workspaceLayout": {
|
||||
"appsDir": "apps",
|
||||
"libsDir": "libs"
|
||||
},
|
||||
"affectedProjectIds": [],
|
||||
"focus": null,
|
||||
"groupByFolder": false,
|
||||
"exclude": []
|
||||
}
|
||||
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 207 KiB |
|
Before Width: | Height: | Size: 174 KiB |
|
Before Width: | Height: | Size: 208 KiB |
|
Before Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 566 KiB |
|
Before Width: | Height: | Size: 864 KiB |
|
Before Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 57 KiB |