2 Commits

Author SHA1 Message Date
Bas
13968904c0 "Claude Code Review workflow" 2025-09-12 16:25:57 +02:00
Bas
e3b79710ba "Claude PR Assistant workflow" 2025-09-12 16:25:56 +02:00
3 changed files with 306 additions and 29 deletions

View File

@@ -0,0 +1,78 @@
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
# Optional: Only run on specific file changes
# paths:
# - "src/**/*.ts"
# - "src/**/*.tsx"
# - "src/**/*.js"
# - "src/**/*.jsx"
jobs:
claude-review:
# Optional: Filter by PR author
# if: |
# github.event.pull_request.user.login == 'external-contributor' ||
# github.event.pull_request.user.login == 'new-developer' ||
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@beta
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4.1)
# model: "claude-opus-4-1-20250805"
# Direct prompt for automated review (no @claude mention needed)
direct_prompt: |
Please review this pull request and provide feedback on:
- Code quality and best practices
- Potential bugs or issues
- Performance considerations
- Security concerns
- Test coverage
Be constructive and helpful in your feedback.
# Optional: Use sticky comments to make Claude reuse the same comment on subsequent pushes to the same PR
# use_sticky_comment: true
# Optional: Customize review based on file types
# direct_prompt: |
# Review this PR focusing on:
# - For TypeScript files: Type safety and proper interface usage
# - For API endpoints: Security, input validation, and error handling
# - For React components: Performance, accessibility, and best practices
# - For tests: Coverage, edge cases, and test quality
# Optional: Different prompts for different authors
# direct_prompt: |
# ${{ github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' &&
# 'Welcome! Please review this PR from a first-time contributor. Be encouraging and provide detailed explanations for any suggestions.' ||
# 'Please provide a thorough code review focusing on our coding standards and best practices.' }}
# Optional: Add specific tools for running tests or linting
# allowed_tools: "Bash(npm run test),Bash(npm run lint),Bash(npm run typecheck)"
# Optional: Skip review for certain conditions
# if: |
# !contains(github.event.pull_request.title, '[skip-review]') &&
# !contains(github.event.pull_request.title, '[WIP]')

64
.github/workflows/claude.yml vendored Normal file
View File

@@ -0,0 +1,64 @@
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]
jobs:
claude:
if: |
(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: read
pull-requests: read
issues: read
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@beta
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# This is an optional setting that allows Claude to read CI results on PRs
additional_permissions: |
actions: read
# Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4.1)
# model: "claude-opus-4-1-20250805"
# Optional: Customize the trigger phrase (default: @claude)
# trigger_phrase: "/claude"
# Optional: Trigger when specific user is assigned to an issue
# assignee_trigger: "claude-bot"
# Optional: Allow Claude to run specific commands
# allowed_tools: "Bash(npm install),Bash(npm run build),Bash(npm run test:*),Bash(npm run lint:*)"
# Optional: Add custom instructions for Claude to customize its behavior for your project
# custom_instructions: |
# Follow our coding standards
# Ensure all new code has tests
# Use TypeScript for new files
# Optional: Custom environment variables for Claude
# claude_env: |
# NODE_ENV: test

193
README.md
View File

@@ -1,19 +1,18 @@
# @xtr-dev/payload-automation
[![npm version](https://badge.fury.io/js/@xtr-dev%2Fpayload-automation.svg)](https://www.npmjs.com/package/@xtr-dev/payload-automation)
A workflow automation plugin for PayloadCMS 3.x. Run steps in workflows triggered by document changes or webhooks.
A comprehensive workflow automation plugin for PayloadCMS 3.x that enables visual workflow building, execution tracking, and parallel processing.
⚠️ **Pre-release Warning**: This package is currently in active development (v0.0.x). Breaking changes may occur before v1.0.0. Not recommended for production use.
## Features
- 🔄 Visual workflow builder in PayloadCMS admin
-Run workflows when documents are created/updated/deleted
- 🎯 Trigger workflows via webhooks
- 📊 Track workflow execution history
- 🔧 HTTP requests, document operations, email sending
- 🔗 Use data from previous steps in templates
- 🔄 **Visual Workflow Builder** - Create complex workflows with drag-and-drop interface
-**Parallel Execution** - Smart dependency resolution for optimal performance
- 🎯 **Multiple Triggers** - Collection hooks, webhooks, manual execution
- **Scheduled Workflows** - Use webhook triggers with external cron services
- 📊 **Execution Tracking** - Complete history and monitoring of workflow runs
- 🔧 **Extensible Steps** - HTTP requests, document CRUD, email notifications
- 🔧 **Handlebars Templates** - Dynamic data interpolation with automatic type conversion
## Installation
@@ -48,25 +47,94 @@ export default buildConfig({
})
```
## Imports
## Import Structure
The plugin uses separate exports to avoid bundling server-side code in client bundles:
```typescript
// Server plugin
// Server-side plugin and functions
import { workflowsPlugin } from '@xtr-dev/payload-automation/server'
// Client components
// Client-side components
import { StatusCell, ErrorDisplay } from '@xtr-dev/payload-automation/client'
// Types
// Helper utilities
import { /* helpers */ } from '@xtr-dev/payload-automation/helpers'
// Types only (safe for both server and client)
import type { WorkflowsPluginConfig } from '@xtr-dev/payload-automation'
```
## Step Types
### HTTP Request
Call external APIs. Supports GET, POST, PUT, DELETE, PATCH. Uses Bearer tokens, API keys, or basic auth.
Make external API calls with comprehensive error handling and retry logic.
HTTP steps succeed even with 4xx/5xx status codes. Only network errors (timeouts, DNS failures) cause step failure. Check `{{steps.stepName.output.status}}` for error handling.
**Key Features:**
- Support for GET, POST, PUT, DELETE, PATCH methods
- Authentication: Bearer token, Basic auth, API key headers
- Configurable timeouts and retry logic
- Handlebars templates for dynamic URLs and request bodies
**Error Handling:**
HTTP Request steps use a **response-based success model** rather than status-code-based failures:
-**Successful completion**: All HTTP requests that receive a response (including 4xx/5xx status codes) are marked as "succeeded"
-**Failed execution**: Only network errors, timeouts, DNS failures, and connection issues cause step failure
- 📊 **Error information preserved**: HTTP error status codes (404, 500, etc.) are captured in the step output for workflow conditional logic
**Example workflow logic:**
```typescript
// Step outputs for a 404 response:
{
"status": 404,
"statusText": "Not Found",
"body": "Resource not found",
"headers": {...},
"duration": 1200
}
// Use in workflow conditions:
// "{{steps.apiRequest.output.status}} >= 400" to handle errors
```
This design allows workflows to handle HTTP errors gracefully rather than failing completely, enabling robust error handling and retry logic.
**Enhanced Error Tracking:**
For network failures (timeouts, DNS errors, connection failures), the plugin provides detailed error information through an independent storage system that bypasses PayloadCMS's output limitations:
```typescript
// Timeout error details preserved in workflow context:
{
"steps": {
"httpStep": {
"state": "failed",
"error": "Task handler returned a failed state",
"errorDetails": {
"errorType": "timeout",
"duration": 2006,
"attempts": 1,
"finalError": "Request timeout after 2000ms",
"context": {
"url": "https://api.example.com/data",
"method": "GET",
"timeout": 2000
}
},
"executionInfo": {
"completed": true,
"success": false,
"executedAt": "2025-09-04T15:16:10.000Z",
"duration": 2006
}
}
}
}
// Access in workflow conditions:
// "{{steps.httpStep.errorDetails.errorType}} == 'timeout'"
// "{{steps.httpStep.errorDetails.duration}} > 5000"
```
### Document Operations
- **Create Document** - Create PayloadCMS documents
@@ -77,17 +145,38 @@ HTTP steps succeed even with 4xx/5xx status codes. Only network errors (timeouts
### Communication
- **Send Email** - Send notifications via PayloadCMS email
## Templates
## Data Resolution
Use `{{}}` to insert data:
Use Handlebars templates to access workflow data:
- `{{trigger.doc.id}}` - Data from the document that triggered the workflow
- `{{steps.stepName.output}}` - Data from previous steps
- `{{trigger.doc.id}}` - Access trigger document
- `{{steps.stepName.output}}` - Use previous step outputs
- `{{context}}` - Access workflow context
### Template Examples
Example:
```json
{
"url": "https://api.example.com/posts/{{steps.createPost.output.id}}",
"message": "Post {{trigger.doc.title}} was updated by {{trigger.req.user.email}}",
"timeout": "{{steps.configStep.output.timeoutMs}}"
}
```
### Automatic Type Conversion
Handlebars templates automatically convert string results to appropriate types based on field names:
- **Numbers**: `timeout`, `retries`, `delay`, `port`, `count`, etc. → converted to numbers
- **Booleans**: `enabled`, `active`, `success`, `complete`, etc. → converted to booleans
- **Numeric strings**: `"5000"``5000`, `"3.14"``3.14`
### Conditions
Conditions support Handlebars templates with comparison operators:
```json
{
"condition": "{{trigger.doc.status}} == 'published'"
}
```
@@ -98,26 +187,72 @@ Example:
- Node.js ^18.20.2 || >=20.9.0
- pnpm ^9 || ^10
## Logging
## Environment Variables
Set `PAYLOAD_AUTOMATION_LOG_LEVEL` to control logs:
- `silent`, `error`, `warn` (default), `info`, `debug`, `trace`
Control plugin logging with these environment variables:
### `PAYLOAD_AUTOMATION_LOG_LEVEL`
Controls both configuration-time and runtime logging.
- **Values**: `silent`, `error`, `warn`, `info`, `debug`, `trace`
- **Default**: `warn`
- **Example**: `PAYLOAD_AUTOMATION_LOG_LEVEL=debug`
### `PAYLOAD_AUTOMATION_CONFIG_LOG_LEVEL` (optional)
Override log level specifically for configuration-time logs (plugin setup).
- **Values**: Same as above
- **Default**: Falls back to `PAYLOAD_AUTOMATION_LOG_LEVEL` or `warn`
- **Example**: `PAYLOAD_AUTOMATION_CONFIG_LOG_LEVEL=silent`
### Production Usage
For production, keep the default (`warn`) or use `error` or `silent`:
```bash
PAYLOAD_AUTOMATION_LOG_LEVEL=error npm start
```
### Development Usage
For debugging, use `debug` or `info`:
```bash
PAYLOAD_AUTOMATION_LOG_LEVEL=debug npm run dev
```
## Scheduled Workflows
Use webhook triggers with external cron services:
For scheduled workflows, use **webhook triggers** with external cron services instead of built-in cron triggers:
```bash
# Call workflow webhook from cron
curl -X POST https://your-app.com/api/workflows-webhook/daily-report
### GitHub Actions (Free)
```yaml
# .github/workflows/daily-report.yml
on:
schedule:
- cron: '0 9 * * *' # Daily at 9 AM UTC
jobs:
trigger-workflow:
runs-on: ubuntu-latest
steps:
- run: curl -X POST https://your-app.com/api/workflows-webhook/daily-report
```
Built-in cron triggers were removed in v0.0.37+.
### Vercel Cron (Serverless)
```js
// api/cron/daily.js
export default async function handler(req, res) {
await fetch('https://your-app.com/api/workflows-webhook/daily-report', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ source: 'vercel-cron' })
});
res.status(200).json({ success: true });
}
```
**Benefits**: Better reliability, proper process isolation, easier debugging, and leverages existing infrastructure.
**Note**: Built-in cron triggers have been removed in v0.0.37+ to focus on webhook-based scheduling which provides better reliability and debugging capabilities.
## Documentation
Full documentation coming soon. For now, explore the development environment in the repository for examples and patterns.
## License
MIT
MIT