codetether-agent 4.5.7

A2A-native AI coding agent for the CodeTether ecosystem
Documentation
name: CodeTether Review

on:
  pull_request:
    types: [opened, synchronize, reopened]
  issues:
    types: [assigned, labeled]
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]

concurrency:
  group: codetether-review-${{ github.event_name }}-${{ github.event.pull_request.number || github.event.issue.number }}
  cancel-in-progress: true

permissions:
  contents: write
  pull-requests: write
  issues: write

jobs:
  review:
    runs-on: ubuntu-latest
    timeout-minutes: 25
    # PRs: always run
    # Issues: when assigned or labeled 'codetether'
    # Issue comments: when @mentioning the bot
    if: >
      github.event_name == 'pull_request' ||
      (github.event_name == 'issues' && (
        github.event.action == 'assigned' ||
        contains(github.event.issue.labels.*.name, 'codetether')
      )) ||
      (github.event_name == 'issue_comment' && (
        contains(github.event.comment.body, '@codetether')
      )) ||
      (github.event_name == 'pull_request_review_comment' && (
        contains(github.event.comment.body, '@codetether')
      ))
    steps:
      - name: Classify request
        id: classify
        shell: bash
        env:
          EVENT_NAME: ${{ github.event_name }}
          COMMENT_BODY: ${{ github.event.comment.body || '' }}
          ISSUE_PR_URL: ${{ github.event.issue.pull_request.url || '' }}
        run: |
          mode="server"
          body="$(printf '%s' "${COMMENT_BODY}" | tr '\n' ' ' | tr '[:upper:]' '[:lower:]')"
          is_pr_comment="false"
          if [ "$EVENT_NAME" = "pull_request_review_comment" ]; then
            is_pr_comment="true"
          elif [ "$EVENT_NAME" = "issue_comment" ] && [ -n "$ISSUE_PR_URL" ]; then
            is_pr_comment="true"
          fi
          if [ "$is_pr_comment" = "true" ] && printf '%s' "$body" | grep -Eq '(@codetether([^[:alnum:]_-]|$).*(fix|apply|address|implement|patch))|((fix|apply|address|implement|patch).+@codetether([^[:alnum:]_-]|$))'; then
            mode="local"
          fi
          echo "mode=${mode}" >> "$GITHUB_OUTPUT"

      - name: Checkout repository
        shell: bash
        env:
          REPO_DIR: ${{ github.workspace }}/repo
          CHECKOUT_REF: ${{ (github.event_name == 'pull_request' || github.event_name == 'pull_request_review_comment') && github.event.pull_request.head.sha || (github.event_name == 'issue_comment' && github.event.issue.pull_request && format('refs/pull/{0}/head', github.event.issue.number)) || github.sha }}
          RAW_GITHUB_TOKEN: ${{ github.token }}
        run: |
          rm -rf "${REPO_DIR}"
          mkdir -p "${REPO_DIR}"
          git -C "${REPO_DIR}" init .
          git -C "${REPO_DIR}" remote add origin "https://x-access-token:${RAW_GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
          git -C "${REPO_DIR}" fetch --prune --no-recurse-submodules origin \
            +refs/heads/*:refs/remotes/origin/* \
            +refs/tags/*:refs/tags/*
          git -C "${REPO_DIR}" fetch --no-recurse-submodules origin "${CHECKOUT_REF}"
          git -C "${REPO_DIR}" checkout --force FETCH_HEAD

      # Get a GitHub App installation token so comments come from the bot identity
      - name: Get App Token
        uses: actions/create-github-app-token@v3.1.1
        id: app-token
        with:
          app-id: ${{ secrets.APP_ID }}
          private-key: ${{ secrets.APP_PRIVATE_KEY }}

      - name: CodeTether Review
        uses: rileyseaburg/codetether-action@v1
        with:
          mode: ${{ steps.classify.outputs.mode }}
          token: ${{ secrets.CODETETHER_TOKEN }}
          github_token: ${{ steps.app-token.outputs.token }}
          vault_addr: ${{ secrets.VAULT_ADDR }}
          vault_token: ${{ secrets.VAULT_TOKEN }}
          max_steps: "60"
          task_wait_seconds: "1200"
          workspace_path: ${{ github.workspace }}/repo