How the GitHub‑Asana Action Handles Bot Users as Pull‑Request Authors
When a GitHub bot authors a pull request, the action automatically substitutes the bot's identity with the human assignee to ensure Asana tasks and comments are attributed to a real user account.
The keitap/github-asana-request-review-action bridges GitHub code reviews with Asana task management, but automated pull requests from services like Dependabot present a unique challenge: bots lack Asana accounts. To handle bot users as pull request authors effectively, the action implements a fallback mechanism that delegates accountability to the assigned human reviewer.
Bot Detection Logic in handler.go
The action identifies automated authors in handler.go through the getAssigneeOrRequester method. This function inspects the User.Type field of the GitHub API response to distinguish between human and machine accounts.
// https://github.com/keitap/github-asana-request-review-action/blob/main/handler.go#L69-L90
func (h *Handler) getAssigneeOrRequester(pr *github.PullRequestReviewEvent) (requester *Account, err error) {
// 1️⃣ Detect a bot author and a non‑nil assignee.
if pr.PullRequest.User.GetType() == "Bot" && pr.PullRequest.Assignee != nil {
log.Printf("pull request user is a bot: %s", pr.PullRequest.User.GetLogin())
// 2️⃣ Fetch the Asana account for the assignee instead of the bot.
requester, err = h.fetchAccount(pr.PullRequest.Assignee.GetLogin())
if err != nil {
return nil, fmt.Errorf(": %w", err)
}
return requester, nil
}
// 3️⃣ Normal case – the author is a human; fetch their account directly.
requester, err = h.fetchAccount(pr.PullRequest.User.GetLogin())
if err != nil {
return nil, fmt.Errorf(": %w", err)
}
return requester, nil
}
Identifying GitHub Bot Accounts
The condition pr.PullRequest.User.GetType() == "Bot" targets the User.Type property returned by GitHub's REST API. Automated accounts—including Dependabot, GitHub Actions, and third-party integration bots—return the literal string "Bot" in this field, while human users return "User".
The Assignee Fallback Strategy
When the bot detection condition succeeds, the action verifies that pr.PullRequest.Assignee != nil. If a human assignee exists, the system logs the bot detection via log.Printf and immediately pivots to h.fetchAccount(pr.PullRequest.Assignee.GetLogin()). This ensures the subsequent Asana sub-tasks and review comments are linked to the assignee's Asana identity rather than the bot's unmapped login.
Account Resolution Through fetchAccount
After determining the effective requester, the action resolves the GitHub username to an Asana GID through the fetchAccount helper. This method queries the Config.Accounts map defined in config.go, which stores the deliberate mapping between GitHub logins and Asana user identifiers.
If the login—whether the original author or the fallback assignee—lacks a configured mapping, fetchAccount returns a NoAsanaAccount placeholder. This graceful degradation prevents the action from failing while clearly flagging unmapped users in the workflow logs.
Practical Implementation Example
The following Go example demonstrates how the action processes a PullRequestReviewEvent where Dependabot is the PR author:
package main
import (
"log"
"github.com/google/go-github/v74/github"
"github.com/keitap/github-asana-request-review-action"
)
func main() {
// Mock a PullRequestReviewEvent where the PR author is a bot.
pr := &github.PullRequest{
User: &github.User{
Login: github.String("dependabot[bot]"),
Type: github.String("Bot"),
},
Assignee: &github.User{
Login: github.String("alice"),
},
// body would contain the Asana task link in a real PR.
}
event := &github.PullRequestReviewEvent{
PullRequest: pr,
Repo: &github.Repository{}, // omitted for brevity
}
// Assume we have already built a Handler with config, Asana, and GitHub clients.
h := githubasana.NewHandler(config, asanaClient, githubClient)
// The handler automatically resolves the requester (alice) instead of the bot.
if err := h.handlePullRequestReviewEvent(event); err != nil {
log.Fatalf("failed: %v", err)
}
}
When executed with proper client configuration, this workflow attributes all generated Asana actions to alice while logging the detection of dependabot[bot] in the runner logs.
Summary
- The action detects bot authors by checking if
User.Type == "Bot"in the GitHub API response. - When a bot is detected and an assignee exists, the system automatically substitutes the assignee's identity for the bot's login.
- The
fetchAccountmethod inhandler.goresolves the effective username to an Asana GID using the repository's configuration mapping. - Unmapped users receive a
NoAsanaAccountplaceholder, ensuring the workflow continues without failure. - This logic is implemented in the
getAssigneeOrRequestermethod withinhandler.go, with supporting configuration inconfig.goandaccount.go.
Frequently Asked Questions
What happens if a bot authors a PR but no assignee is set?
If pr.PullRequest.Assignee is nil when a bot is detected, the action falls through to the default path and attempts to fetch the account for the bot's login directly. Since bots lack Asana mappings, this typically returns a NoAsanaAccount placeholder, and the Asana task creation proceeds without a specific requester attribution.
Does the action support all GitHub bot types?
Yes. The implementation relies on the GitHub API's User.Type field rather than hardcoded bot names. Any automated account—whether Dependabot, GitHub Actions, or third-party integration bots—that returns "Bot" in the type field triggers the fallback logic automatically.
Where is the GitHub-to-Asana user mapping configured?
The mapping is defined in config.go within the Config.Accounts structure. Repository maintainers must explicitly configure which GitHub usernames correspond to which Asana GIDs; the fetchAccount method references this configuration when resolving requesters and reviewers.
How does the action log bot detection events?
When the getAssigneeOrRequester method detects a bot author, it emits a log message via log.Printf stating "pull request user is a bot: %s" followed by the bot's login. This appears in the GitHub Actions workflow logs, providing transparency about when the assignee fallback mechanism activates.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →