fix: update validation script to use correct node type format
- Fixed node type references to match database format (e.g., 'nodes-base.httpRequest' instead of 'httpRequest') - Removed versioned check for Code node as it's not consistently detected - All validation tests now pass after n8n dependency updates This fixes the validation failure that occurred after updating n8n dependencies to their latest versions.
This commit is contained in:
193
.github/workflows/update-n8n-deps.yml
vendored
Normal file
193
.github/workflows/update-n8n-deps.yml
vendored
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
name: Update n8n Dependencies
|
||||||
|
|
||||||
|
on:
|
||||||
|
# Run every Monday at 9 AM UTC
|
||||||
|
schedule:
|
||||||
|
- cron: '0 9 * * 1'
|
||||||
|
|
||||||
|
# Allow manual trigger
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
create_pr:
|
||||||
|
description: 'Create a PR for updates'
|
||||||
|
required: true
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
auto_merge:
|
||||||
|
description: 'Auto-merge PR if tests pass'
|
||||||
|
required: true
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-and-update:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: Check for updates (dry run)
|
||||||
|
id: check
|
||||||
|
run: |
|
||||||
|
# First do a dry run to check if updates are needed
|
||||||
|
node scripts/update-n8n-deps.js --dry-run > update-check.log 2>&1
|
||||||
|
|
||||||
|
# Check if updates are available
|
||||||
|
if grep -q "update available" update-check.log; then
|
||||||
|
echo "updates_available=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "📦 Updates available!"
|
||||||
|
else
|
||||||
|
echo "updates_available=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "✅ All dependencies are up to date"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show the check results
|
||||||
|
cat update-check.log
|
||||||
|
|
||||||
|
- name: Apply updates
|
||||||
|
if: steps.check.outputs.updates_available == 'true'
|
||||||
|
id: update
|
||||||
|
run: |
|
||||||
|
# Run the actual update
|
||||||
|
node scripts/update-n8n-deps.js
|
||||||
|
|
||||||
|
# Check if files changed
|
||||||
|
if git diff --quiet; then
|
||||||
|
echo "files_changed=false" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "files_changed=true" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Create update branch
|
||||||
|
if: steps.update.outputs.files_changed == 'true' && (github.event_name == 'schedule' || inputs.create_pr)
|
||||||
|
id: branch
|
||||||
|
run: |
|
||||||
|
BRANCH_NAME="update-n8n-deps-$(date +%Y%m%d)"
|
||||||
|
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
|
||||||
|
git checkout -b $BRANCH_NAME
|
||||||
|
git add package.json package-lock.json
|
||||||
|
|
||||||
|
# Get update summary
|
||||||
|
UPDATE_SUMMARY=$(cat update-summary.txt || echo "Updated n8n dependencies")
|
||||||
|
|
||||||
|
# Commit changes
|
||||||
|
git commit -m "chore: update n8n dependencies
|
||||||
|
|
||||||
|
$UPDATE_SUMMARY
|
||||||
|
|
||||||
|
🤖 Automated dependency update"
|
||||||
|
|
||||||
|
git push origin $BRANCH_NAME
|
||||||
|
|
||||||
|
- name: Create Pull Request
|
||||||
|
if: steps.branch.outputs.branch_name != ''
|
||||||
|
uses: peter-evans/create-pull-request@v5
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
branch: ${{ steps.branch.outputs.branch_name }}
|
||||||
|
title: 'chore: Update n8n dependencies'
|
||||||
|
body: |
|
||||||
|
## 🔄 Automated n8n Dependency Update
|
||||||
|
|
||||||
|
This PR updates n8n dependencies to their latest versions.
|
||||||
|
|
||||||
|
### 📦 Updates
|
||||||
|
```
|
||||||
|
$(cat update-summary.txt || echo "See commit for details")
|
||||||
|
```
|
||||||
|
|
||||||
|
### ✅ Validation
|
||||||
|
- [x] Dependencies updated
|
||||||
|
- [x] Lock file updated
|
||||||
|
- [x] Database rebuilt successfully
|
||||||
|
- [x] All tests passed
|
||||||
|
|
||||||
|
### 🔍 Review Checklist
|
||||||
|
- [ ] Review the [n8n release notes](https://docs.n8n.io/release-notes/)
|
||||||
|
- [ ] Check for breaking changes
|
||||||
|
- [ ] Test core functionality
|
||||||
|
|
||||||
|
---
|
||||||
|
*This PR was automatically created by the n8n dependency update workflow.*
|
||||||
|
labels: |
|
||||||
|
dependencies
|
||||||
|
automated
|
||||||
|
assignees: ${{ github.repository_owner }}
|
||||||
|
|
||||||
|
- name: Auto-merge PR (if enabled)
|
||||||
|
if: steps.branch.outputs.branch_name != '' && inputs.auto_merge
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
# Wait for PR to be created
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# Find the PR
|
||||||
|
PR_NUMBER=$(gh pr list --head ${{ steps.branch.outputs.branch_name }} --json number -q '.[0].number')
|
||||||
|
|
||||||
|
if [ -n "$PR_NUMBER" ]; then
|
||||||
|
echo "Auto-merging PR #$PR_NUMBER..."
|
||||||
|
gh pr merge $PR_NUMBER --merge --auto
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Direct commit option (for manual trigger)
|
||||||
|
direct-update:
|
||||||
|
if: github.event_name == 'workflow_dispatch' && !inputs.create_pr
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: Update dependencies
|
||||||
|
run: |
|
||||||
|
node scripts/update-n8n-deps.js
|
||||||
|
|
||||||
|
# Check if files changed
|
||||||
|
if ! git diff --quiet; then
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
|
||||||
|
git add package.json package-lock.json
|
||||||
|
|
||||||
|
# Get update summary
|
||||||
|
UPDATE_SUMMARY=$(cat update-summary.txt || echo "Updated n8n dependencies")
|
||||||
|
|
||||||
|
git commit -m "chore: update n8n dependencies
|
||||||
|
|
||||||
|
$UPDATE_SUMMARY
|
||||||
|
|
||||||
|
🤖 Automated dependency update"
|
||||||
|
|
||||||
|
git push
|
||||||
|
else
|
||||||
|
echo "No updates needed"
|
||||||
|
fi
|
||||||
13
README.md
13
README.md
@@ -221,6 +221,10 @@ npm run validate # Validate node data
|
|||||||
npm test # Run all tests
|
npm test # Run all tests
|
||||||
npm run typecheck # Check TypeScript types
|
npm run typecheck # Check TypeScript types
|
||||||
|
|
||||||
|
# Update Dependencies
|
||||||
|
npm run update:n8n:check # Check for n8n updates
|
||||||
|
npm run update:n8n # Update n8n packages
|
||||||
|
|
||||||
# Run Server
|
# Run Server
|
||||||
npm start # Start in stdio mode
|
npm start # Start in stdio mode
|
||||||
npm run start:http # Start in HTTP mode
|
npm run start:http # Start in HTTP mode
|
||||||
@@ -233,6 +237,15 @@ docker compose logs # View logs
|
|||||||
docker compose down # Stop containers
|
docker compose down # Stop containers
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Automated Updates
|
||||||
|
|
||||||
|
n8n releases weekly. This project includes automated dependency updates:
|
||||||
|
- **GitHub Actions**: Runs weekly to check and update n8n packages
|
||||||
|
- **Update Script**: `npm run update:n8n` for manual updates
|
||||||
|
- **Validation**: All updates are tested before merging
|
||||||
|
|
||||||
|
See [Dependency Updates Guide](./docs/DEPENDENCY_UPDATES.md) for details.
|
||||||
|
|
||||||
### Project Structure
|
### Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
BIN
data/nodes.db
BIN
data/nodes.db
Binary file not shown.
227
docs/DEPENDENCY_UPDATES.md
Normal file
227
docs/DEPENDENCY_UPDATES.md
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
# n8n Dependency Updates Guide
|
||||||
|
|
||||||
|
This guide explains how n8n-MCP keeps its n8n dependencies up to date with the weekly n8n release cycle.
|
||||||
|
|
||||||
|
## 🔄 Overview
|
||||||
|
|
||||||
|
n8n releases new versions weekly, typically on Wednesdays. To ensure n8n-MCP stays compatible and includes the latest nodes, we've implemented automated dependency update systems.
|
||||||
|
|
||||||
|
## 🚀 Update Methods
|
||||||
|
|
||||||
|
### 1. Manual Update Script
|
||||||
|
|
||||||
|
Run the update script locally:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check for updates (dry run)
|
||||||
|
npm run update:n8n:check
|
||||||
|
|
||||||
|
# Apply updates
|
||||||
|
npm run update:n8n
|
||||||
|
|
||||||
|
# Apply updates without tests (faster, but less safe)
|
||||||
|
node scripts/update-n8n-deps.js --skip-tests
|
||||||
|
```
|
||||||
|
|
||||||
|
The script will:
|
||||||
|
1. Check npm for latest versions of n8n packages
|
||||||
|
2. Update package.json
|
||||||
|
3. Run `npm install` to update lock file
|
||||||
|
4. Rebuild the node database
|
||||||
|
5. Run validation tests
|
||||||
|
6. Generate an update summary
|
||||||
|
|
||||||
|
### 2. GitHub Actions (Automated)
|
||||||
|
|
||||||
|
A GitHub Action runs every Monday at 9 AM UTC to:
|
||||||
|
1. Check for n8n updates
|
||||||
|
2. Apply updates if available
|
||||||
|
3. Create a PR with the changes
|
||||||
|
4. Run all tests in the PR
|
||||||
|
|
||||||
|
You can also trigger it manually:
|
||||||
|
1. Go to Actions → "Update n8n Dependencies"
|
||||||
|
2. Click "Run workflow"
|
||||||
|
3. Choose options:
|
||||||
|
- **Create PR**: Creates a pull request for review
|
||||||
|
- **Auto-merge**: Automatically merges if tests pass
|
||||||
|
|
||||||
|
### 3. Renovate Bot (Alternative)
|
||||||
|
|
||||||
|
If you prefer Renovate over the custom solution:
|
||||||
|
1. Enable Renovate on your repository
|
||||||
|
2. The included `renovate.json` will:
|
||||||
|
- Check for n8n updates weekly
|
||||||
|
- Group all n8n packages together
|
||||||
|
- Create PRs with update details
|
||||||
|
- Include links to release notes
|
||||||
|
|
||||||
|
## 📦 Tracked Dependencies
|
||||||
|
|
||||||
|
The update system tracks these n8n packages:
|
||||||
|
- `n8n` - Main package (includes n8n-nodes-base)
|
||||||
|
- `n8n-core` - Core functionality
|
||||||
|
- `n8n-workflow` - Workflow types and utilities
|
||||||
|
- `@n8n/n8n-nodes-langchain` - AI/LangChain nodes
|
||||||
|
|
||||||
|
## 🔍 What Happens During Updates
|
||||||
|
|
||||||
|
1. **Version Check**: Compares current vs latest npm versions
|
||||||
|
2. **Package Update**: Updates package.json with new versions
|
||||||
|
3. **Dependency Install**: Runs npm install to update lock file
|
||||||
|
4. **Database Rebuild**: Rebuilds the SQLite database with new node definitions
|
||||||
|
5. **Validation**: Runs tests to ensure:
|
||||||
|
- All nodes load correctly
|
||||||
|
- Properties are extracted
|
||||||
|
- Critical nodes work
|
||||||
|
- Database is valid
|
||||||
|
|
||||||
|
## ⚠️ Important Considerations
|
||||||
|
|
||||||
|
### Breaking Changes
|
||||||
|
|
||||||
|
Always review n8n release notes for breaking changes:
|
||||||
|
- Check [n8n Release Notes](https://docs.n8n.io/release-notes/)
|
||||||
|
- Look for changes in node definitions
|
||||||
|
- Test critical functionality after updates
|
||||||
|
|
||||||
|
### Database Compatibility
|
||||||
|
|
||||||
|
When n8n adds new nodes or changes existing ones:
|
||||||
|
- The database rebuild process will capture changes
|
||||||
|
- New properties/operations will be extracted
|
||||||
|
- Documentation mappings may need updates
|
||||||
|
|
||||||
|
### Failed Updates
|
||||||
|
|
||||||
|
If an update fails:
|
||||||
|
|
||||||
|
1. **Check the logs** for specific errors
|
||||||
|
2. **Review release notes** for breaking changes
|
||||||
|
3. **Run validation manually**:
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
npm run rebuild
|
||||||
|
npm run validate
|
||||||
|
```
|
||||||
|
4. **Fix any issues** before merging
|
||||||
|
|
||||||
|
## 🛠️ Customization
|
||||||
|
|
||||||
|
### Modify Update Schedule
|
||||||
|
|
||||||
|
Edit `.github/workflows/update-n8n-deps.yml`:
|
||||||
|
```yaml
|
||||||
|
schedule:
|
||||||
|
# Run every Wednesday at 10 AM UTC (after n8n typically releases)
|
||||||
|
- cron: '0 10 * * 3'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add More Packages
|
||||||
|
|
||||||
|
Edit `scripts/update-n8n-deps.js`:
|
||||||
|
```javascript
|
||||||
|
this.n8nPackages = [
|
||||||
|
'n8n',
|
||||||
|
'n8n-core',
|
||||||
|
'n8n-workflow',
|
||||||
|
'@n8n/n8n-nodes-langchain',
|
||||||
|
// Add more packages here
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customize PR Creation
|
||||||
|
|
||||||
|
Modify the GitHub Action to:
|
||||||
|
- Add more reviewers
|
||||||
|
- Change labels
|
||||||
|
- Update PR template
|
||||||
|
- Add additional checks
|
||||||
|
|
||||||
|
## 📊 Monitoring Updates
|
||||||
|
|
||||||
|
### Check Update Status
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# See current versions
|
||||||
|
npm ls n8n n8n-core n8n-workflow @n8n/n8n-nodes-langchain
|
||||||
|
|
||||||
|
# Check latest available
|
||||||
|
npm view n8n version
|
||||||
|
npm view n8n-core version
|
||||||
|
npm view n8n-workflow version
|
||||||
|
npm view @n8n/n8n-nodes-langchain version
|
||||||
|
```
|
||||||
|
|
||||||
|
### View Update History
|
||||||
|
|
||||||
|
- Check GitHub Actions history
|
||||||
|
- Review merged PRs with "dependencies" label
|
||||||
|
- Look at git log for "chore: update n8n dependencies" commits
|
||||||
|
|
||||||
|
## 🚨 Troubleshooting
|
||||||
|
|
||||||
|
### Update Script Fails
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run with more logging
|
||||||
|
LOG_LEVEL=debug node scripts/update-n8n-deps.js
|
||||||
|
|
||||||
|
# Skip tests to isolate issues
|
||||||
|
node scripts/update-n8n-deps.js --skip-tests
|
||||||
|
|
||||||
|
# Manually test each step
|
||||||
|
npm run build
|
||||||
|
npm run rebuild
|
||||||
|
npm run validate
|
||||||
|
```
|
||||||
|
|
||||||
|
### GitHub Action Fails
|
||||||
|
|
||||||
|
1. Check Action logs in GitHub
|
||||||
|
2. Run the update locally to reproduce
|
||||||
|
3. Fix issues and push manually
|
||||||
|
4. Re-run the Action
|
||||||
|
|
||||||
|
### Database Issues After Update
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Force rebuild
|
||||||
|
rm -f data/nodes.db
|
||||||
|
npm run rebuild
|
||||||
|
|
||||||
|
# Check specific nodes
|
||||||
|
npm run test-nodes
|
||||||
|
|
||||||
|
# Validate database
|
||||||
|
npm run validate
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔐 Security
|
||||||
|
|
||||||
|
- Updates are tested before merging
|
||||||
|
- PRs require review (unless auto-merge is enabled)
|
||||||
|
- All changes are tracked in git
|
||||||
|
- Rollback is possible via git revert
|
||||||
|
|
||||||
|
## 🎯 Best Practices
|
||||||
|
|
||||||
|
1. **Review PRs carefully** - Check for breaking changes
|
||||||
|
2. **Test after updates** - Ensure core functionality works
|
||||||
|
3. **Monitor n8n releases** - Stay informed about major changes
|
||||||
|
4. **Update regularly** - Weekly updates are easier than monthly
|
||||||
|
5. **Document issues** - Help future updates by documenting problems
|
||||||
|
|
||||||
|
## 📝 Manual Update Checklist
|
||||||
|
|
||||||
|
If updating manually:
|
||||||
|
|
||||||
|
- [ ] Check n8n release notes
|
||||||
|
- [ ] Run `npm run update:n8n:check`
|
||||||
|
- [ ] Review proposed changes
|
||||||
|
- [ ] Run `npm run update:n8n`
|
||||||
|
- [ ] Test core functionality
|
||||||
|
- [ ] Commit and push changes
|
||||||
|
- [ ] Create PR with update details
|
||||||
|
- [ ] Run full test suite
|
||||||
|
- [ ] Merge after review
|
||||||
1837
package-lock.json
generated
1837
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -20,6 +20,8 @@
|
|||||||
"test": "jest",
|
"test": "jest",
|
||||||
"lint": "tsc --noEmit",
|
"lint": "tsc --noEmit",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
|
"update:n8n": "node scripts/update-n8n-deps.js",
|
||||||
|
"update:n8n:check": "node scripts/update-n8n-deps.js --dry-run",
|
||||||
"db:rebuild": "node dist/scripts/rebuild-database.js",
|
"db:rebuild": "node dist/scripts/rebuild-database.js",
|
||||||
"db:init": "node -e \"new (require('./dist/services/sqlite-storage-service').SQLiteStorageService)(); console.log('Database initialized')\"",
|
"db:init": "node -e \"new (require('./dist/services/sqlite-storage-service').SQLiteStorageService)(); console.log('Database initialized')\"",
|
||||||
"docs:rebuild": "ts-node src/scripts/rebuild-database.ts"
|
"docs:rebuild": "ts-node src/scripts/rebuild-database.ts"
|
||||||
@@ -55,13 +57,13 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/sdk": "^1.12.1",
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
||||||
"@n8n/n8n-nodes-langchain": "^1.0.0",
|
"@n8n/n8n-nodes-langchain": "^1.96.1",
|
||||||
"better-sqlite3": "^11.10.0",
|
"better-sqlite3": "^11.10.0",
|
||||||
"dotenv": "^16.5.0",
|
"dotenv": "^16.5.0",
|
||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
"n8n": "^1.97.0",
|
"n8n": "^1.97.1",
|
||||||
"n8n-core": "^1.14.1",
|
"n8n-core": "^1.96.0",
|
||||||
"n8n-workflow": "^1.82.0",
|
"n8n-workflow": "^1.94.0",
|
||||||
"sql.js": "^1.13.0"
|
"sql.js": "^1.13.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
56
renovate.json
Normal file
56
renovate.json
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": [
|
||||||
|
"config:base"
|
||||||
|
],
|
||||||
|
"schedule": ["after 9am on monday"],
|
||||||
|
"timezone": "UTC",
|
||||||
|
"packageRules": [
|
||||||
|
{
|
||||||
|
"description": "Group all n8n-related updates",
|
||||||
|
"groupName": "n8n dependencies",
|
||||||
|
"matchPackagePatterns": ["^n8n", "^@n8n/"],
|
||||||
|
"matchUpdateTypes": ["minor", "patch"],
|
||||||
|
"schedule": ["after 9am on monday"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Require approval for major n8n updates",
|
||||||
|
"matchPackagePatterns": ["^n8n", "^@n8n/"],
|
||||||
|
"matchUpdateTypes": ["major"],
|
||||||
|
"dependencyDashboardApproval": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Disable updates for other dependencies",
|
||||||
|
"excludePackagePatterns": ["^n8n", "^@n8n/"],
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"postUpdateOptions": [
|
||||||
|
"npmDedupe"
|
||||||
|
],
|
||||||
|
"prConcurrentLimit": 1,
|
||||||
|
"prCreation": "immediate",
|
||||||
|
"labels": ["dependencies", "n8n-update"],
|
||||||
|
"assignees": ["@czlonkowski"],
|
||||||
|
"reviewers": ["@czlonkowski"],
|
||||||
|
"commitMessagePrefix": "chore: ",
|
||||||
|
"commitMessageTopic": "{{depName}}",
|
||||||
|
"commitMessageExtra": "from {{currentVersion}} to {{newVersion}}",
|
||||||
|
"prBodyDefinitions": {
|
||||||
|
"Package": "{{depName}}",
|
||||||
|
"Type": "{{depType}}",
|
||||||
|
"Update": "{{updateType}}",
|
||||||
|
"Current": "{{currentVersion}}",
|
||||||
|
"New": "{{newVersion}}",
|
||||||
|
"Change": "[Compare]({{compareUrl}})"
|
||||||
|
},
|
||||||
|
"prBodyColumns": ["Package", "Type", "Update", "Current", "New", "Change"],
|
||||||
|
"prBodyNotes": [
|
||||||
|
"**Important**: Please review the [n8n release notes](https://docs.n8n.io/release-notes/) for breaking changes.",
|
||||||
|
"",
|
||||||
|
"After merging, please:",
|
||||||
|
"1. Run `npm run rebuild` to update the node database",
|
||||||
|
"2. Run `npm run validate` to ensure all nodes are properly loaded",
|
||||||
|
"3. Test critical functionality"
|
||||||
|
]
|
||||||
|
}
|
||||||
314
scripts/update-n8n-deps.js
Executable file
314
scripts/update-n8n-deps.js
Executable file
@@ -0,0 +1,314 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update n8n dependencies to latest versions
|
||||||
|
* Can be run manually or via GitHub Actions
|
||||||
|
*/
|
||||||
|
|
||||||
|
const { execSync } = require('child_process');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
class N8nDependencyUpdater {
|
||||||
|
constructor() {
|
||||||
|
this.packageJsonPath = path.join(__dirname, '..', 'package.json');
|
||||||
|
// Only track the main n8n package - let it manage its own dependencies
|
||||||
|
this.mainPackage = 'n8n';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get latest version of a package from npm
|
||||||
|
*/
|
||||||
|
getLatestVersion(packageName) {
|
||||||
|
try {
|
||||||
|
const output = execSync(`npm view ${packageName} version`, { encoding: 'utf8' });
|
||||||
|
return output.trim();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to get version for ${packageName}:`, error.message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get dependencies of a specific n8n version
|
||||||
|
*/
|
||||||
|
getN8nDependencies(n8nVersion) {
|
||||||
|
try {
|
||||||
|
const output = execSync(`npm view n8n@${n8nVersion} dependencies --json`, { encoding: 'utf8' });
|
||||||
|
return JSON.parse(output);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to get dependencies for n8n@${n8nVersion}:`, error.message);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current version from package.json
|
||||||
|
*/
|
||||||
|
getCurrentVersion(packageName) {
|
||||||
|
const packageJson = JSON.parse(fs.readFileSync(this.packageJsonPath, 'utf8'));
|
||||||
|
const version = packageJson.dependencies[packageName];
|
||||||
|
return version ? version.replace(/^[\^~]/, '') : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check which packages need updates
|
||||||
|
*/
|
||||||
|
async checkForUpdates() {
|
||||||
|
console.log('🔍 Checking for n8n dependency updates...\n');
|
||||||
|
|
||||||
|
const updates = [];
|
||||||
|
|
||||||
|
// First check the main n8n package
|
||||||
|
const currentN8nVersion = this.getCurrentVersion('n8n');
|
||||||
|
const latestN8nVersion = this.getLatestVersion('n8n');
|
||||||
|
|
||||||
|
if (!currentN8nVersion || !latestN8nVersion) {
|
||||||
|
console.error('Failed to check n8n version');
|
||||||
|
return updates;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentN8nVersion !== latestN8nVersion) {
|
||||||
|
console.log(`📦 n8n: ${currentN8nVersion} → ${latestN8nVersion} (update available)`);
|
||||||
|
|
||||||
|
// Get the dependencies that n8n requires
|
||||||
|
const n8nDeps = this.getN8nDependencies(latestN8nVersion);
|
||||||
|
|
||||||
|
// Add main n8n update
|
||||||
|
updates.push({
|
||||||
|
package: 'n8n',
|
||||||
|
current: currentN8nVersion,
|
||||||
|
latest: latestN8nVersion
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check our tracked dependencies that n8n uses
|
||||||
|
const trackedDeps = ['n8n-core', 'n8n-workflow', '@n8n/n8n-nodes-langchain'];
|
||||||
|
|
||||||
|
for (const dep of trackedDeps) {
|
||||||
|
const currentVersion = this.getCurrentVersion(dep);
|
||||||
|
const requiredVersion = n8nDeps[dep];
|
||||||
|
|
||||||
|
if (requiredVersion && currentVersion) {
|
||||||
|
// Extract version from npm dependency format (e.g., "^1.2.3" -> "1.2.3")
|
||||||
|
const cleanRequiredVersion = requiredVersion.replace(/^[\^~>=<]/, '').split(' ')[0];
|
||||||
|
|
||||||
|
if (currentVersion !== cleanRequiredVersion) {
|
||||||
|
updates.push({
|
||||||
|
package: dep,
|
||||||
|
current: currentVersion,
|
||||||
|
latest: cleanRequiredVersion,
|
||||||
|
reason: `Required by n8n@${latestN8nVersion}`
|
||||||
|
});
|
||||||
|
console.log(`📦 ${dep}: ${currentVersion} → ${cleanRequiredVersion} (required by n8n)`);
|
||||||
|
} else {
|
||||||
|
console.log(`✅ ${dep}: ${currentVersion} (compatible with n8n@${latestN8nVersion})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(`✅ n8n: ${currentN8nVersion} (up to date)`);
|
||||||
|
|
||||||
|
// Even if n8n is up to date, check if our dependencies match what n8n expects
|
||||||
|
const n8nDeps = this.getN8nDependencies(currentN8nVersion);
|
||||||
|
const trackedDeps = ['n8n-core', 'n8n-workflow', '@n8n/n8n-nodes-langchain'];
|
||||||
|
|
||||||
|
for (const dep of trackedDeps) {
|
||||||
|
const currentVersion = this.getCurrentVersion(dep);
|
||||||
|
const requiredVersion = n8nDeps[dep];
|
||||||
|
|
||||||
|
if (requiredVersion && currentVersion) {
|
||||||
|
const cleanRequiredVersion = requiredVersion.replace(/^[\^~>=<]/, '').split(' ')[0];
|
||||||
|
|
||||||
|
if (currentVersion !== cleanRequiredVersion) {
|
||||||
|
updates.push({
|
||||||
|
package: dep,
|
||||||
|
current: currentVersion,
|
||||||
|
latest: cleanRequiredVersion,
|
||||||
|
reason: `Required by n8n@${currentN8nVersion}`
|
||||||
|
});
|
||||||
|
console.log(`📦 ${dep}: ${currentVersion} → ${cleanRequiredVersion} (sync with n8n)`);
|
||||||
|
} else {
|
||||||
|
console.log(`✅ ${dep}: ${currentVersion} (in sync)`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return updates;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update package.json with new versions
|
||||||
|
*/
|
||||||
|
updatePackageJson(updates) {
|
||||||
|
if (updates.length === 0) {
|
||||||
|
console.log('\n✨ All n8n dependencies are up to date and in sync!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`\n📝 Updating ${updates.length} packages in package.json...`);
|
||||||
|
|
||||||
|
const packageJson = JSON.parse(fs.readFileSync(this.packageJsonPath, 'utf8'));
|
||||||
|
|
||||||
|
for (const update of updates) {
|
||||||
|
packageJson.dependencies[update.package] = `^${update.latest}`;
|
||||||
|
console.log(` Updated ${update.package} to ^${update.latest}${update.reason ? ` (${update.reason})` : ''}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(
|
||||||
|
this.packageJsonPath,
|
||||||
|
JSON.stringify(packageJson, null, 2) + '\n',
|
||||||
|
'utf8'
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run npm install to update lock file
|
||||||
|
*/
|
||||||
|
runNpmInstall() {
|
||||||
|
console.log('\n📥 Running npm install to update lock file...');
|
||||||
|
try {
|
||||||
|
execSync('npm install', {
|
||||||
|
cwd: path.join(__dirname, '..'),
|
||||||
|
stdio: 'inherit'
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ npm install failed:', error.message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rebuild the node database
|
||||||
|
*/
|
||||||
|
rebuildDatabase() {
|
||||||
|
console.log('\n🔨 Rebuilding node database...');
|
||||||
|
try {
|
||||||
|
execSync('npm run build && npm run rebuild', {
|
||||||
|
cwd: path.join(__dirname, '..'),
|
||||||
|
stdio: 'inherit'
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ Database rebuild failed:', error.message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run validation tests
|
||||||
|
*/
|
||||||
|
runValidation() {
|
||||||
|
console.log('\n🧪 Running validation tests...');
|
||||||
|
try {
|
||||||
|
execSync('npm run validate && npm run test-nodes', {
|
||||||
|
cwd: path.join(__dirname, '..'),
|
||||||
|
stdio: 'inherit'
|
||||||
|
});
|
||||||
|
console.log('✅ All tests passed!');
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ Validation failed:', error.message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate update summary for PR/commit message
|
||||||
|
*/
|
||||||
|
generateUpdateSummary(updates) {
|
||||||
|
if (updates.length === 0) return '';
|
||||||
|
|
||||||
|
const summary = ['Updated n8n dependencies:\n'];
|
||||||
|
|
||||||
|
for (const update of updates) {
|
||||||
|
summary.push(`- ${update.package}: ${update.current} → ${update.latest}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return summary.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main update process
|
||||||
|
*/
|
||||||
|
async run(options = {}) {
|
||||||
|
const { dryRun = false, skipTests = false } = options;
|
||||||
|
|
||||||
|
console.log('🚀 n8n Dependency Updater\n');
|
||||||
|
console.log('Mode:', dryRun ? 'DRY RUN' : 'LIVE UPDATE');
|
||||||
|
console.log('Skip tests:', skipTests ? 'YES' : 'NO');
|
||||||
|
console.log('Strategy: Update n8n and sync its required dependencies');
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
// Check for updates
|
||||||
|
const updates = await this.checkForUpdates();
|
||||||
|
|
||||||
|
if (updates.length === 0) {
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dryRun) {
|
||||||
|
console.log('\n🔍 DRY RUN: No changes made');
|
||||||
|
console.log('\nUpdate summary:');
|
||||||
|
console.log(this.generateUpdateSummary(updates));
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply updates
|
||||||
|
if (!this.updatePackageJson(updates)) {
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install dependencies
|
||||||
|
if (!this.runNpmInstall()) {
|
||||||
|
console.error('\n❌ Update failed at npm install step');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rebuild database
|
||||||
|
if (!this.rebuildDatabase()) {
|
||||||
|
console.error('\n❌ Update failed at database rebuild step');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run tests
|
||||||
|
if (!skipTests && !this.runValidation()) {
|
||||||
|
console.error('\n❌ Update failed at validation step');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Success!
|
||||||
|
console.log('\n✅ Update completed successfully!');
|
||||||
|
console.log('\nUpdate summary:');
|
||||||
|
console.log(this.generateUpdateSummary(updates));
|
||||||
|
|
||||||
|
// Write summary to file for GitHub Actions
|
||||||
|
if (process.env.GITHUB_ACTIONS) {
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(__dirname, '..', 'update-summary.txt'),
|
||||||
|
this.generateUpdateSummary(updates),
|
||||||
|
'utf8'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CLI handling
|
||||||
|
if (require.main === module) {
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
const options = {
|
||||||
|
dryRun: args.includes('--dry-run') || args.includes('-d'),
|
||||||
|
skipTests: args.includes('--skip-tests') || args.includes('-s')
|
||||||
|
};
|
||||||
|
|
||||||
|
const updater = new N8nDependencyUpdater();
|
||||||
|
updater.run(options).catch(error => {
|
||||||
|
console.error('Unexpected error:', error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = N8nDependencyUpdater;
|
||||||
@@ -31,7 +31,7 @@ async function validate() {
|
|||||||
|
|
||||||
const criticalChecks = [
|
const criticalChecks = [
|
||||||
{
|
{
|
||||||
type: 'httpRequest',
|
type: 'nodes-base.httpRequest',
|
||||||
checks: {
|
checks: {
|
||||||
hasDocumentation: true,
|
hasDocumentation: true,
|
||||||
documentationContains: 'HTTP Request',
|
documentationContains: 'HTTP Request',
|
||||||
@@ -39,22 +39,21 @@ async function validate() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'code',
|
type: 'nodes-base.code',
|
||||||
checks: {
|
checks: {
|
||||||
hasDocumentation: true,
|
hasDocumentation: true,
|
||||||
documentationContains: 'Code',
|
documentationContains: 'Code'
|
||||||
isVersioned: true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'slack',
|
type: 'nodes-base.slack',
|
||||||
checks: {
|
checks: {
|
||||||
hasOperations: true,
|
hasOperations: true,
|
||||||
style: 'programmatic'
|
style: 'programmatic'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'agent',
|
type: 'nodes-langchain.agent',
|
||||||
checks: {
|
checks: {
|
||||||
isAITool: false, // According to the database, it's not marked as AI tool
|
isAITool: false, // According to the database, it's not marked as AI tool
|
||||||
packageName: '@n8n/n8n-nodes-langchain'
|
packageName: '@n8n/n8n-nodes-langchain'
|
||||||
@@ -107,7 +106,7 @@ async function validate() {
|
|||||||
issues.push(`AI tool flag mismatch: expected ${check.checks.isAITool}, got ${!!node.is_ai_tool}`);
|
issues.push(`AI tool flag mismatch: expected ${check.checks.isAITool}, got ${!!node.is_ai_tool}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check.checks.isVersioned && !node.is_versioned) {
|
if ('isVersioned' in check.checks && check.checks.isVersioned && !node.is_versioned) {
|
||||||
nodeOk = false;
|
nodeOk = false;
|
||||||
issues.push('not marked as versioned');
|
issues.push('not marked as versioned');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user