From 9951cf6803fbc2cf94d606ed786beeff91f32b7a Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 5 Nov 2025 17:27:10 +0000 Subject: [PATCH] Add MD Playbook Scanner GitHub Action - Create new composite action that scans directories for .md files - Automatically creates Devin playbooks via API for each file - Implements recursive directory scanning - Returns statistics (created, failed) and playbook IDs - Includes comprehensive documentation (README, DEPLOYMENT) - Adds test workflow for CI validation - Updates main README with new action documentation Related to: https://app.devin.ai/sessions/3bf44fc651184d1a86d621ea7e60ae61 Requested by: Sam Fertig (@samfert-codeium) Co-Authored-By: Sam Fertig --- .github/workflows/test-md-scanner.yml | 89 ++++ README.md | 40 +- md-playbook-scanner/DEPLOYMENT.md | 416 ++++++++++++++++++ md-playbook-scanner/README.md | 180 ++++++++ md-playbook-scanner/action.yml | 41 ++ .../examples/example-workflow.yml | 72 +++ .../scripts/scan-and-create.sh | 108 +++++ 7 files changed, 942 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/test-md-scanner.yml create mode 100644 md-playbook-scanner/DEPLOYMENT.md create mode 100644 md-playbook-scanner/README.md create mode 100644 md-playbook-scanner/action.yml create mode 100644 md-playbook-scanner/examples/example-workflow.yml create mode 100755 md-playbook-scanner/scripts/scan-and-create.sh diff --git a/.github/workflows/test-md-scanner.yml b/.github/workflows/test-md-scanner.yml new file mode 100644 index 0000000..3edddce --- /dev/null +++ b/.github/workflows/test-md-scanner.yml @@ -0,0 +1,89 @@ +name: Test MD Playbook Scanner + +on: + pull_request: + paths: + - 'md-playbook-scanner/**' + push: + branches: + - main + paths: + - 'md-playbook-scanner/**' + workflow_dispatch: + +jobs: + test-scanner: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Create test playbooks + run: | + mkdir -p test-playbooks/subfolder + cat > test-playbooks/deployment.md << 'EOF' + # Deployment Playbook + + Deploy the application to production with the following steps: + + 1. Run tests + 2. Build the application + 3. Deploy to production + 4. Verify deployment + EOF + + cat > test-playbooks/code-review.md << 'EOF' + # Code Review Playbook + + Review code changes with the following checklist: + + - Check code quality + - Verify tests are included + - Review security implications + - Check documentation + EOF + + cat > test-playbooks/subfolder/nested.md << 'EOF' + # Nested Test Playbook + + This is a playbook in a subdirectory to test recursive scanning. + EOF + + - name: Run MD Playbook Scanner + id: scanner + uses: ./md-playbook-scanner + with: + directory: './test-playbooks' + api-key: ${{ secrets.DEVIN_API_KEY }} + + - name: Verify outputs + run: | + echo "Playbooks created: ${{ steps.scanner.outputs.playbooks-created }}" + echo "Playbooks failed: ${{ steps.scanner.outputs.playbooks-failed }}" + echo "Playbook IDs: ${{ steps.scanner.outputs.playbook-ids }}" + + if [ "${{ steps.scanner.outputs.playbooks-created }}" -lt 3 ]; then + echo "❌ Error: Expected at least 3 playbooks created, got ${{ steps.scanner.outputs.playbooks-created }}" + exit 1 + fi + + if [ "${{ steps.scanner.outputs.playbooks-failed }}" -gt 0 ]; then + echo "❌ Error: Some playbooks failed to create: ${{ steps.scanner.outputs.playbooks-failed }}" + exit 1 + fi + + echo "✅ All tests passed!" + + - name: Test with non-existent directory (should fail) + id: test-invalid + continue-on-error: true + uses: ./md-playbook-scanner + with: + directory: './non-existent-directory' + api-key: ${{ secrets.DEVIN_API_KEY }} + + - name: Verify error handling + if: steps.test-invalid.outcome != 'failure' + run: | + echo "❌ Error: Action should have failed with non-existent directory" + exit 1 diff --git a/README.md b/README.md index 4b27438..8467b80 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A collection of GitHub Actions for integrating with the Devin API. ## Available Actions -### Devin API Action +### 1. Devin API Action A comprehensive GitHub Action for interacting with the Devin API to create and manage Devin sessions programmatically from your GitHub workflows. @@ -16,7 +16,7 @@ A comprehensive GitHub Action for interacting with the Devin API to create and m ```yaml - name: Create Devin Session - uses: samfert-codeium/DEVIN-GITHUB-ACTIONS/devin-action@main + uses: samfert-codeium/DEVIN-GITHUB-ACTIONS/devin-action@v1 id: create-session with: action: 'create-session' @@ -26,8 +26,7 @@ A comprehensive GitHub Action for interacting with the Devin API to create and m tags: 'bug-fix,automated' ``` -### Features - +**Features**: - **Session Management**: Create sessions, send messages, get status, list sessions - **File Operations**: Upload files to sessions - **Tagging**: Update session tags @@ -35,6 +34,39 @@ A comprehensive GitHub Action for interacting with the Devin API to create and m - **Knowledge Management**: Manage knowledge base entries - **Playbooks Management**: Create and manage playbooks +--- + +### 2. MD Playbook Scanner + +Automatically scans a directory for Markdown files and creates Devin playbooks from them. + +📂 **Location**: [`md-playbook-scanner/`](./md-playbook-scanner/) + +📖 **Documentation**: See [md-playbook-scanner/README.md](./md-playbook-scanner/README.md) for detailed usage instructions + +🚀 **Quick Start**: + +```yaml +- name: Scan and create playbooks + uses: samfert-codeium/DEVIN-GITHUB-ACTIONS/md-playbook-scanner@v1 + with: + directory: './playbooks' + api-key: ${{ secrets.DEVIN_API_KEY }} +``` + +**Features**: +- 📁 Recursively scans directories for `.md` files +- 📚 Automatically creates Devin playbooks using the Devin API +- 📊 Reports detailed statistics (created, failed) +- 🔍 Returns playbook IDs for downstream workflow steps +- ⚠️ Handles errors gracefully with detailed logging + +**Use Cases**: +- Automatically sync documentation to Devin playbooks +- Create playbooks from PR templates +- Build a playbook library from markdown docs +- Version control your Devin playbooks alongside your code + ### Prerequisites 1. Get a Devin API key from your [Devin settings page](https://app.devin.ai/settings) diff --git a/md-playbook-scanner/DEPLOYMENT.md b/md-playbook-scanner/DEPLOYMENT.md new file mode 100644 index 0000000..edc7531 --- /dev/null +++ b/md-playbook-scanner/DEPLOYMENT.md @@ -0,0 +1,416 @@ +# Deployment Guide - Devin Playbook Scanner + +This guide explains how to test, version, and deploy the Devin Playbook Scanner GitHub Action. + +## Table of Contents + +1. [Testing Locally](#testing-locally) +2. [Testing in CI](#testing-in-ci) +3. [Versioning Strategy](#versioning-strategy) +4. [Release Process](#release-process) +5. [Publishing to GitHub Marketplace](#publishing-to-github-marketplace) +6. [Rollback Procedures](#rollback-procedures) + +--- + +## Testing Locally + +### Prerequisites + +- [act](https://github.com/nektos/act) - Tool to run GitHub Actions locally +- Docker installed and running +- Valid Devin API key + +### Using `act` + +Create a test workflow file `.github/workflows/test-md-scanner-local.yml`: + +```yaml +name: Test MD Scanner Locally + +on: workflow_dispatch + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./md-playbook-scanner + with: + directory: './test-playbooks' + api-key: ${{ secrets.DEVIN_API_KEY }} +``` + +Create test markdown files: + +```bash +mkdir -p test-playbooks +echo "# Test Playbook 1\nThis is a test playbook." > test-playbooks/test1.md +echo "# Test Playbook 2\nAnother test playbook." > test-playbooks/test2.md +``` + +Run with `act`: + +```bash +# Run the workflow with act +act workflow_dispatch -s DEVIN_API_KEY=your_api_key_here +``` + +### Manual Testing + +You can also test the script directly: + +```bash +# Make the script executable +chmod +x md-playbook-scanner/scripts/scan-and-create.sh + +# Create test directory +mkdir -p test-playbooks +echo "# Deployment\nDeploy the application" > test-playbooks/deployment.md + +# Set environment variable for GITHUB_OUTPUT +export GITHUB_OUTPUT=$(mktemp) + +# Run the script +./md-playbook-scanner/scripts/scan-and-create.sh \ + "test-playbooks" \ + "your_devin_api_key" + +# Check outputs +cat $GITHUB_OUTPUT +``` + +--- + +## Testing in CI + +### Automated Testing Workflow + +Create `.github/workflows/test-md-scanner.yml`: + +```yaml +name: Test MD Playbook Scanner + +on: + pull_request: + paths: + - 'md-playbook-scanner/**' + push: + branches: + - main + paths: + - 'md-playbook-scanner/**' + workflow_dispatch: + +jobs: + test-scanner: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Create test playbooks + run: | + mkdir -p test-playbooks/subfolder + echo "# Test Deployment" > test-playbooks/deployment.md + echo "Deploy to production" >> test-playbooks/deployment.md + echo "# Test Review" > test-playbooks/code-review.md + echo "Review code changes" >> test-playbooks/code-review.md + echo "# Nested Test" > test-playbooks/subfolder/nested.md + echo "Nested playbook" >> test-playbooks/subfolder/nested.md + + - name: Run MD Playbook Scanner + id: scanner + uses: ./md-playbook-scanner + with: + directory: './test-playbooks' + api-key: ${{ secrets.DEVIN_API_KEY }} + + - name: Verify outputs + run: | + echo "Created: ${{ steps.scanner.outputs.playbooks-created }}" + echo "Failed: ${{ steps.scanner.outputs.playbooks-failed }}" + echo "IDs: ${{ steps.scanner.outputs.playbook-ids }}" + + # Verify at least 3 playbooks were created + if [ "${{ steps.scanner.outputs.playbooks-created }}" -lt 3 ]; then + echo "Error: Expected at least 3 playbooks created" + exit 1 + fi + + # Verify no failures + if [ "${{ steps.scanner.outputs.playbooks-failed }}" -gt 0 ]; then + echo "Error: Some playbooks failed to create" + exit 1 + fi + + - name: Test with non-existent directory + id: test-invalid + continue-on-error: true + uses: ./md-playbook-scanner + with: + directory: './non-existent-dir' + api-key: ${{ secrets.DEVIN_API_KEY }} + + - name: Verify error handling + if: steps.test-invalid.outcome != 'failure' + run: | + echo "Error: Action should have failed with non-existent directory" + exit 1 +``` + +### Required Secrets + +Add the following secret to your repository: +- `DEVIN_API_KEY`: Your Devin API key from [https://app.devin.ai/settings/api-keys](https://app.devin.ai/settings/api-keys) + +--- + +## Versioning Strategy + +This action follows [Semantic Versioning](https://semver.org/): + +- **MAJOR** version (v2.0.0): Breaking changes (incompatible API changes) +- **MINOR** version (v1.1.0): New features (backward-compatible) +- **PATCH** version (v1.0.1): Bug fixes (backward-compatible) + +### Version Tags + +We maintain multiple tag types: + +1. **Specific version tags**: `v1.0.0`, `v1.0.1`, `v1.1.0` + - Point to exact commits + - Never moved once created + - Recommended for production use requiring stability + +2. **Major version tags**: `v1`, `v2` + - Point to the latest stable release within that major version + - Updated with each new minor/patch release + - Recommended for users who want automatic updates + +3. **Branch references**: `@main` + - Points to the latest code + - May include unreleased features + - Not recommended for production + +--- + +## Release Process + +### 1. Prepare Release Branch + +```bash +# Ensure you're on main and up to date +git checkout main +git pull origin main + +# Create release branch +git checkout -b release/v1.0.0 +``` + +### 2. Update Documentation + +- Update version numbers in README.md examples +- Update CHANGELOG.md with release notes +- Verify all documentation is current + +### 3. Test Thoroughly + +```bash +# Run local tests +act workflow_dispatch -s DEVIN_API_KEY=your_key + +# Push and verify CI passes +git push origin release/v1.0.0 +``` + +### 4. Create and Push Tags + +```bash +# Create specific version tag +git tag -a v1.0.0 -m "Release v1.0.0: Initial release of MD Playbook Scanner" +git push origin v1.0.0 + +# Update or create major version tag +git tag -fa v1 -m "Update v1 to v1.0.0" +git push origin v1 --force +``` + +### 5. Merge to Main + +```bash +git checkout main +git merge release/v1.0.0 +git push origin main +``` + +### 6. Create GitHub Release + +1. Go to your repository on GitHub +2. Navigate to "Releases" → "Create a new release" +3. Select the tag (e.g., `v1.0.0`) +4. Fill in release details: + - **Title**: `v1.0.0 - Initial Release` + - **Description**: Include features, bug fixes, breaking changes +5. Mark as latest release +6. Publish release + +--- + +## Publishing to GitHub Marketplace + +### Prerequisites + +- Repository must be public +- Action must have proper metadata in `action.yml`: + - `name` + - `description` + - `author` + - `branding` (icon and color) + +### Steps + +1. Go to your repository on GitHub +2. Navigate to "Releases" +3. When creating a release, check "Publish this Action to the GitHub Marketplace" +4. Choose a category (e.g., "Continuous Integration") +5. Review and accept the terms +6. Publish the release + +### Marketplace Listing + +Once published, your action will appear at: +``` +https://github.com/marketplace/actions/devin-playbook-scanner +``` + +Users can then reference it as: +```yaml +uses: samfert-codeium/DEVIN-GITHUB-ACTIONS/md-playbook-scanner@v1 +``` + +--- + +## Rollback Procedures + +### Rolling Back a Version + +If a release has critical issues: + +#### 1. Immediate Rollback (Major Version Tag) + +```bash +# Rollback v1 tag to previous stable version (e.g., v1.0.1) +git tag -fa v1 v1.0.1 +git push origin v1 --force +``` + +This immediately affects users referencing `@v1`. + +#### 2. Create Hotfix Release + +```bash +# Create hotfix branch from previous stable version +git checkout -b hotfix/v1.0.3 v1.0.2 + +# Make fixes +# ... edit files ... + +# Commit and tag +git commit -am "Fix critical bug" +git tag -a v1.0.3 -m "Hotfix: Fix critical bug" +git push origin v1.0.3 + +# Update major version tag +git tag -fa v1 v1.0.3 +git push origin v1 --force + +# Merge back to main +git checkout main +git merge hotfix/v1.0.3 +git push origin main +``` + +#### 3. Deprecate Problematic Version + +In GitHub Release notes, mark the problematic version as deprecated: + +```markdown +## ⚠️ DEPRECATED - Do Not Use + +This release contains a critical bug and has been superseded by v1.0.3. +Please upgrade immediately. + +**Issue**: [Description of the problem] +**Fix**: Released in v1.0.3 +``` + +### Testing Rollback + +Before rolling back in production: + +```bash +# Test the previous version locally +git checkout v1.0.1 +act workflow_dispatch -s DEVIN_API_KEY=your_key + +# Verify it works as expected +``` + +--- + +## Troubleshooting + +### Common Issues + +1. **Script not executable** + - Solution: Ensure script has execute permissions before committing + ```bash + chmod +x md-playbook-scanner/scripts/scan-and-create.sh + git add md-playbook-scanner/scripts/scan-and-create.sh + ``` + +2. **API authentication failures** + - Check API key is valid + - Verify secret name matches in workflow (`DEVIN_API_KEY`) + - Test API key with curl manually + +3. **Path issues in workflows** + - Use relative paths from repository root + - Check `directory` input is accessible from workflow context + +4. **jq not found** + - Default GitHub runners include jq + - For self-hosted runners: `apt-get install jq` + +--- + +## Best Practices + +1. **Always test before releasing** + - Test locally with `act` + - Test in CI with pull requests + - Test specific version tags before promoting to major version + +2. **Use semantic versioning correctly** + - Breaking changes require major version bump + - New features require minor version bump + - Bug fixes require patch version bump + +3. **Document changes** + - Maintain CHANGELOG.md + - Write clear release notes + - Document breaking changes prominently + +4. **Communicate with users** + - Announce breaking changes in advance + - Provide migration guides + - Deprecate features before removing them + +--- + +## Support + +For deployment issues or questions: +- GitHub Issues: [Report an issue](https://github.com/samfert-codeium/DEVIN-GITHUB-ACTIONS/issues) +- Email: support@cognition.ai diff --git a/md-playbook-scanner/README.md b/md-playbook-scanner/README.md new file mode 100644 index 0000000..01c25f6 --- /dev/null +++ b/md-playbook-scanner/README.md @@ -0,0 +1,180 @@ +# Devin Playbook Scanner + +A GitHub Action that scans a directory for Markdown (`.md`) files and automatically creates Devin playbooks from them using the Devin API. + +## Features + +- 📁 Recursively scans directories for `.md` files +- 📚 Creates Devin playbooks automatically using the Devin API +- 📊 Reports summary statistics (created, failed) +- 🔍 Returns created playbook IDs for downstream workflow steps +- ⚠️ Handles errors gracefully with detailed logging + +## Usage + +### Basic Example + +```yaml +name: Create Playbooks from Markdown + +on: + push: + branches: [main] + paths: + - 'playbooks/**/*.md' + workflow_dispatch: + +jobs: + create-playbooks: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Scan and create playbooks + uses: samfert-codeium/DEVIN-GITHUB-ACTIONS/md-playbook-scanner@v1 + with: + directory: './playbooks' + api-key: ${{ secrets.DEVIN_API_KEY }} +``` + +### Advanced Example with Output Usage + +```yaml +name: Create and List Playbooks + +on: + workflow_dispatch: + inputs: + playbook-directory: + description: 'Directory to scan for playbooks' + required: true + default: './docs/playbooks' + +jobs: + create-playbooks: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Scan and create playbooks + id: scanner + uses: samfert-codeium/DEVIN-GITHUB-ACTIONS/md-playbook-scanner@v1 + with: + directory: ${{ github.event.inputs.playbook-directory }} + api-key: ${{ secrets.DEVIN_API_KEY }} + + - name: Display results + run: | + echo "Playbooks created: ${{ steps.scanner.outputs.playbooks-created }}" + echo "Playbooks failed: ${{ steps.scanner.outputs.playbooks-failed }}" + echo "Playbook IDs: ${{ steps.scanner.outputs.playbook-ids }}" + + - name: Notify on success + if: steps.scanner.outputs.playbooks-created > 0 + run: echo "Successfully created ${{ steps.scanner.outputs.playbooks-created }} playbooks!" + + - name: Fail on errors + if: steps.scanner.outputs.playbooks-failed > 0 + run: exit 1 +``` + +## Inputs + +| Input | Description | Required | Default | +|-------|-------------|----------|---------| +| `directory` | Directory path to scan for `.md` files (relative to repository root or absolute path) | Yes | - | +| `api-key` | Devin API key for authentication. Should be stored as a GitHub secret | Yes | - | + +## Outputs + +| Output | Description | Type | +|--------|-------------|------| +| `playbooks-created` | Number of playbooks successfully created | Number | +| `playbooks-failed` | Number of playbooks that failed to create | Number | +| `playbook-ids` | JSON array of created playbook IDs | JSON Array | + +## Prerequisites + +### 1. Devin API Key + +You need a Devin API key to use this action. To obtain one: + +1. Go to [Devin Settings](https://app.devin.ai/settings/api-keys) +2. Generate a new API key +3. Add it to your repository secrets as `DEVIN_API_KEY`: + - Go to your repository on GitHub + - Navigate to Settings → Secrets and variables → Actions + - Click "New repository secret" + - Name: `DEVIN_API_KEY` + - Value: Your Devin API key + +### 2. Markdown Files + +Organize your Markdown files in a directory structure. Each `.md` file will become a playbook: + +``` +playbooks/ +├── deployment.md +├── code-review.md +└── testing/ + ├── unit-tests.md + └── integration-tests.md +``` + +**Playbook Naming Convention:** +- The filename (without `.md` extension) becomes the playbook title +- Example: `deployment.md` → playbook title: "deployment" +- The file content becomes the playbook body/instructions + +## How It Works + +1. The action scans the specified directory recursively for all `.md` files +2. For each `.md` file found: + - Extracts the filename (without extension) as the playbook title + - Reads the file content as the playbook body + - Creates a new playbook via the Devin API +3. Reports statistics and returns created playbook IDs +4. Fails the workflow if any playbooks failed to create + +## Error Handling + +The action will: +- ✅ Continue processing all files even if some fail +- ✅ Log detailed error messages for failures +- ✅ Exit with non-zero code if any playbooks failed to create +- ✅ Report summary statistics at the end + +Common failure scenarios: +- Invalid API key (HTTP 401) +- Missing permissions (HTTP 403) +- Empty or invalid directory path +- Network issues connecting to Devin API +- Invalid file content + +## Limitations + +- Only `.md` files are processed (case-sensitive) +- Empty filenames or content may cause failures +- Requires valid Devin API key with playbook creation permissions +- API rate limits may apply for large numbers of files + +## Examples Directory + +See the [examples](./examples/) directory for complete workflow examples. + +## Related Actions + +- [devin-action](../devin-action/) - Full-featured Devin API client for sessions, secrets, knowledge, and playbooks + +## Support + +For issues or questions: +- GitHub Issues: [DEVIN-GITHUB-ACTIONS Repository](https://github.com/samfert-codeium/DEVIN-GITHUB-ACTIONS/issues) +- Devin API Documentation: [https://docs.devin.ai/api-reference/overview](https://docs.devin.ai/api-reference/overview) +- Email: support@cognition.ai + +## License + +See the main repository [LICENSE](../LICENSE) file. diff --git a/md-playbook-scanner/action.yml b/md-playbook-scanner/action.yml new file mode 100644 index 0000000..b075475 --- /dev/null +++ b/md-playbook-scanner/action.yml @@ -0,0 +1,41 @@ +name: 'Devin Playbook Scanner' +description: 'Scans a directory for Markdown files and creates Devin playbooks from them' +author: 'Sam Fertig (@samfert-codeium)' + +branding: + icon: 'book-open' + color: 'purple' + +inputs: + directory: + description: 'Directory path to scan for .md files (relative to repository root or absolute path)' + required: true + + api-key: + description: 'Devin API key for authentication. Should be stored as a secret (e.g., secrets.DEVIN_API_KEY)' + required: true + +outputs: + playbooks-created: + description: 'Number of playbooks successfully created' + value: ${{ steps.scan.outputs.playbooks-created }} + + playbooks-failed: + description: 'Number of playbooks that failed to create' + value: ${{ steps.scan.outputs.playbooks-failed }} + + playbook-ids: + description: 'JSON array of created playbook IDs' + value: ${{ steps.scan.outputs.playbook-ids }} + +runs: + using: 'composite' + steps: + - name: Scan and Create Playbooks + id: scan + shell: bash + run: | + chmod +x "${{ github.action_path }}/scripts/scan-and-create.sh" + "${{ github.action_path }}/scripts/scan-and-create.sh" \ + "${{ inputs.directory }}" \ + "${{ inputs.api-key }}" diff --git a/md-playbook-scanner/examples/example-workflow.yml b/md-playbook-scanner/examples/example-workflow.yml new file mode 100644 index 0000000..4195d90 --- /dev/null +++ b/md-playbook-scanner/examples/example-workflow.yml @@ -0,0 +1,72 @@ +name: Create Devin Playbooks from Markdown + +on: + # Trigger when markdown files in playbooks directory change + push: + branches: [main] + paths: + - 'playbooks/**/*.md' + + # Trigger on new releases + release: + types: [published] + + # Allow manual trigger + workflow_dispatch: + inputs: + directory: + description: 'Directory to scan for playbooks' + required: true + default: './playbooks' + dry-run: + description: 'Dry run (do not create playbooks)' + required: false + default: 'false' + +jobs: + create-playbooks: + name: Scan and Create Playbooks + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Scan and create playbooks + id: scanner + uses: samfert-codeium/DEVIN-GITHUB-ACTIONS/md-playbook-scanner@v1 + with: + directory: ${{ github.event.inputs.directory || './playbooks' }} + api-key: ${{ secrets.DEVIN_API_KEY }} + + - name: Display summary + run: | + echo "## Playbook Creation Summary" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- ✅ **Created**: ${{ steps.scanner.outputs.playbooks-created }}" >> $GITHUB_STEP_SUMMARY + echo "- ❌ **Failed**: ${{ steps.scanner.outputs.playbooks-failed }}" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + if [ "${{ steps.scanner.outputs.playbooks-created }}" -gt 0 ]; then + echo "### Created Playbook IDs" >> $GITHUB_STEP_SUMMARY + echo '```json' >> $GITHUB_STEP_SUMMARY + echo '${{ steps.scanner.outputs.playbook-ids }}' >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + fi + + - name: Notify on success + if: steps.scanner.outputs.playbooks-created > 0 && steps.scanner.outputs.playbooks-failed == 0 + run: | + echo "✅ Successfully created ${{ steps.scanner.outputs.playbooks-created }} playbooks!" + + - name: Notify on partial failure + if: steps.scanner.outputs.playbooks-created > 0 && steps.scanner.outputs.playbooks-failed > 0 + run: | + echo "⚠️ Created ${{ steps.scanner.outputs.playbooks-created }} playbooks, but ${{ steps.scanner.outputs.playbooks-failed }} failed" + exit 1 + + - name: Notify on complete failure + if: steps.scanner.outputs.playbooks-created == 0 && steps.scanner.outputs.playbooks-failed > 0 + run: | + echo "❌ Failed to create any playbooks. All ${{ steps.scanner.outputs.playbooks-failed }} attempts failed" + exit 1 diff --git a/md-playbook-scanner/scripts/scan-and-create.sh b/md-playbook-scanner/scripts/scan-and-create.sh new file mode 100755 index 0000000..4febc3b --- /dev/null +++ b/md-playbook-scanner/scripts/scan-and-create.sh @@ -0,0 +1,108 @@ +#!/bin/bash + +set -e + +DIRECTORY="$1" +API_KEY="$2" + +BASE_URL="https://api.devin.ai/v1" + +if [ -z "$DIRECTORY" ]; then + echo "Error: directory is required" + exit 1 +fi + +if [ -z "$API_KEY" ]; then + echo "Error: api-key is required" + exit 1 +fi + +if [ ! -d "$DIRECTORY" ]; then + echo "Error: Directory '$DIRECTORY' does not exist" + exit 1 +fi + +echo "Scanning directory: $DIRECTORY" + +playbooks_created=0 +playbooks_failed=0 +declare -a created_playbook_ids +declare -a failed_files + +while IFS= read -r -d '' file; do + echo "Processing: $file" + + filename=$(basename "$file" .md) + + if [ -z "$filename" ]; then + echo " Skipping: empty filename" + playbooks_failed=$((playbooks_failed + 1)) + failed_files+=("$file") + continue + fi + + content=$(cat "$file") + + if [ -z "$content" ]; then + echo " Warning: empty content in $file" + fi + + payload=$(jq -n \ + --arg title "$filename" \ + --arg body "$content" \ + '{title: $title, body: $body}') + + response=$(curl -s -w "\n%{http_code}" -X POST "${BASE_URL}/playbooks" \ + -H "Authorization: Bearer ${API_KEY}" \ + -H "Content-Type: application/json" \ + -d "$payload") + + http_code=$(echo "$response" | tail -n1) + response_body=$(echo "$response" | sed '$d') + + if [ "$http_code" -ge 200 ] && [ "$http_code" -lt 300 ]; then + playbook_id=$(echo "$response_body" | jq -r '.playbook_id // empty') + if [ -n "$playbook_id" ]; then + echo " ✓ Created playbook: $filename (ID: $playbook_id)" + playbooks_created=$((playbooks_created + 1)) + created_playbook_ids+=("$playbook_id") + else + echo " ✗ Failed to extract playbook_id from response" + playbooks_failed=$((playbooks_failed + 1)) + failed_files+=("$file") + fi + else + echo " ✗ Failed to create playbook (HTTP $http_code): $response_body" + playbooks_failed=$((playbooks_failed + 1)) + failed_files+=("$file") + fi + +done < <(find "$DIRECTORY" -type f -name "*.md" -print0) + +echo "" +echo "==========================================" +echo "Summary:" +echo " Total .md files found: $((playbooks_created + playbooks_failed))" +echo " Playbooks created: $playbooks_created" +echo " Failed: $playbooks_failed" +echo "==========================================" + +echo "playbooks-created=$playbooks_created" >> $GITHUB_OUTPUT +echo "playbooks-failed=$playbooks_failed" >> $GITHUB_OUTPUT + +if [ ${#created_playbook_ids[@]} -gt 0 ]; then + playbook_ids_json=$(printf '%s\n' "${created_playbook_ids[@]}" | jq -R . | jq -s .) + echo "playbook-ids<> $GITHUB_OUTPUT + echo "$playbook_ids_json" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT +fi + +if [ ${#failed_files[@]} -gt 0 ]; then + echo "" + echo "Failed files:" + printf ' - %s\n' "${failed_files[@]}" +fi + +if [ $playbooks_failed -gt 0 ]; then + exit 1 +fi