Skip to content

Plan: Webhook Verification & Issue-Branch Linking #49

Description

@sylvansys

Branch: 49-fix/can-u-please-tell-me-what-context-files-
Plan file: /home/ben/.claude/plans/melodic-hugging-bumblebee.md


Plan: Webhook Verification & Issue-Branch Linking

Intent

Ensure every PR to repos with Constellos App installed triggers the requirements reviewer with both the linked issue context and modified files. Support new commits to existing PRs.

Key Question: Own DB vs GitHub?

Recommendation: Use GitHub only - no DB needed

GitHub provides everything needed:

  1. Branch name parsing - 123-feature-name → issue #123 (already implemented)
  2. PR body parsing - "Closes #123" keywords (can add)
  3. GraphQL API - closingIssuesReferences gives official linked issues
  4. Changed files - gh pr view --json files

A DB would add complexity without benefit since GitHub already tracks these relationships.

Webhook Events to Subscribe

Configure GitHub App to listen for:

pull_request:
  - opened      # New PR created
  - synchronize # New commits pushed to PR branch
  - reopened    # PR reopened after close

All three events provide the same payload structure with PR number, branch, and commit info.

Data Available in Webhook Payload

Data Source API Call?
PR number event.number No
Branch name event.pull_request.head.ref No
Base branch event.pull_request.base.ref No
PR body event.pull_request.body No
Changed files gh pr view --json files Yes
Issue context gh issue view --json title,body Yes

Issue Linking Strategy (Priority Order)

  1. Branch name - Parse {issue}-{description} pattern
  2. PR body keywords - Parse "Closes #X", "Fixes #X", "Resolves #X"
  3. GraphQL fallback - Query closingIssuesReferences if above fail
# 1. Try branch name first
[[ $BRANCH =~ ^([0-9]+)- ]] && ISSUE="${BASH_REMATCH[1]}"

# 2. Try PR body keywords if branch didn't match
if [ -z "$ISSUE" ]; then
  ISSUE=$(echo "$PR_BODY" | grep -oP '(Closes|Fixes|Resolves)\s+#\K[0-9]+' | head -1)
fi

# 3. GraphQL fallback (most reliable)
if [ -z "$ISSUE" ]; then
  ISSUE=$(gh api graphql -f query='...' | jq '.data...closingIssuesReferences...')
fi

Verification Approach

1. Test Webhook Delivery

  • GitHub App Settings → Advanced → Recent Deliveries
  • Shows all webhook payloads sent and response codes
  • Can redeliver failed webhooks for debugging

2. Test PR Scenarios

Scenario Expected Behavior
PR opened with 123-feature branch Links to issue #123, runs review
PR opened with "Closes #456" in body Links to issue #456, runs review
New commit pushed to existing PR Re-runs review, edits existing comment
PR with no linked issue Skips requirements review (code-quality still runs)

3. Logging for Verification

Add to Constellos backend:

[webhook] PR #50 opened on repo/name
[issue]   Linked issue: #49 (from branch name)
[files]   Changed: 5 files
[agent]   Running: requirements
[agent]   Running: code-quality
[result]  Posted comment to PR #50

Architecture: GitHub Actions with Config-Driven Agents

Why GitHub Actions (not server-side):

  • claude-code-base-action requires Actions runtime environment
  • OAuth tokens last ~1 year, stored in GitHub secrets
  • Stateless execution per PR event

Approach: Single config-driven workflow

  • Target repos add ONE workflow file
  • Workflow reads .constellos/config.json to determine which agents to run
  • Loops through enabled agents, runs each one
  • Cleaner than multiple separate workflow steps

Implementation: Single Config-Driven Action

How Target Repos Use This

Target repo adds:

  1. One workflow file (.github/workflows/constellos.yml)
  2. Config file (.constellos/config.json) - optional, defaults used if missing

Example workflow with matrix strategy:

name: Constellos Review
on:
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  # Job 1: Read config and output enabled agents
  config:
    runs-on: ubuntu-latest
    outputs:
      agents: ${{ steps.read.outputs.agents }}
    steps:
      - uses: actions/checkout@v4
      - id: read
        run: |
          if [ -f ".constellos/config.json" ]; then
            AGENTS=$(jq -c '[.agents | to_entries[] | select(.value.enabled) | .key]' .constellos/config.json)
          else
            AGENTS='["requirements","code-quality"]'
          fi
          echo "agents=$AGENTS" >> $GITHUB_OUTPUT

  # Job 2: Run each enabled agent in parallel
  review:
    needs: config
    runs-on: ubuntu-latest
    strategy:
      matrix:
        agent: ${{ fromJson(needs.config.outputs.agents) }}
    steps:
      - uses: actions/checkout@v4
      - uses: constellos/constellos-actions@main
        with:
          review_type: ${{ matrix.agent }}
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
          pr_number: ${{ github.event.number }}
          branch: ${{ github.head_ref }}

Benefits:

  • Agents run in parallel (faster)
  • Config-driven (enable/disable without workflow changes)
  • Clean separation of concerns

Files to Modify in This Repo

  1. .github/actions/requirements-reviewer/action.yml

    • Add PR body parsing as fallback for issue linking
    • Handle "Closes #X", "Fixes #X", "Resolves #X" keywords
  2. .github/workflows/test-actions.yml

    • Remove checks for README.md and CHANGELOG.md
    • Update expected action count (now 3)
  3. CLAUDE.md

    • Add "Setup Guide" section with example workflow
    • Document config.json options
    • Issue linking conventions (branch name + PR body)
  4. .github/templates/constellos-review.yml (new)

    • Ready-to-copy workflow template with matrix strategy

Verification Commands

# Check GitHub App webhook config
gh api /app/hook/config

# List recent webhook deliveries
gh api /app/hook/deliveries

# Test issue extraction from branch
BRANCH="49-fix-something"
[[ $BRANCH =~ ^([0-9]+)- ]] && echo "Issue: ${BASH_REMATCH[1]}"

# Test PR body parsing
echo "This PR Closes #123" | grep -oP '(Closes|Fixes|Resolves)\s+#\K[0-9]+'

Success Criteria

  • PR body parsing added as fallback for issue linking in requirements-reviewer
  • Test workflow passes (no README/CHANGELOG checks, action count = 3)
  • CLAUDE.md has setup guide with matrix workflow example
  • Workflow template at .github/templates/constellos-review.yml

Verification

# 1. Test workflow passes
gh workflow run test-actions.yml

# 2. Verify issue linking logic (manual test)
# Branch: 999-test → links to issue #999
# PR body "Closes #888" → links to issue #888

# 3. Verify file structure
ls .github/templates/constellos-review.yml
grep -q "Closes\|Fixes\|Resolves" .github/actions/requirements-reviewer/action.yml

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions