diff --git a/README.md b/README.md index fb97391..dda440b 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,70 @@ # Bitcomplete GitHub Actions -The automation behind Claude Code plugin marketplaces. We use these workflows ourselves, and now you can too. +Reusable GitHub Actions workflows for Claude Code development and Platform Engineering. We use these workflows ourselves, and now you can too. -## What This Does +## Actions -Plugin marketplaces shouldn't require babysitting. These workflows handle the boring stuff: +### Marketplace Automation -- **Auto-discovery** - Push a plugin, it gets registered. No manual JSON editing. -- **Validation** - Every PR gets checked for proper structure and naming. -- **Sync** - marketplace.json stays current automatically. +Automates Claude Code plugin marketplace management through auto-discovery, validation, and synchronization. -## Why We Built This +**Features:** +- Auto-discovery of plugins and components +- Structure and naming validation +- Automatic marketplace.json generation +- PR-based workflow with optional auto-merge -| The old way | With these actions | -|-------------|-------------------| -| Edit JSON by hand | Auto-discovery on push | -| Inconsistent naming | Standards enforced | -| Stale marketplace files | Always in sync | -| "It worked on my machine" | Validated before merge | +[View marketplace action documentation →](marketplace/README.md) -We got tired of the manual work. You shouldn't have to deal with it either. +## Basic Marketplace Publish Workflow + +When you push changes to a marketplace repository, the workflow automatically discovers, validates, and updates your marketplace.json: + +```mermaid +graph LR + A[Push to main] --> B[Discover] + B --> C[Validate] + C --> D[Generate] + D --> E[Create PR] + E --> F[Auto-merge] + + B -->|Finds| B1[Plugins] + B -->|Finds| B2[Commands] + B -->|Finds| B3[Skills] + + C -->|Checks| C1[Structure] + C -->|Checks| C2[Naming] + C -->|Checks| C3[Metadata] + + D -->|Updates| D1[marketplace.json] + D -->|Updates| D2[Component files] +``` + +**How it works:** + +1. **Discover** - Scans your repository for plugins, commands, skills, and other components based on your configuration +2. **Validate** - Checks that all components follow naming conventions, have required metadata, and match your validation rules +3. **Generate** - Creates or updates marketplace.json with all discovered components +4. **Create PR** - Opens a pull request with the changes for review +5. **Auto-merge** - Optionally merges the PR automatically if validation passes + +This happens automatically on every push to your main branch. No manual JSON editing required. ## Quick Start -Add this to your marketplace's workflow: +### Using Marketplace Automation + +Add this to `.github/workflows/marketplace.yml` in your marketplace repository: ```yaml +name: Update Marketplace + +on: + push: + branches: [main] + pull_request: + branches: [main] + jobs: update: uses: bitcomplete/bc-github-actions/.github/workflows/marketplace.yml@v1 @@ -35,26 +74,24 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} ``` -Or use individual actions: +Or use individual actions in your own workflow: ```yaml - uses: bitcomplete/bc-github-actions/marketplace/discover@v1 + with: + config-path: .claude-plugin/generator.config.toml + - uses: bitcomplete/bc-github-actions/marketplace/validate@v1 + with: + config-path: .claude-plugin/generator.config.toml + - uses: bitcomplete/bc-github-actions/marketplace/generate@v1 + with: + config-path: .claude-plugin/generator.config.toml + github-token: ${{ secrets.GITHUB_TOKEN }} + auto-merge: true ``` -See [docs/USAGE.md](docs/USAGE.md) for configuration options. - -## Already Using a Bitcomplete Marketplace? - -You're set. These workflows run automatically when you merge changes. -No action needed on your part—just keep shipping plugins. - -## Documentation - -- [Usage Guide](docs/USAGE.md) - Configuration and usage examples -- [Customization](docs/CUSTOMIZATION.md) - Advanced configuration options - ## Versioning We use semantic versioning with floating major tags: diff --git a/marketplace/README.md b/marketplace/README.md new file mode 100644 index 0000000..5ffccb6 --- /dev/null +++ b/marketplace/README.md @@ -0,0 +1,339 @@ +# Marketplace Automation + +Automates Claude Code plugin marketplace management through auto-discovery, validation, and synchronization. + +## Overview + +The marketplace action provides three composable actions that work together to manage your Claude Code plugin marketplace: + +1. **discover** - Finds plugins, commands, agents, skills, hooks, and MCP servers +2. **validate** - Validates component structure, naming, and metadata +3. **generate** - Creates marketplace.json and plugin.json files, opens PR with auto-merge + +## Quick Start + +### Using the Reusable Workflow (Recommended) + +Add `.github/workflows/marketplace.yml` to your marketplace repository: + +```yaml +name: Update Marketplace + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + update: + uses: bitcomplete/bc-github-actions/.github/workflows/marketplace.yml@v1 + with: + config-path: .claude-plugin/generator.config.toml + secrets: + token: ${{ secrets.GITHUB_TOKEN }} +``` + +### Using Individual Actions + +For custom workflows, use the actions individually: + +```yaml +name: Custom Marketplace Workflow + +on: + push: + branches: [main] + +jobs: + marketplace: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Discover components + id: discover + uses: bitcomplete/bc-github-actions/marketplace/discover@v1 + with: + config-path: .claude-plugin/generator.config.toml + + - name: Validate components + uses: bitcomplete/bc-github-actions/marketplace/validate@v1 + with: + config-path: .claude-plugin/generator.config.toml + fail-on-error: true + + - name: Generate marketplace files + uses: bitcomplete/bc-github-actions/marketplace/generate@v1 + with: + config-path: .claude-plugin/generator.config.toml + github-token: ${{ secrets.GITHUB_TOKEN }} + auto-merge: true +``` + +## Actions Reference + +### discover + +Scans your repository for Claude Code components based on your configuration file. + +**Inputs:** +- `config-path` (optional) - Path to generator.config.toml (default: `.claude-plugin/generator.config.toml`) + +**Outputs:** +- `plugins` - JSON array of discovered plugins +- `components` - JSON object of all discovered components (commands, skills, agents, etc.) + +**Example:** +```yaml +- uses: bitcomplete/bc-github-actions/marketplace/discover@v1 + id: discover + with: + config-path: .claude-plugin/generator.config.toml + +- name: Show discovered plugins + run: echo '${{ steps.discover.outputs.plugins }}' +``` + +### validate + +Validates discovered components against marketplace standards defined in your configuration. + +**Inputs:** +- `config-path` (optional) - Path to generator.config.toml (default: `.claude-plugin/generator.config.toml`) +- `fail-on-error` (optional) - Exit with error if validation fails (default: `true`) + +**Outputs:** +- `valid` - Boolean indicating if all components are valid +- `errors` - JSON array of validation errors (if any) + +**Validation checks:** +- Component naming follows configured pattern (kebab-case, snake_case, camelCase) +- Required metadata fields are present +- No reserved words in component names +- Plugin structure matches expected hierarchy + +**Example:** +```yaml +- uses: bitcomplete/bc-github-actions/marketplace/validate@v1 + id: validate + with: + config-path: .claude-plugin/generator.config.toml + fail-on-error: true + +- name: Check validation result + if: steps.validate.outputs.valid == 'false' + run: | + echo "Validation errors found:" + echo '${{ steps.validate.outputs.errors }}' +``` + +### generate + +Generates marketplace.json and plugin.json files, then creates a pull request with the changes. + +**Inputs:** +- `config-path` (optional) - Path to generator.config.toml (default: `.claude-plugin/generator.config.toml`) +- `github-token` (required) - GitHub token for creating PRs +- `auto-merge` (optional) - Enable auto-merge for the PR (default: `true`) +- `dry-run` (optional) - Preview changes without committing (default: `false`) + +**Outputs:** +- `pr-number` - Pull request number if created +- `pr-url` - Pull request URL if created + +**Generated files:** +- `.claude-plugin/marketplace.json` - Marketplace manifest with all plugins and components +- `category/plugin-name/.claude-plugin/plugin.json` - Individual plugin metadata + +**Example:** +```yaml +- uses: bitcomplete/bc-github-actions/marketplace/generate@v1 + id: generate + with: + config-path: .claude-plugin/generator.config.toml + github-token: ${{ secrets.GITHUB_TOKEN }} + auto-merge: true + +- name: Show PR details + if: steps.generate.outputs.pr-number != '' + run: | + echo "PR created: ${{ steps.generate.outputs.pr-url }}" + echo "PR number: ${{ steps.generate.outputs.pr-number }}" +``` + +## Configuration + +The marketplace actions are configured via a TOML file at `.claude-plugin/generator.config.toml`: + +```toml +# Naming pattern for components +naming_pattern = "^[a-z0-9]+(-[a-z0-9]+)*$" # kebab-case + +# Reserved words that cannot appear in component names +reserved_words = ["anthropic", "claude"] + +# Plugin discovery paths (glob patterns) +plugin_categories = ["code/**", "analysis/**", "communication/**"] + +# Component types to discover +[discovery] +plugins = true +commands = true +skills = true +agents = true +hooks = true +mcp_servers = true + +# Validation rules +[validation] +require_description = true +require_version = true +min_description_length = 10 +max_description_length = 200 +``` + +## Repository Structure + +The marketplace action expects this structure: + +``` +your-marketplace/ +├── .claude-plugin/ +│ ├── marketplace.json # Generated automatically +│ └── generator.config.toml # Your configuration +├── .github/ +│ └── workflows/ +│ └── marketplace.yml # Workflow file +├── code/ # Category directory +│ └── my-plugin/ # Plugin directory +│ ├── .claude-plugin/ +│ │ └── plugin.json # Generated automatically +│ ├── commands/ +│ │ └── my-command.md +│ ├── skills/ +│ │ └── my-skill.md +│ └── agents/ +│ └── my-agent.md +└── analysis/ # Another category + └── another-plugin/ + └── ... +``` + +## Workflow Details + +### Discovery Process + +The discover action scans your repository based on the plugin_categories patterns in your config: + +1. Finds all directories matching the two-level pattern: `category/plugin-name/` +2. Scans each plugin directory for: + - Commands in `commands/**/*.md` + - Skills in `skills/**/*.md` + - Agents in `agents/**/*.md` + - Hooks in `hooks/hooks.json` + - MCP servers in `.mcp.json` +3. Extracts metadata from YAML frontmatter in markdown files +4. Outputs discovered components as JSON + +### Validation Process + +The validate action checks each component against your configuration rules: + +- **Naming**: Matches configured pattern (kebab-case, snake_case, camelCase) +- **Reserved words**: No component names contain reserved words +- **Metadata**: Required fields are present (name, description, version) +- **Structure**: Plugin directories follow expected hierarchy +- **Constraints**: Description length within min/max bounds + +Validation errors are reported with file paths and specific issues. + +### Generation Process + +The generate action creates or updates marketplace files: + +1. Generates `.claude-plugin/marketplace.json` with all plugins and their components +2. Generates individual `plugin.json` files for each plugin +3. Creates a pull request with changes +4. If `auto-merge: true`, enables auto-merge on the PR +5. PR auto-merges when CI checks pass + +## Troubleshooting + +### No components discovered + +Check that: +- Your `generator.config.toml` `plugin_categories` patterns match your directory structure +- Plugin directories follow the two-level pattern: `category/plugin-name/` +- Component files have proper YAML frontmatter + +### Validation failures + +Common issues: +- Component names don't match the configured `naming_pattern` +- Component names contain `reserved_words` +- Missing required metadata fields (name, description, version) +- Description too short or too long + +### PR not created + +Possible causes: +- No changes detected (marketplace.json already up to date) +- GitHub token lacks `contents: write` and `pull-requests: write` permissions +- Branch protection rules blocking automated PRs + +### Auto-merge not working + +Check that: +- Repository settings allow auto-merge +- Branch protection rules don't require additional approvals +- All required status checks pass +- GitHub token has sufficient permissions + +## Advanced Usage + +### Dry Run + +Preview changes without creating a PR: + +```yaml +- uses: bitcomplete/bc-github-actions/marketplace/generate@v1 + with: + config-path: .claude-plugin/generator.config.toml + github-token: ${{ secrets.GITHUB_TOKEN }} + dry-run: true +``` + +### Manual Merge + +Disable auto-merge to review changes before merging: + +```yaml +- uses: bitcomplete/bc-github-actions/marketplace/generate@v1 + with: + config-path: .claude-plugin/generator.config.toml + github-token: ${{ secrets.GITHUB_TOKEN }} + auto-merge: false +``` + +### Custom Validation + +Use validation output to implement custom logic: + +```yaml +- uses: bitcomplete/bc-github-actions/marketplace/validate@v1 + id: validate + with: + fail-on-error: false + +- name: Custom validation handling + if: steps.validate.outputs.valid == 'false' + run: | + # Send notification, post comment, etc. + echo "Validation failed with errors:" + echo '${{ steps.validate.outputs.errors }}' +``` + +## Examples + +See the [main README](../README.md) for complete workflow examples and diagrams.