mirror of
https://github.com/aljazceru/goose.git
synced 2026-01-02 05:54:23 +01:00
Update Recipe Cookbook Submission Flow (#3064)
Co-authored-by: angiejones <jones.angie@gmail.com>
This commit is contained in:
114
.github/ISSUE_TEMPLATE/submit-recipe.yml
vendored
114
.github/ISSUE_TEMPLATE/submit-recipe.yml
vendored
@@ -1,5 +1,5 @@
|
||||
name: 🧑🍳 Submit a Recipe to the Goose Cookbook
|
||||
description: Share a reusable Goose session (aka a recipe) to help the community!
|
||||
description: Share a reusable Goose recipe with the community!
|
||||
title: "[Recipe] <your recipe title here>"
|
||||
labels: ["recipe submission"]
|
||||
body:
|
||||
@@ -7,52 +7,104 @@ body:
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for contributing to the Goose Cookbook! 🍳
|
||||
Recipes are reusable sessions created in Goose Desktop or CLI and shared with the community to help others vibe-code faster.
|
||||
Recipes are reusable sessions created in Goose Desktop or CLI and shared with the community to help others vibe code faster.
|
||||
|
||||
📌 **How to Submit**
|
||||
- Create your recipe using Goose ("Make Agent from this session")
|
||||
- Fill out the JSON below using the format provided
|
||||
- Fill out the YAML below using the format provided
|
||||
- Paste it into the field and submit the issue — we'll review and add it to the Cookbook!
|
||||
|
||||
🪄 **What Happens After?**
|
||||
- If accepted, we'll publish your recipe to the [Goose Recipes Cookbook](https://block.github.io/goose/recipes)
|
||||
- You'll receive LLM credits as a thank-you!
|
||||
- You'll receive OpenRouter **LLM API credits** as a thank you!
|
||||
- Your GitHub handle will be displayed and linked on the recipe card
|
||||
- If you provide an email below, we'll email you your credits when your recipe is approved and merged.
|
||||
- If the YAML has any issues, Goose will comment with validation errors so you can fix and resubmit.
|
||||
|
||||
🧪 **Pro Tip:** You can test your recipe locally in your terminal with:
|
||||
`goose recipe validate your-recipe.yaml`
|
||||
|
||||
- type: textarea
|
||||
id: recipe-json
|
||||
id: recipe-yaml
|
||||
attributes:
|
||||
label: Paste Your Recipe JSON Below
|
||||
description: Use the structure below and be sure to include your GitHub handle.
|
||||
label: Paste Your Full Recipe YAML Below
|
||||
description: Use the structure below and we’ll auto-fill your GitHub handle for `author.contact` after submission.
|
||||
placeholder: |
|
||||
{
|
||||
"id": "joke-of-the-day",
|
||||
"title": "Joke of the day",
|
||||
"description": "Will tell you a joke of the day based on the current day",
|
||||
"instructions": "Your job is to tell a joke of the day",
|
||||
"prompt": "Based on what day it is today, generate a joke. Mention the day on the first line then an empty line and then the joke. Don't just say the date, but figure out if there's any cultural significance, like national shelves day",
|
||||
"action": "Generate Joke",
|
||||
"category": "Entertainment",
|
||||
"extensions": ["Developer"],
|
||||
"activities": ["Tell a joke", "Daily humor"],
|
||||
"recipeUrl": "goose://recipe?config=...",
|
||||
"author": "your-github-handle"
|
||||
}
|
||||
version: "1.0.0"
|
||||
id: clean-up-feature-flag
|
||||
title: Clean Up Feature Flag
|
||||
description: Automatically clean up all references of a fully rolled out feature flag from a codebase and make the new behavior the default.
|
||||
instructions: |
|
||||
Your job is to systematically remove a fully rolled out feature flag and ensure the new behavior is now the default. Use code search tools like ripgrep to identify all references to the flag, clean up definition files, usage sites, tests, and configuration files. Then create a commit and push changes with clear commit messages documenting the flag removal.
|
||||
prompt: |
|
||||
Task: Remove a feature flag that has been fully rolled out, where the feature flag's functionality should become the default behavior.
|
||||
|
||||
Context:
|
||||
Feature flag key: {{ feature_flag_key }}
|
||||
Project: {{ repo_dir }}
|
||||
|
||||
Steps to follow:
|
||||
1. Check out a *new* branch from main or master named using the feature flag key.
|
||||
2. Find the feature flag constant/object that wraps the key.
|
||||
3. Search for all references to the constant/object using ripgrep or equivalent tools.
|
||||
4. Remove all conditional logic and make the new behavior default.
|
||||
5. Remove unused imports, mocks, config, and tests.
|
||||
6. Commit your changes and push the branch.
|
||||
7. Open a GitHub PR.
|
||||
|
||||
Use commit messages like:
|
||||
chore(flag-cleanup): remove <feature_flag_key> flag from codebase
|
||||
|
||||
parameters:
|
||||
- key: feature_flag_key
|
||||
input_type: string
|
||||
requirement: required
|
||||
description: Key of the feature flag
|
||||
|
||||
- key: repo_dir
|
||||
input_type: string
|
||||
requirement: optional
|
||||
default: ./
|
||||
description: Directory of the codebase
|
||||
|
||||
extensions:
|
||||
- type: stdio
|
||||
name: developer
|
||||
cmd: uvx
|
||||
args:
|
||||
- developer-mcp@latest
|
||||
timeout: 300
|
||||
bundled: true
|
||||
description: Access developer tools
|
||||
|
||||
activities:
|
||||
- Remove feature flag definitions
|
||||
- Clean up feature flag usage sites
|
||||
- Update affected tests
|
||||
- Remove flag configurations
|
||||
- Document flag removal
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: email
|
||||
attributes:
|
||||
label: Your Email (optional)
|
||||
description: If your recipe is approved, we'll email your LLM API credits here.
|
||||
placeholder: yourname@example.com
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
🛠 **Recipe Field Tips**
|
||||
- `"id"` should be lowercase, hyphenated, and unique (e.g. `my-awesome-recipe`)
|
||||
- `"title"` is the display name of your recipe
|
||||
- `"description"` should clearly explain what the recipe does
|
||||
- `"instructions"` are the specific instructions for the Goose agent
|
||||
- `"prompt"` is the initial prompt that starts the recipe when launched
|
||||
- `"action"` describes the core purpose of the recipe (e.g., `Generate Docs`)
|
||||
- `"category"` is the type of user this recipe is for (e.g., `Developer`, `Entertainment`)
|
||||
- `"extensions"` are the Goose tools this recipe uses
|
||||
- `"activities"` are the main steps or capabilities of your recipe
|
||||
- `"recipeUrl"` is from Goose Desktop/CLI
|
||||
- `"author"` is your GitHub handle — we'll link to your profile in the Cookbook
|
||||
- `version` must be "1.0.0" for now
|
||||
- `id` should be lowercase, hyphenated, and unique (e.g. `my-awesome-recipe`)
|
||||
- `title` is the display name of your recipe
|
||||
- `description` should clearly explain what the recipe does
|
||||
- `instructions` are specific steps Goose should follow — supports template variables like `{{ variable_name }}`
|
||||
- `prompt` is the first thing Goose sees when the recipe is launched
|
||||
- `parameters` should include required or optional inputs — optional ones must have `default`
|
||||
- `extensions` must follow the full format with `type`, `cmd`, `args`, `timeout`, etc.
|
||||
- `activities` describe the main actions the recipe performs
|
||||
|
||||
136
.github/workflows/create-recipe-pr.yml
vendored
Normal file
136
.github/workflows/create-recipe-pr.yml
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
name: Handle Recipe Submissions
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened, labeled]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
create-recipe-pr:
|
||||
if: github.event.label.name == 'recipe submission' || github.event.issue.labels.*.name contains 'recipe submission'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
PROVIDER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Install and Configure Goose
|
||||
run: |
|
||||
mkdir -p /home/runner/.local/bin
|
||||
curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh \
|
||||
| CONFIGURE=false INSTALL_PATH=/home/runner/.local/bin bash
|
||||
echo "/home/runner/.local/bin" >> $GITHUB_PATH
|
||||
|
||||
mkdir -p ~/.config/goose
|
||||
cat <<EOF > ~/.config/goose/config.yaml
|
||||
GOOSE_PROVIDER: openrouter
|
||||
GOOSE_MODEL: "anthropic/claude-3.5-sonnet"
|
||||
keyring: false
|
||||
EOF
|
||||
|
||||
- name: Extract recipe YAML from issue
|
||||
id: parse
|
||||
run: |
|
||||
ISSUE_BODY=$(jq -r .issue.body "$GITHUB_EVENT_PATH")
|
||||
RECIPE_YAML=$(echo "$ISSUE_BODY" | awk '/```/,/```/' | sed '1d;$d')
|
||||
echo "$RECIPE_YAML" > recipe.yaml
|
||||
|
||||
AUTHOR="${{ github.event.issue.user.login }}"
|
||||
if ! grep -q "^author:" recipe.yaml; then
|
||||
echo -e "\nauthor:\n contact: $AUTHOR" >> recipe.yaml
|
||||
fi
|
||||
|
||||
TITLE=$(yq '.title' recipe.yaml | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-')
|
||||
echo "branch_name=add-recipe-${TITLE}" >> $GITHUB_OUTPUT
|
||||
echo "recipe_title=${TITLE}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Validate recipe.yaml with Goose
|
||||
id: validate
|
||||
continue-on-error: true
|
||||
run: |
|
||||
OUTPUT=$(goose recipe validate recipe.yaml 2>&1)
|
||||
echo "$OUTPUT"
|
||||
{
|
||||
echo "validation_output<<EOF"
|
||||
echo "$OUTPUT"
|
||||
echo "EOF"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Post validation result to issue
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
||||
VALIDATION_B64: ${{ steps.validate.outputs.validation_output }}
|
||||
run: |
|
||||
if [ "${{ steps.validate.outcome }}" == "failure" ]; then
|
||||
OUTPUT=$(echo "$VALIDATION_B64" | base64 --decode)
|
||||
COMMENT="❌ Recipe validation failed:\n\n\`\`\`\n$OUTPUT\n\`\`\`\nPlease fix the above issues and resubmit."
|
||||
echo -e "$COMMENT" | gh issue comment "$ISSUE_NUMBER"
|
||||
gh issue close "$ISSUE_NUMBER"
|
||||
exit 1
|
||||
else
|
||||
gh issue comment "$ISSUE_NUMBER" --body "✅ Recipe validated successfully!"
|
||||
fi
|
||||
|
||||
|
||||
- name: Generate recipeUrl and save updated recipe
|
||||
run: |
|
||||
BASE64_ENCODED=$(cat recipe.yaml | base64 | tr -d '\n')
|
||||
echo "" >> recipe.yaml
|
||||
echo "recipeUrl: goose://recipe?config=${BASE64_ENCODED}" >> recipe.yaml
|
||||
|
||||
- name: Create branch and add file
|
||||
env:
|
||||
BRANCH_NAME: ${{ steps.parse.outputs.branch_name }}
|
||||
run: |
|
||||
git checkout -b "$BRANCH_NAME"
|
||||
DEST_DIR="documentation/src/pages/recipes/data/recipes"
|
||||
mkdir -p "$DEST_DIR"
|
||||
ID=$(yq '.id' recipe.yaml)
|
||||
|
||||
if [ -f "$DEST_DIR/${ID}.yaml" ]; then
|
||||
echo "❌ Recipe with ID '$ID' already exists. Aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp recipe.yaml "$DEST_DIR/${ID}.yaml"
|
||||
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add "$DEST_DIR/${ID}.yaml"
|
||||
git commit -m "Add recipe: ${ID}"
|
||||
git push origin "$BRANCH_NAME"
|
||||
|
||||
- name: Create pull request
|
||||
id: cpr
|
||||
uses: peter-evans/create-pull-request@5e5b2916f4b4c9420e5e9b0dc4a6d292d30165d7
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: ${{ steps.parse.outputs.branch_name }}
|
||||
title: "Add recipe: ${{ steps.parse.outputs.recipe_title }}"
|
||||
body: "This PR adds a new Goose recipe submitted via issue #${{ github.event.issue.number }}."
|
||||
reviewers: |
|
||||
EbonyLouis
|
||||
angiejones
|
||||
blackgirlbytes
|
||||
|
||||
- name: Comment and close issue
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
||||
PR_URL: ${{ steps.cpr.outputs.pull-request-url }}
|
||||
run: |
|
||||
gh issue comment "$ISSUE_NUMBER" --body "🎉 Thanks for submitting your recipe! We've created a [PR]($PR_URL) to add it to the Cookbook."
|
||||
gh issue close "$ISSUE_NUMBER"
|
||||
Reference in New Issue
Block a user