feat: start recipes v0.5 #313
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: AI Triage Automation | |
| on: | |
| issues: | |
| types: | |
| - labeled | |
| workflow_dispatch: | |
| inputs: | |
| issue_url: | |
| description: "GitHub Issue URL to process" | |
| required: true | |
| type: string | |
| template_name: | |
| description: "Coder template to use for workspace" | |
| required: true | |
| default: "coder" | |
| type: string | |
| template_preset: | |
| description: "Template preset to use" | |
| required: false | |
| default: "" | |
| type: string | |
| prefix: | |
| description: "Prefix for workspace name" | |
| required: false | |
| default: "traiage" | |
| type: string | |
| jobs: | |
| traiage: | |
| name: Triage GitHub Issue with Claude Code | |
| runs-on: ubuntu-latest | |
| if: github.event.label.name == 'traiage' || github.event_name == 'workflow_dispatch' | |
| timeout-minutes: 30 | |
| env: | |
| CODER_URL: ${{ secrets.TRAIAGE_CODER_URL }} | |
| CODER_SESSION_TOKEN: ${{ secrets.TRAIAGE_CODER_SESSION_TOKEN }} | |
| permissions: | |
| contents: read | |
| issues: write | |
| actions: write | |
| steps: | |
| # This is only required for testing locally using nektos/act, so leaving commented out. | |
| # An alternative is to use a larger or custom image. | |
| # - name: Install Github CLI | |
| # id: install-gh | |
| # run: | | |
| # (type -p wget >/dev/null || (sudo apt update && sudo apt install wget -y)) \ | |
| # && sudo mkdir -p -m 755 /etc/apt/keyrings \ | |
| # && out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg \ | |
| # && cat $out | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \ | |
| # && sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \ | |
| # && sudo mkdir -p -m 755 /etc/apt/sources.list.d \ | |
| # && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ | |
| # && sudo apt update \ | |
| # && sudo apt install gh -y | |
| - name: Determine Inputs | |
| id: determine-inputs | |
| if: always() | |
| env: | |
| GITHUB_ACTOR: ${{ github.actor }} | |
| GITHUB_EVENT_ISSUE_HTML_URL: ${{ github.event.issue.html_url }} | |
| GITHUB_EVENT_NAME: ${{ github.event_name }} | |
| GITHUB_EVENT_USER_ID: ${{ github.event.sender.id }} | |
| GITHUB_EVENT_USER_LOGIN: ${{ github.event.sender.login }} | |
| INPUTS_ISSUE_URL: ${{ inputs.issue_url }} | |
| INPUTS_TEMPLATE_NAME: ${{ inputs.template_name || 'coder' }} | |
| INPUTS_TEMPLATE_PRESET: ${{ inputs.template_preset || ''}} | |
| INPUTS_PREFIX: ${{ inputs.prefix || 'traiage' }} | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| echo "Using template name: ${INPUTS_TEMPLATE_NAME}" | |
| echo "template_name=${INPUTS_TEMPLATE_NAME}" >> "${GITHUB_OUTPUT}" | |
| echo "Using template preset: ${INPUTS_TEMPLATE_PRESET}" | |
| echo "template_preset=${INPUTS_TEMPLATE_PRESET}" >> "${GITHUB_OUTPUT}" | |
| echo "Using prefix: ${INPUTS_PREFIX}" | |
| echo "prefix=${INPUTS_PREFIX}" >> "${GITHUB_OUTPUT}" | |
| # For workflow_dispatch, use the actor who triggered it | |
| # For issues events, use the issue author. | |
| if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then | |
| if ! GITHUB_USER_ID=$(gh api "users/${GITHUB_ACTOR}" --jq '.id'); then | |
| echo "::error::Failed to get GitHub user ID for actor ${GITHUB_ACTOR}" | |
| exit 1 | |
| fi | |
| echo "Using workflow_dispatch actor: ${GITHUB_ACTOR} (ID: ${GITHUB_USER_ID})" | |
| echo "github_user_id=${GITHUB_USER_ID}" >> "${GITHUB_OUTPUT}" | |
| echo "github_username=${GITHUB_ACTOR}" >> "${GITHUB_OUTPUT}" | |
| echo "Using issue URL: ${INPUTS_ISSUE_URL}" | |
| echo "issue_url=${INPUTS_ISSUE_URL}" >> "${GITHUB_OUTPUT}" | |
| exit 0 | |
| elif [[ "${GITHUB_EVENT_NAME}" == "issues" ]]; then | |
| GITHUB_USER_ID=${GITHUB_EVENT_USER_ID} | |
| echo "Using issue author: ${GITHUB_EVENT_USER_LOGIN} (ID: ${GITHUB_USER_ID})" | |
| echo "github_user_id=${GITHUB_USER_ID}" >> "${GITHUB_OUTPUT}" | |
| echo "github_username=${GITHUB_EVENT_USER_LOGIN}" >> "${GITHUB_OUTPUT}" | |
| echo "Using issue URL: ${GITHUB_EVENT_ISSUE_HTML_URL}" | |
| echo "issue_url=${GITHUB_EVENT_ISSUE_HTML_URL}" >> "${GITHUB_OUTPUT}" | |
| exit 0 | |
| else | |
| echo "::error::Unsupported event type: ${GITHUB_EVENT_NAME}" | |
| exit 1 | |
| fi | |
| - name: Verify push access | |
| env: | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| GH_TOKEN: ${{ github.token }} | |
| GITHUB_USERNAME: ${{ steps.determine-inputs.outputs.github_username }} | |
| GITHUB_USER_ID: ${{ steps.determine-inputs.outputs.github_user_id }} | |
| run: | | |
| # Query the actor’s permission on this repo | |
| can_push="$(gh api "/repos/${GITHUB_REPOSITORY}/collaborators/${GITHUB_USERNAME}/permission" --jq '.user.permissions.push')" | |
| if [[ "${can_push}" != "true" ]]; then | |
| echo "::error title=Access Denied::${GITHUB_USERNAME} does not have push access to ${GITHUB_REPOSITORY}" | |
| exit 1 | |
| fi | |
| - name: Extract context key and description from issue | |
| id: extract-context | |
| env: | |
| ISSUE_URL: ${{ steps.determine-inputs.outputs.issue_url }} | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| issue_number="$(gh issue view "${ISSUE_URL}" --json number --jq '.number')" | |
| context_key="gh-${issue_number}" | |
| TASK_PROMPT=$(cat <<EOF | |
| Fix ${ISSUE_URL} | |
| 1. Use the gh CLI to read the issue description and comments. | |
| 2. Think carefully and try to understand the root cause. If the issue is unclear or not well defined, ask me to clarify and provide more information. | |
| 3. Write a proposed implementation plan to PLAN.md for me to review before starting implementation. Your plan should use TDD and only make the minimal changes necessary to fix the root cause. | |
| 4. When I approve your plan, start working on it. If you encounter issues with the plan, ask me for clarification and update the plan as required. | |
| 5. When you have finished implementation according to the plan, commit and push your changes, and create a PR using the gh CLI for me to review. | |
| EOF | |
| ) | |
| echo "context_key=${context_key}" >> "${GITHUB_OUTPUT}" | |
| { | |
| echo "TASK_PROMPT<<EOF" | |
| echo "${TASK_PROMPT}" | |
| echo "EOF" | |
| } >> "${GITHUB_OUTPUT}" | |
| - name: Checkout repository | |
| uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 | |
| with: | |
| fetch-depth: 1 | |
| path: ./.github/actions/create-task-action | |
| persist-credentials: false | |
| ref: main | |
| repository: coder/create-task-action | |
| - name: Create Coder Task | |
| id: create_task | |
| uses: ./.github/actions/create-task-action | |
| with: | |
| coder-url: ${{ secrets.TRAIAGE_CODER_URL }} | |
| coder-token: ${{ secrets.TRAIAGE_CODER_SESSION_TOKEN }} | |
| coder-organization: "default" | |
| coder-template-name: coder | |
| coder-template-preset: ${{ steps.determine-inputs.outputs.template_preset }} | |
| coder-task-name-prefix: gh-coder | |
| coder-task-prompt: ${{ steps.extract-context.outputs.task_prompt }} | |
| github-user-id: ${{ steps.determine-inputs.outputs.github_user_id }} | |
| github-token: ${{ github.token }} | |
| github-issue-url: ${{ steps.determine-inputs.outputs.issue_url }} | |
| comment-on-issue: ${{ startsWith(steps.determine-inputs.outputs.issue_url, format('{0}/{1}', github.server_url, github.repository)) }} | |
| - name: Write outputs | |
| env: | |
| TASK_CREATED: ${{ steps.create_task.outputs.task-created }} | |
| TASK_NAME: ${{ steps.create_task.outputs.task-name }} | |
| TASK_URL: ${{ steps.create_task.outputs.task-url }} | |
| run: | | |
| { | |
| echo "**Task created:** ${TASK_CREATED}" | |
| echo "**Task name:** ${TASK_NAME}" | |
| echo "**Task URL**: ${TASK_URL}" | |
| } >> "${GITHUB_STEP_SUMMARY}" |