name: automating-workflow-name description: Use this skill when automating [workflow type], setting up CI/CD pipelines, or creating repeatable processes. This includes [specific automation scenarios]. Keywords: automate, workflow, pipeline, [domain-specific terms].
[Workflow] Automation
Automate [workflow] to reduce manual work and ensure consistency.
Automation Scope
| Task | Automated? | Method |
|---|---|---|
| [Task 1] | Yes | CLI/Script |
| [Task 2] | Yes | Hook |
| [Task 3] | Partial | Requires approval |
Prerequisites
Ensure these tools are available:
# Check required tools
which git gh node npm
# Install if missing
npm install -g required-package
Automation Workflow
1. Trigger Detection
Identify when automation should run:
Hook-based (automatic):
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [{
"type": "command",
"command": "~/.claude/hooks/auto-workflow.js"
}]
}
]
}
}
Command-based (manual trigger):
# Run automation script
node ~/.claude/scripts/run-workflow.js
2. Validation
Before proceeding, validate prerequisites:
#!/usr/bin/env node
import { existsSync } from 'fs';
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
async function validate() {
const checks = [
{ name: 'Git repo', test: () => existsSync('.git') },
{ name: 'Node modules', test: () => existsSync('node_modules') },
{ name: 'Clean working tree', test: async () => {
const { stdout } = await execAsync('git status --porcelain');
return stdout.trim() === '';
}},
];
for (const check of checks) {
const passed = typeof check.test === 'function'
? await check.test()
: check.test;
console.log(`${passed ? '✓' : '✗'} ${check.name}`);
if (!passed) process.exit(1);
}
}
validate();
3. Execution
Run the automated steps:
#!/usr/bin/env node
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
async function runWorkflow() {
const steps = [
{ name: 'Install dependencies', cmd: 'npm install' },
{ name: 'Run tests', cmd: 'npm test' },
{ name: 'Build', cmd: 'npm run build' },
{ name: 'Lint', cmd: 'npm run lint' },
];
for (const step of steps) {
console.log(`\n→ ${step.name}...`);
try {
const { stdout, stderr } = await execAsync(step.cmd);
if (stdout) console.log(stdout);
console.log(`✓ ${step.name} complete`);
} catch (error) {
console.error(`✗ ${step.name} failed:`, error.message);
process.exit(1);
}
}
console.log('\n✓ Workflow complete!');
}
runWorkflow();
4. Notification/Reporting
Report results after completion:
#!/usr/bin/env node
import { writeFile } from 'fs/promises';
const report = {
timestamp: new Date().toISOString(),
status: 'success',
steps: [
{ name: 'Install', duration: '12s', status: 'pass' },
{ name: 'Test', duration: '45s', status: 'pass' },
{ name: 'Build', duration: '30s', status: 'pass' },
]
};
await writeFile('workflow-report.json', JSON.stringify(report, null, 2));
console.log('Report saved to workflow-report.json');
Hook Integration
Auto-Run on File Changes
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"hooks": [{
"type": "command",
"command": "npm run lint --fix",
"timeout": 30
}]
}
]
}
}
Pre-Commit Validation
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "~/.claude/hooks/pre-commit-check.js"
}]
}
]
}
}
Script: pre-commit-check.js
#!/usr/bin/env node
import { readFileSync } from 'fs';
const input = JSON.parse(readFileSync('/dev/stdin', 'utf-8'));
const command = input.tool_input?.command || '';
if (command.includes('git commit')) {
// Add validation context
console.log(JSON.stringify({
hookSpecificOutput: {
hookEventName: 'PreToolUse',
additionalContext: 'Pre-commit: Ensure tests pass and code is formatted.'
}
}));
}
Examples
Example 1: Automated Testing Workflow
User Query: "Run tests automatically when I edit test files"
Hook Configuration:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [{
"type": "command",
"command": "~/.claude/hooks/auto-test.js"
}]
}
]
}
}
Script: auto-test.js
#!/usr/bin/env node
import { readFileSync } from 'fs';
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
const input = JSON.parse(readFileSync('/dev/stdin', 'utf-8'));
const filePath = input.tool_input?.file_path || '';
// Only run tests for test files or source files
if (filePath.includes('.test.') || filePath.includes('.spec.') ||
filePath.match(/src\/.*\.(js|ts)$/)) {
try {
await execAsync('npm test');
console.log(JSON.stringify({
hookSpecificOutput: {
hookEventName: 'PostToolUse',
additionalContext: '✓ Tests passed'
}
}));
} catch (error) {
console.log(JSON.stringify({
hookSpecificOutput: {
hookEventName: 'PostToolUse',
additionalContext: '✗ Tests failed - review output'
}
}));
}
}
Example 2: Deployment Pipeline
User Query: "Create an automated deployment workflow"
Script: deploy.js
#!/usr/bin/env node
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
async function deploy(environment = 'staging') {
console.log(`Deploying to ${environment}...`);
const steps = [
{ name: 'Validate', cmd: 'npm run validate' },
{ name: 'Test', cmd: 'npm test' },
{ name: 'Build', cmd: `npm run build -- --env ${environment}` },
{ name: 'Deploy', cmd: `npm run deploy:${environment}` },
];
for (const step of steps) {
console.log(`\n→ ${step.name}...`);
const { stdout } = await execAsync(step.cmd);
console.log(stdout);
}
console.log(`\n✓ Deployed to ${environment}!`);
}
const env = process.argv[2] || 'staging';
deploy(env).catch(err => {
console.error('Deploy failed:', err.message);
process.exit(1);
});
Best Practices
- Validate prerequisites before running
- Log each step clearly
- Handle errors gracefully with informative messages
- Use timeouts for long-running operations
- Save reports for debugging
- Test automation in safe environment first
Validation Checklist
- All prerequisites available
- Each step completes successfully
- Error handling works correctly
- Notifications/reports generated
- Rollback procedure defined (if applicable)
Troubleshooting
Issue: Script Timeout
Symptoms: Hook times out before completion
Solution: Increase timeout or run in background
{
"hooks": [{
"type": "command",
"command": "your-script.js",
"timeout": 300
}]
}
Issue: Permission Denied
Symptoms: Cannot execute script
Solution:
chmod +x ~/.claude/hooks/script.js