Hooks & Automation

Customize your workflow with pre-run and post-run hooks for automated testing, formatting, and deployment.

Hook Types

Pre-Run Hook

Executed before any git operations. Perfect for:

  • Code formatting and linting
  • Running tests
  • Build verification
  • Security scans
Location: .lfg/pre-run.sh

Post-Run Hook

Executed after successful completion. Ideal for:

  • Opening PR in browser
  • Sending notifications
  • Triggering deployments
  • Updating project management tools
Location: .lfg/post-run.sh

Pre-Run Hook Examples

Node.js/JavaScript Project

.lfg/pre-run.sh
#!/usr/bin/env bash
# Pre-run hook for Node.js projects

set -e  # Exit on any error

echo "🔍 Running pre-commit checks..."

# Format code with Prettier
echo "📝 Formatting code..."
npm run format || exit 1

# Lint code
echo "🔍 Linting code..."
npm run lint || exit 1

# Run tests
echo "🧪 Running tests..."
npm run test || exit 1

# Type checking (if using TypeScript)
if [ -f "tsconfig.json" ]; then
    echo "🔍 Type checking..."
    npm run type-check || exit 1
fi

echo "✅ All pre-commit checks passed!"
exit 0

Python Project

.lfg/pre-run.sh
#!/usr/bin/env bash
# Pre-run hook for Python projects

set -e

echo "🐍 Running Python pre-commit checks..."

# Format with Black
echo "📝 Formatting with Black..."
black . --check || {
    echo "❌ Code formatting issues found. Run 'black .' to fix."
    exit 1
}

# Sort imports with isort
echo "📦 Checking import sorting..."
isort . --check-only || {
    echo "❌ Import sorting issues found. Run 'isort .' to fix."
    exit 1
}

# Lint with flake8
echo "🔍 Linting with flake8..."
flake8 . || exit 1

# Type checking with mypy
echo "🔍 Type checking with mypy..."
mypy . || exit 1

# Run tests with pytest
echo "🧪 Running tests..."
pytest || exit 1

echo "✅ All Python checks passed!"
exit 0

Go Project

.lfg/pre-run.sh
#!/usr/bin/env bash
# Pre-run hook for Go projects

set -e

echo "🐹 Running Go pre-commit checks..."

# Format code
echo "📝 Formatting Go code..."
gofmt -l . | grep -q . && {
    echo "❌ Code formatting issues found. Run 'gofmt -w .' to fix."
    exit 1
}

# Vet code
echo "🔍 Vetting Go code..."
go vet ./... || exit 1

# Run golint if available
if command -v golint >/dev/null 2>&1; then
    echo "🔍 Linting Go code..."
    golint -set_exit_status ./... || exit 1
fi

# Build to check for compilation errors
echo "🔨 Building project..."
go build ./... || exit 1

# Run tests
echo "🧪 Running tests..."
go test ./... || exit 1

echo "✅ All Go checks passed!"
exit 0

Laravel/PHP Project

.lfg/pre-run.sh
#!/usr/bin/env bash
# Pre-run hook for Laravel/PHP projects

set -e

echo "🐘 Running PHP/Laravel pre-commit checks..."

# Format code with Laravel Pint
echo "📝 Formatting PHP code..."
./vendor/bin/pint --test || {
    echo "❌ Code formatting issues found. Run './vendor/bin/pint' to fix."
    exit 1
}

# Static analysis with PHPStan
if [ -f "phpstan.neon" ] || [ -f "phpstan.neon.dist" ]; then
    echo "🔍 Running PHPStan analysis..."
    ./vendor/bin/phpstan analyse || exit 1
fi

# Run tests
echo "🧪 Running PHPUnit tests..."
./vendor/bin/phpunit || exit 1

# Check for security vulnerabilities
if command -v composer >/dev/null 2>&1; then
    echo "🔒 Checking for security vulnerabilities..."
    composer audit || exit 1
fi

echo "✅ All PHP/Laravel checks passed!"
exit 0

Post-Run Hook Examples

Open PR in Browser

.lfg/post-run.sh
#!/usr/bin/env bash
# Post-run hook to open PR in browser

# PR_URL is provided by LFG when a PR is created
if [ -n "$PR_URL" ]; then
    echo "🌐 Opening PR in browser..."
    
    # macOS
    if command -v open >/dev/null 2>&1; then
        open "$PR_URL" >/dev/null 2>&1 || true
    # Linux
    elif command -v xdg-open >/dev/null 2>&1; then
        xdg-open "$PR_URL" >/dev/null 2>&1 || true
    # Windows (WSL)
    elif command -v cmd.exe >/dev/null 2>&1; then
        cmd.exe /c start "$PR_URL" >/dev/null 2>&1 || true
    fi
    
    echo "✅ PR opened in browser"
fi

exit 0

Slack Notification

.lfg/post-run.sh
#!/usr/bin/env bash
# Post-run hook for Slack notifications

# Load environment variables (including SLACK_WEBHOOK_URL)
if [ -f ".lfg/.env" ]; then
    source .lfg/.env
fi

# Only send notification if PR was created
if [ -n "$PR_URL" ] && [ -n "$SLACK_WEBHOOK_URL" ]; then
    BRANCH=$(git rev-parse --abbrev-ref HEAD)
    AUTHOR=$(git config user.name)
    REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner 2>/dev/null || echo "repository")
    
    # Get commit message
    COMMIT_MSG=$(git log -1 --pretty=format:"%s")
    
    # Send Slack notification
    curl -X POST -H 'Content-type: application/json' \
        --data "{
            \"text\": \"🚀 New PR created by $AUTHOR\",
            \"blocks\": [
                {
                    \"type\": \"section\",
                    \"text\": {
                        \"type\": \"mrkdwn\",
                        \"text\": \"*New Pull Request*\n*Repository:* $REPO\n*Branch:* \`$BRANCH\`\n*Author:* $AUTHOR\n*Commit:* $COMMIT_MSG\"
                    }
                },
                {
                    \"type\": \"actions\",
                    \"elements\": [
                        {
                            \"type\": \"button\",
                            \"text\": {
                                \"type\": \"plain_text\",
                                \"text\": \"View PR\"
                            },
                            \"url\": \"$PR_URL\"
                        }
                    ]
                }
            ]
        }" \
        "$SLACK_WEBHOOK_URL" >/dev/null 2>&1 || true
    
    echo "📢 Slack notification sent"
fi

exit 0

Deployment Trigger

.lfg/post-run.sh
#!/usr/bin/env bash
# Post-run hook for deployment triggers

BRANCH=$(git rev-parse --abbrev-ref HEAD)

# Trigger staging deployment for develop branch
if [ "$BRANCH" = "develop" ]; then
    echo "🚀 Triggering staging deployment..."
    
    # Example: GitHub Actions workflow dispatch
    if command -v gh >/dev/null 2>&1; then
        gh workflow run deploy-staging.yml \
            --field branch="$BRANCH" \
            --field environment="staging" >/dev/null 2>&1 || true
    fi
    
    echo "✅ Staging deployment triggered"
fi

# Trigger production deployment for main branch
if [ "$BRANCH" = "main" ]; then
    echo "🚀 Triggering production deployment..."
    
    # Example: Call deployment webhook
    if [ -n "$DEPLOY_WEBHOOK_URL" ]; then
        curl -X POST -H "Content-Type: application/json" \
            -d "{\"branch\": \"$BRANCH\", \"environment\": \"production\"}" \
            "$DEPLOY_WEBHOOK_URL" >/dev/null 2>&1 || true
    fi
    
    echo "✅ Production deployment triggered"
fi

exit 0

Project Management Integration

.lfg/post-run.sh
#!/usr/bin/env bash
# Post-run hook for project management integration

# Extract ticket number from branch name (e.g., PROJ-123-feature-name)
BRANCH=$(git rev-parse --abbrev-ref HEAD)
TICKET=$(echo "$BRANCH" | sed -nE 's/^([A-Z]+-[0-9]+).*$/\1/p')

if [ -n "$TICKET" ] && [ -n "$PR_URL" ]; then
    echo "🎫 Updating ticket $TICKET..."
    
    # Example: Update Jira ticket
    if [ -n "$JIRA_API_TOKEN" ] && [ -n "$JIRA_BASE_URL" ]; then
        COMMIT_MSG=$(git log -1 --pretty=format:"%s")
        
        # Add comment to Jira ticket
        curl -X POST \
            -H "Authorization: Bearer $JIRA_API_TOKEN" \
            -H "Content-Type: application/json" \
            -d "{
                \"body\": \"Pull request created: $PR_URL\n\nCommit: $COMMIT_MSG\"
            }" \
            "$JIRA_BASE_URL/rest/api/3/issue/$TICKET/comment" >/dev/null 2>&1 || true
        
        echo "✅ Jira ticket $TICKET updated"
    fi
    
    # Example: Update Linear issue
    if [ -n "$LINEAR_API_TOKEN" ]; then
        curl -X POST \
            -H "Authorization: $LINEAR_API_TOKEN" \
            -H "Content-Type: application/json" \
            -d "{
                \"query\": \"mutation { commentCreate(input: { issueId: \\\"$TICKET\\\", body: \\\"PR created: $PR_URL\\\" }) { success } }\"
            }" \
            "https://api.linear.app/graphql" >/dev/null 2>&1 || true
        
        echo "✅ Linear issue $TICKET updated"
    fi
fi

exit 0

Hook Configuration

Configuration Options

.lfg/config.yml
hooks:
  pre: .lfg/pre-run.sh      # Path to pre-run hook (relative to repo root)
  post: .lfg/post-run.sh    # Path to post-run hook (relative to repo root)

Hook Permissions

Make sure your hook scripts are executable:

Set Hook Permissions
$
chmod +x .lfg/pre-run.sh .lfg/post-run.sh
✓ Hook permissions set

Environment Variables

Store sensitive information in .lfg/.env:

.lfg/.env
# Slack integration
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...

# Jira integration
JIRA_API_TOKEN=your_jira_token
JIRA_BASE_URL=https://yourcompany.atlassian.net

# Linear integration
LINEAR_API_TOKEN=your_linear_token

# Deployment webhooks
DEPLOY_WEBHOOK_URL=https://deploy.yourcompany.com/webhook

Hook Best Practices

Exit Codes Matter

Pre-run hooks should exit with non-zero code to block commits on failure

Use 'set -e' and 'exit 1' for failures, 'exit 0' for success

Fast Feedback

Keep pre-run hooks fast to avoid slowing down the development workflow

Run quick checks first, skip slow tests in pre-hooks

Error Handling

Post-run hooks should be resilient and not fail the entire process

Use '|| true' for non-critical operations in post-hooks

Environment Detection

Check for required tools and environment variables before using them

Use 'command -v tool >/dev/null 2>&1' to check if tools exist

Logging

Provide clear feedback about what the hooks are doing

Use echo statements to show progress and results

Conditional Logic

Make hooks smart about when to run certain operations

Check branch names, file changes, or environment variables

Hook Troubleshooting

Problem: Hook script not executing

Solution: Check file permissions with 'ls -la .lfg/' and set executable with 'chmod +x .lfg/pre-run.sh .lfg/post-run.sh'

Problem: Pre-run hook blocking commits

Solution: Check the exit code of your hook script. Use 'bash -x .lfg/pre-run.sh' to debug step by step.

Problem: Environment variables not available

Solution: Source .lfg/.env in your hook script or check that variables are exported properly.

Problem: Hook script path not found

Solution: Verify the path in hooks.pre and hooks.post in config.yml. Paths are relative to repository root.

Problem: Post-run hook not receiving PR_URL

Solution: PR_URL is only available when --pr flag is used and PR creation succeeds. Check GitHub CLI authentication.

Problem: Hook script syntax errors

Solution: Test your hook scripts independently with 'bash .lfg/pre-run.sh' to check for syntax issues.