# How the GitHub Action Handles Pull Request Event Types and Triggers Asana Subtask Creation

> Learn how the GitHub Action handles pull request events and triggers Asana subtask creation. Discover the logic behind reviewer-related actions and subtask generation.

- Repository: [Keita Kitamura/github-asana-request-review-action](https://github.com/keitap/github-asana-request-review-action)
- Tags: internals
- Published: 2026-03-05

---

**The GitHub Action processes `PullRequestEvent` and `PullRequestReviewEvent` webhooks in [`handler.go`](https://github.com/keitap/github-asana-request-review-action/blob/main/handler.go), creating Asana subtasks only when reviewer-related actions occur and no existing subtask is found.**

The `keitap/github-asana-request-review-action` bridges GitHub pull requests and Asana tasks by automatically managing code review workflows. When GitHub delivers webhook payloads to this action, it dispatches events based on their concrete type to either synchronize reviewers or record review submissions, creating subtasks only during the reviewer assignment phase according to specific trigger conditions defined in the source code.

## Event Dispatch Architecture in handler.go

The action's core orchestration lives in [[`handler.go`](https://github.com/keitap/github-asana-request-review-action/blob/main/handler.go)](https://github.com/keitap/github-asana-request-review-action/blob/main/handler.go). When GitHub delivers a webhook, the `Handler.Handle` method (lines 35-48) unmarshals the payload and routes it to specialized handlers based on the event type.

### Webhook Entry Point and Type Detection

The `Handle` method acts as the central router. It inspects the incoming event and delegates to one of two primary handlers:

- **`handlePullRequestEvent`** – Processes PR lifecycle changes (opened, synchronized, labeled, etc.)
- **`handlePullRequestReviewEvent`** – Processes submitted reviews (approvals, comments, change requests)

This dispatch pattern ensures that reviewer synchronization logic remains separate from review comment logging.

## Pull Request Events and Reviewer Synchronization

For every `PullRequestEvent`, the `handlePullRequestEvent` function executes a two-phase process: commenting on the parent Asana task and synchronizing the reviewer list.

### Extracting Asana Task Links

First, the handler extracts the Asana task ID from the PR description using `parseAsanaTaskLink` (lines 54-60). If no task link is found, processing terminates early.

When a valid task ID exists, the handler performs:

1. **Task comment upsertion** via `updateTask` → `upsertPullRequestComment`
2. **Reviewer synchronization** via `updateReviewers`

### Review-Relevant Actions That Trigger Updates

Not every PR webhook triggers reviewer processing. The `updateReviewers` method (lines 101-110) filters for specific `action` values deemed review-relevant:

- **`synchronize`** – New commits pushed to the PR branch
- **`edited`** – Modifications to PR body or metadata
- **`labeled`** / **`unlabeled`** – Label additions or removals
- **`review_requested`** / **`review_request_removed`** – Explicit reviewer assignments

When any of these actions fire, the handler gathers the current reviewer list either directly from the webhook payload or via the GitHub API (lines 115-124), then resolves each GitHub login to an Asana account using `fetchAccount`.

## How Subtask Creation Is Triggered

Subtask creation occurs exclusively within the reviewer synchronization path, not during review submission handling.

### The upsertReviewer Logic

For each resolved reviewer, the action calls `upsertReviewer` (lines 158-176). This method:

1. Skips users without an associated Asana GID
2. Calculates a due date using `NextBusinessDay` from [`config.go`](https://github.com/keitap/github-asana-request-review-action/blob/main/config.go) (respecting configured holidays)
3. Searches for existing subtasks via `FindSubtaskByName` (lines 158-164)

### Subtask Creation Criteria

A new subtask is created **only if no existing subtask contains the reviewer's name**. This duplication check prevents multiple subtasks for the same reviewer on the same PR.

When triggered, the action invokes `AddCodeReviewSubtask` (lines 166-170), implemented in [`asana.go`](https://github.com/keitap/github-asana-request-review-action/blob/main/asana.go).

### Subtask Structure and Metadata

The created subtask contains the following properties:

- **Parent**: The original feature task extracted from the PR description
- **Assignee**: The reviewer's Asana user GID
- **Followers**: The PR requester's Asana GID (for visibility)
- **Name**: Formatted as `✍️ Code review: #<PR-number> <reviewer>`
- **Due date**: Next business day (configurable via [`config.go`](https://github.com/keitap/github-asana-request-review-action/blob/main/config.go))

## Pull Request Review Events

When a reviewer submits actual feedback (approval, comment, or request changes), GitHub sends a `PullRequestReviewEvent`.

### Comment Submission vs. Subtask Creation

The `handlePullRequestReviewEvent` handler (lines 59-66) performs a read-only operation relative to subtask creation:

1. Extracts the Asana task ID from the PR
2. Resolves the reviewer's Asana account via `fetchAccount`
3. Locates the existing review subtask using `FindSubtaskByName`
4. Appends a comment via `AddCodeReviewSubtaskComment`

**Critical distinction**: If the subtask does not exist when a review is submitted, the handler logs a message and **does not create a new subtask**. Subtask creation is strictly limited to the reviewer assignment workflow described in `handlePullRequestEvent`.

## Summary

- The action routes webhooks through `Handler.Handle` in [`handler.go`](https://github.com/keitap/github-asana-request-review-action/blob/main/handler.go) to either `handlePullRequestEvent` or `handlePullRequestReviewEvent`
- Only `PullRequestEvent` actions—`synchronize`, `edited`, `labeled`, `review_requested`, and their removal counterparts—trigger reviewer synchronization
- Subtasks are created by `upsertReviewer` when a reviewer is assigned and no existing subtask matches their name
- `PullRequestReviewEvent` only adds comments to existing subtasks; it never creates them
- Subtask metadata includes automatic assignee mapping, follower configuration, and business-day due dates configured in [`config.go`](https://github.com/keitap/github-asana-request-review-action/blob/main/config.go)

## Frequently Asked Questions

### What triggers the creation of an Asana subtask?

According to the source code in [`handler.go`](https://github.com/keitap/github-asana-request-review-action/blob/main/handler.go), subtask creation triggers when a `PullRequestEvent` contains a review-relevant action (`review_requested`, `synchronize`, `edited`, or `labeled` variants) and the `upsertReviewer` method determines no existing subtask contains the reviewer's name. The action then calls `AddCodeReviewSubtask` in [`asana.go`](https://github.com/keitap/github-asana-request-review-action/blob/main/asana.go) to generate the task with the reviewer as assignee and the PR requester as a follower.

### How does the action handle review submissions?

When a `PullRequestReviewEvent` fires, the `handlePullRequestReviewEvent` method locates the existing review subtask and appends a comment via `AddCodeReviewSubtaskComment` (lines 59-66). If the subtask is missing, the handler logs the condition and exits without creating a new subtask, ensuring creation remains tied exclusively to the reviewer assignment workflow.

### Which pull request actions are considered review-relevant?

The `updateReviewers` function in [`handler.go`](https://github.com/keitap/github-asana-request-review-action/blob/main/handler.go) (lines 101-110) treats six specific actions as review-relevant: `synchronize` (new commits), `edited` (PR metadata changes), `labeled` / `unlabeled` (tag changes), and `review_requested` / `review_request_removed` (explicit reviewer assignments). Only these actions trigger the reviewer synchronization logic that may result in subtask creation.

### Where is the core event handling logic located?

The primary event dispatch and handling logic resides in [[`handler.go`](https://github.com/keitap/github-asana-request-review-action/blob/main/handler.go)](https://github.com/keitap/github-asana-request-review-action/blob/main/handler.go), specifically within the `Handler.Handle` method (lines 35-48) and its delegates: `handlePullRequestEvent` (lines 54-60) and `handlePullRequestReviewEvent` (lines 59-66). Asana-specific API operations including subtask creation live in [`asana.go`](https://github.com/keitap/github-asana-request-review-action/blob/main/asana.go), while business-day calculations and account mappings are configured in [`config.go`](https://github.com/keitap/github-asana-request-review-action/blob/main/config.go) and [`account.go`](https://github.com/keitap/github-asana-request-review-action/blob/main/account.go).