How Pull Request Labels Are Displayed in Asana Task Comments: A Code Deep Dive

The GitHub Action renders pull request labels as bold-hashtagged items (e.g., #<b>bug</b>) inside HTML Asana comments by using the getLabelsText helper function in asana.go.

The keitap/github-asana-request-review-action bridges GitHub and Asana by automatically syncing pull request metadata to task comments. When labels are applied to a PR, the action extracts them using a specific formatting pipeline that converts GitHub label objects into searchable, visually distinct HTML elements within Asana's rich text body.

How Labels Are Extracted and Formatted in asana.go

The core logic for label display resides in asana.go, where the getLabelsText function handles extraction, formatting, and sorting.

The getLabelsText Function Implementation

Located at lines 214–226, this function receives a github.PullRequestEvent and iterates over the Labels slice to build a formatted string:

func getLabelsText(pr *github.PullRequestEvent) string {
    labels := make([]string, 0, len(pr.PullRequest.Labels))
    for _, l := range pr.PullRequest.Labels {
        labels = append(labels, fmt.Sprintf("#<b>%s</b>", l.GetName()))
    }
    if len(labels) == 0 {
        return ""
    }
    sort.Strings(labels)
    return "Labels: " + strings.Join(labels, ", ")
}

Each label name is wrapped in HTML bold tags (<b>) and prefixed with a hash symbol, producing output like #<b>bug</b> or #<b>frontend</b>.

Sorting and Joining Logic

After collecting labels into a slice, the function applies alphabetical sorting using Go's sort.Strings utility. The sorted slice is then joined with comma separators and prefixed with the literal string Labels: . If the pull request contains no labels, the function returns an empty string, ensuring no Labels line appears in the final comment.

Where Labels Appear in Asana Task Comments

The formatted label string is embedded into Asana task comments by two primary functions in asana.go: createPullRequestCommentText (lines 92–96) and createReviewRequestDescText. Both functions call getLabelsText and inject its return value directly into the HTML body.

Comment Template Integration

When createPullRequestCommentText constructs the initial PR comment, it concatenates the label output alongside other metadata such as PR state, file change counts, and author information. The insertion point occurs after the changed-files summary, creating a consistent visual hierarchy.

HTML Output Structure

The resulting HTML sent to Asana's API follows this pattern:

<body>
📋 <code>[<b>open</b>] <a href="https://github.com/example/repo/pull/42">Pull request #42: Fix login bug</a> by <a href="https://github.com/example">example</a>

<b>12</b> changed files (<b>+30 -5</b>)
Labels: #<b>bug</b>, #<b>frontend</b>

#github-asana-request-review</code></body>

The Labels: line appears immediately after the file statistics, with each label rendered as a bold, clickable-looking entity due to the hash-bold combination.

Event Handling Flow from GitHub to Asana

The orchestration begins in handler.go, which processes incoming pull_request webhooks. When a label is added, removed, or the PR is opened, the handler invokes the Asana helper functions.

Because getLabelsText operates on the current state of pr.PullRequest.Labels, any label modifications trigger an updated comment that reflects the latest set of labels. The alphabetical sorting ensures consistent ordering across edits, preventing duplicate comment noise from reordering.

Summary

  • Label extraction occurs in asana.go via getLabelsText (lines 214–226), which iterates over pr.PullRequest.Labels.
  • Formatting wraps each label as #<b>name</b> and sorts them alphabetically before joining with commas.
  • Embedding happens through createPullRequestCommentText (lines 92–96) and createReviewRequestDescText, which inject the result into the HTML comment body.
  • Conditional rendering returns an empty string for label-less PRs, omitting the Labels line entirely.
  • Visual output displays as Labels: #<b>bug</b>, #<b>frontend</b> within the Asana task description.

Frequently Asked Questions

What format do pull request labels use in Asana comments?

Labels appear as hash-prefixed, bold-wrapped text within an HTML <code> block. The specific pattern is #<b>label-name</b>, with multiple labels separated by commas and prefixed by Labels: . This format makes labels visually distinct from other PR metadata like file counts or author names.

Where in the codebase are PR labels converted to Asana text?

The conversion happens in asana.go inside the getLabelsText function at lines 214–226. This helper is called by createPullRequestCommentText (lines 92–96) and createReviewRequestDescText to generate the label segment before final comment assembly.

Do labels appear in Asana if the pull request has none attached?

No. When len(pr.PullRequest.Labels) equals zero, getLabelsText returns an empty string. Consequently, the comment template receives no label content, and the Labels line is omitted from the Asana task comment entirely rather than displaying Labels: with no values.

Are the labels sorted in any particular order?

Yes, alphabetically in ascending order. The implementation uses Go's standard sort.Strings function on the slice of formatted label strings before joining them. This ensures that regardless of how labels are ordered in the GitHub event, they always appear in consistent A–Z order in the Asana comment.

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 →