Asana API Operations to Create, Update, and Find Subtasks: A Go Implementation Guide

TLDR: The keitap/github-asana-request-review-action uses client.CreateTask to create subtasks, subtask.Update to update them, and task.Subtasks to find them, wrapped in three helper functions defined in asana.go.

Managing code review workflows between GitHub and Asana requires precise subtask operations through the Asana API. The open-source keitap/github-asana-request-review-action implements dedicated Go functions to create, update, and find subtasks using the official Asana Go SDK. This guide breaks down the specific API operations and implementation details found in the source code.

Creating Subtasks with client.CreateTask

The action creates review subtasks via the AddCodeReviewSubtask function defined at lines 73-86 of asana.go. This function constructs a CreateTaskRequest struct containing the parent task ID, assignee, followers, due date, and formatted HTML notes.

The AddCodeReviewSubtask Implementation

func AddCodeReviewSubtask(client *asana.Client, taskID string, prID int,
    requester *Account, reviewer *Account, dueDate asana.Date,
    pr *github.PullRequestEvent) (*asana.Task, error) {
    req := &asana.CreateTaskRequest{
        Parent:    taskID,
        Assignee:  reviewer.AsanaUserGID,
        Followers: []string{requester.AsanaUserGID},
        TaskBase: asana.TaskBase{
            Name:      fmt.Sprintf(`✍️ Code review: #%d %s`, prID, reviewer),
            HTMLNotes: createReviewRequestDescText(requester, pr),
            DueOn:     &dueDate,
        },
    }
    return client.CreateTask(req)
}

Updating Subtasks with subtask.Update

To modify existing subtasks, the action uses UpdateCodeReviewSubtask at lines 88-96 of asana.go. This function sends an UpdateTaskRequest to modify specific fields without affecting other subtask properties.

The UpdateCodeReviewSubtask Function

func UpdateCodeReviewSubtask(client *asana.Client,
    subtask *asana.Task, requester *Account,
    pr *github.PullRequestEvent) error {
    update := &asana.UpdateTaskRequest{
        TaskBase: asana.TaskBase{
            HTMLNotes: createReviewRequestDescText(requester, pr),
        },
    }
    return subtask.Update(client, update)
}

Finding Subtasks with task.Subtasks

The search operation uses FindSubtaskByName at lines 98-115 of asana.go. This function retrieves up to 100 subtasks from a parent task and filters them by name substring.

The FindSubtaskByName Logic

func FindSubtaskByName(client *asana.Client,
    taskID string, findString string) (*asana.Task, error) {
    task := &asana.Task{ID: taskID}
    subtasks, _, err := task.Subtasks(client, &asana.Options{Limit: 100})
    if err != nil {
        return nil, err
    }
    for _, s := range subtasks {
        if strings.Contains(s.Name, findString) {
            return s, nil
        }
    }
    return nil, nil
}

Integration with the Main Handler

These helper functions are invoked by the main event handler in handler.go when processing GitHub pull request events. The Account struct defined in account.go provides the necessary Asana user GIDs for assignee and follower fields.

Summary

  • Create: Uses client.CreateTask via AddCodeReviewSubtask in asana.go (lines 73-86) to create subtasks with parent relationships, assignees, and due dates.
  • Update: Uses subtask.Update via UpdateCodeReviewSubtask in asana.go (lines 88-96) to modify HTML notes of existing subtasks.
  • Find: Uses task.Subtasks via FindSubtaskByName in asana.go (lines 98-115) to retrieve and filter subtasks by name substring with a limit of 100 results.
  • All operations depend on the Account struct from account.go for user GID management.

Frequently Asked Questions

Which Asana API operations are used to create, update, and find subtasks?

The action uses client.CreateTask for creation, subtask.Update for updates, and task.Subtasks for retrieval. These are wrapped in the AddCodeReviewSubtask, UpdateCodeReviewSubtask, and FindSubtaskByName functions respectively, all defined in asana.go.

How does the action prevent duplicate review subtasks?

Before creating a new subtask, the code calls FindSubtaskByName to search existing subtasks by reviewer login name. If a matching subtask exists, the action updates it rather than creating a duplicate.

What parameters are required when creating a code review subtask?

The AddCodeReviewSubtask function requires the Asana client, parent task ID, PR number, requester account, reviewer account, due date, and the pull request event object. These parameters populate the CreateTaskRequest struct with assignee GIDs, follower IDs, and formatted task metadata.

How does the UpdateCodeReviewSubtask function handle partial updates?

It constructs an UpdateTaskRequest containing only the HTMLNotes field in the TaskBase struct. The Asana SDK's subtask.Update method sends this partial object, leaving other fields unchanged.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →