# Workflow Publishing Guide This guide explains how to publish your workflow to the Spec Kit workflow catalog, making it discoverable by `specify workflow search`. ## Table of Contents 1. [Prerequisites](#prerequisites) 2. [Prepare Your Workflow](#prepare-your-workflow) 3. [Submit to Catalog](#submit-to-catalog) 4. [Verification Process](#verification-process) 5. [Release Workflow](#release-workflow) 6. [Best Practices](#best-practices) --- ## Prerequisites Before publishing a workflow, ensure you have: 1. **Valid Workflow**: A working `workflow.yml` that passes `specify workflow run` validation 2. **Git Repository**: Workflow hosted on GitHub (or other public git hosting) 3. **Documentation**: README.md with description, inputs, and step graph 4. **License**: Open source license file (MIT, Apache 2.0, etc.) 5. **Versioning**: Semantic versioning in the `workflow.version` field 6. **Testing**: Workflow tested on real projects --- ## Prepare Your Workflow ### 1. Workflow Structure Host your workflow in a repository with this structure: ```text your-workflow/ ├── workflow.yml # Required: Workflow definition ├── README.md # Required: Documentation ├── LICENSE # Required: License file └── CHANGELOG.md # Recommended: Version history ``` ### 2. workflow.yml Validation Verify your definition is valid: ```yaml schema_version: "1.0" workflow: id: "your-workflow" # Unique lowercase-hyphenated ID name: "Your Workflow Name" # Human-readable name version: "1.0.0" # Semantic version author: "Your Name or Organization" description: "Brief description (one sentence)" integration: claude # Default integration (optional) model: "claude-sonnet-4-20250514" # Default model (optional) requires: speckit_version: ">=0.6.1" integrations: any: ["claude", "gemini"] # At least one required inputs: spec: type: string required: true prompt: "Describe what you want to build" scope: type: string default: "full" enum: ["full", "backend-only", "frontend-only"] steps: - id: specify command: speckit.specify input: args: "{{ inputs.spec }}" - id: review type: gate message: "Review the output." options: [approve, reject] on_reject: abort ``` **Validation Checklist**: - ✅ `id` is lowercase alphanumeric with hyphens (single-character IDs are allowed) - ✅ `version` follows semantic versioning (X.Y.Z) - ✅ `description` is concise - ✅ All step IDs are unique - ✅ Step types are valid: `command`, `prompt`, `shell`, `gate`, `if`, `switch`, `while`, `do-while`, `fan-out`, `fan-in` - ✅ Required fields present per step type (e.g., `condition` for `if`, `expression` for `switch`) - ✅ Input types are valid: `string`, `number`, `boolean` - ✅ Step IDs do not contain `:` (reserved for engine-generated nested IDs like `parentId:childId`) ### 3. Test Locally ```bash # Run with required inputs specify workflow run ./workflow.yml --input spec="Build a user authentication system with OAuth support" # Check validation specify workflow info ./workflow.yml # Resume after a gate pause specify workflow resume # Check run status specify workflow status ``` ### 4. Create GitHub Release Create a GitHub release for your workflow version: ```bash git tag v1.0.0 git push origin v1.0.0 ``` The raw YAML URL will be: ```text https://raw.githubusercontent.com/your-org/spec-kit-workflow-your-workflow/v1.0.0/workflow.yml ``` ### 5. Test Installation from URL ```bash specify workflow add your-workflow # (once published to catalog) ``` --- ## Submit to Catalog ### Understanding the Catalogs Spec Kit uses a dual-catalog system: - **`catalog.json`** — Official, verified workflows (install allowed by default) - **`catalog.community.json`** — Community-contributed workflows (discovery only by default) All community workflows should be submitted to `catalog.community.json`. ### 1. Fork the spec-kit Repository ```bash git clone https://github.com/YOUR-USERNAME/spec-kit.git cd spec-kit ``` ### 2. Add Workflow to Community Catalog Edit `workflows/catalog.community.json` and add your workflow. > **⚠️ Entries must be sorted alphabetically by workflow ID.** Insert your workflow in the correct position within the `"workflows"` object. ```json { "schema_version": "1.0", "updated_at": "2026-04-10T00:00:00Z", "catalog_url": "https://raw.githubusercontent.com/github/spec-kit/main/workflows/catalog.community.json", "workflows": { "your-workflow": { "id": "your-workflow", "name": "Your Workflow Name", "description": "Brief description of what your workflow automates", "author": "Your Name", "version": "1.0.0", "url": "https://raw.githubusercontent.com/your-org/spec-kit-workflow-your-workflow/v1.0.0/workflow.yml", "repository": "https://github.com/your-org/spec-kit-workflow-your-workflow", "license": "MIT", "requires": { "speckit_version": ">=0.15.0" }, "tags": [ "category", "automation" ], "created_at": "2026-04-10T00:00:00Z", "updated_at": "2026-04-10T00:00:00Z" } } } ``` ### 3. Submit Pull Request ```bash git checkout -b add-your-workflow git add workflows/catalog.community.json git commit -m "Add your-workflow to community catalog - Workflow ID: your-workflow - Version: 1.0.0 - Author: Your Name - Description: Brief description " git push origin add-your-workflow ``` **Pull Request Checklist**: ```markdown ## Workflow Submission **Workflow Name**: Your Workflow Name **Workflow ID**: your-workflow **Version**: 1.0.0 **Repository**: https://github.com/your-org/spec-kit-workflow-your-workflow ### Checklist - [ ] Valid workflow.yml (passes `specify workflow info`) - [ ] README.md with description, inputs, and step graph - [ ] LICENSE file included - [ ] GitHub release created with raw YAML URL - [ ] Workflow tested end-to-end with `specify workflow run` - [ ] All gate steps have clear review messages - [ ] Input prompts are descriptive - [ ] Added to workflows/catalog.community.json (alphabetical order) ``` --- ## Verification Process After submission, maintainers will review: 1. **Definition validation** — valid `workflow.yml`, correct schema 2. **Step correctness** — all step types used correctly, no dangling references 3. **Input design** — clear prompts, sensible defaults and enums 4. **Security** — no malicious shell commands, safe operations 5. **Documentation** — clear README explaining what the workflow does and when to use it Once verified, the workflow appears in `specify workflow search`. --- ## Release Workflow When releasing a new version: 1. Update `version` in `workflow.yml` 2. Update CHANGELOG.md 3. Tag and push: `git tag v1.1.0 && git push origin v1.1.0` 4. Submit PR to update `version` and `url` in `workflows/catalog.community.json` --- ## Best Practices ### Step Design - **Use gates at decision points** — place `gate` steps after each major output so users can review before proceeding - **Keep steps focused** — each step should do one thing; prefer more steps over complex single steps - **Provide clear gate messages** — explain what to review and what approve/reject means ### Inputs - **Use descriptive prompts** — the `prompt` field is shown to users when running the workflow - **Set sensible defaults** — optional inputs should have defaults that work for the common case - **Constrain with enums** — when there's a fixed set of valid values, use `enum` for validation - **Type appropriately** — use `number` for counts, `boolean` for flags, `string` for names ### Shell Steps - **Avoid destructive commands** — don't delete files or directories without explicit confirmation via a gate - **Quote variables** — use proper quoting in shell commands to handle spaces - **Check exit codes** — shell step failures stop the workflow; make sure commands are robust ### Integration Flexibility - **Set `integration` at workflow level** — use the `workflow.integration` field as the default - **Allow per-step overrides** — let individual steps specify a different integration if needed - **Document required integrations** — list which integrations must be installed in `requires.integrations` ### Expression References - **Only reference prior steps** — expressions like `{{ steps.plan.output.file }}` only work if `plan` ran before the current step - **Use `default` filter** — `{{ val | default('fallback') }}` prevents failures from missing values - **Keep expressions simple** — complex logic should be in shell steps, not expressions