How Business Days Are Calculated for Review Due Dates in the GitHub-Asana Request Review Action
The action determines a review sub-task's due date by adding a configurable number of business days to the current timestamp, skipping weekends and user-defined holidays using the NextBusinessDay function implemented in date.go.
The keitap/github-asana-request-review-action automatically creates Asana sub-tasks when GitHub pull requests require review. A critical feature is its ability to set realistic due dates based on actual working days rather than calendar days. This article examines how business days are calculated for review due dates within the action's source code, detailing the algorithm that powers this scheduling logic.
Algorithm Overview
The core calculation resides in the NextBusinessDay function defined in [date.go](https://github.com/keitap/github-asana-request-review-action/blob/main/date.go). The algorithm accepts three inputs and returns a time.Time representing the target business day.
Input Parameters
n(int): The number of business days to add, configured via thedue_datesetting in your workflow YAML.base(time.Time): The starting timestamp, typicallytime.Now().holidays(map[string]bool): A map ofYYYY-MM-DDstrings representing non-working days (e.g., public holidays).
Holiday Detection Logic
The helper function isHoliday determines whether a date should be skipped. It returns true when either condition is met:
- The date exists in the
holidaysmap, or - The date falls on
time.Saturdayortime.Sunday.
Step-by-Step Execution
The algorithm executes in two distinct phases:
1. Normalize to the First Business Day
The function first ensures the calculation starts on an actual business day. If the base date is a weekend or listed holiday, the algorithm advances day-by-day until finding a valid business day:
for {
if isHoliday(base, holidays) {
base = base.AddDate(0, 0, 1)
i = 1
} else {
break
}
}
Here, i is initialized to 1 to indicate the following day when skipping occurs.
2. Count Business Days
After normalization, the function increments a counter only on valid business days, advancing the calendar day-by-day until reaching the requested count:
for {
if !isHoliday(base, holidays) {
i++
}
if n < i {
return base
}
base = base.AddDate(0, 0, 1)
}
The loop exits when the counter i exceeds the requested number n, returning the current base as the due date.
Zero-Day Offset Handling
When n equals 0, the function returns the most recent business day on or before the original base date. Due to the initial normalization loop, a weekend or holiday start date gets bumped forward to the next business day, and since i (set to 1) immediately exceeds n (0), that date is returned instantly.
Core Implementation in date.go
The NextBusinessDay function in date.go implements the complete business day calculation logic. This file also contains the isHoliday helper that checks both the custom holidays map and the day of week. The function uses time.AddDate(0, 0, 1) for day advancement, ensuring proper handling of month and year boundaries without manual calendar math.
Integration with Asana Task Creation
The calculated date is applied when creating review sub-tasks in [handler.go](https://github.com/keitap/github-asana-request-review-action/blob/main/handler.go). The handler retrieves configuration values from the Config struct (defined in [config.go](https://github.com/keitap/github-asana-request-review-action/blob/main/config.go)) and passes them to the business day function:
// In handler.go
due := asana.Date(NextBusinessDay(h.conf.DueDate, time.Now(), h.conf.Holidays))
h.conf.DueDateprovides the integer offset (default 1)h.conf.Holidayscontains the map of excluded dates loaded from the action's configuration
Configuration Options
According to the repository's [README.md](https://github.com/keitap/github-asana-request-review-action/blob/main/README.md), users control the calculation through two configuration fields:
due_date: Integer specifying how many business days to add to the current date. Defaults to 1 if unspecified.holidays: Array ofYYYY-MM-DDstrings representing additional non-working days beyond weekends.
Example configuration:
- uses: keitap/github-asana-request-review-action@main
with:
due_date: 3
holidays: |
2024-12-25
2024-12-26
2025-01-01
Practical Usage Example
You can leverage the NextBusinessDay function directly in custom Go applications importing this action:
package main
import (
"fmt"
"time"
"github.com/keitap/github-asana-request-review-action"
)
func main() {
holidays := map[string]bool{
"2024-12-25": true,
"2024-01-01": true,
}
// Calculate 3 business days from now
due := githubasana.NextBusinessDay(3, time.Now(), holidays)
fmt.Println("Review due:", due.Format("2006-01-02"))
}
This returns a timestamp representing the third business day after today, excluding weekends and the specified Christmas and New Year's dates.
Summary
- The business day calculation resides in the
NextBusinessDayfunction insidedate.go, which adds configurable working days to the current date while excluding weekends and custom holidays. - The algorithm first normalizes the start date to the next valid business day, then iterates through the calendar counting only valid workdays until reaching the requested offset.
- Holiday detection combines a user-provided
YYYY-MM-DDmap with standard weekend checks (time.Saturdayandtime.Sunday). - When the offset is zero, the function returns the most recent business day on or before the start date (after normalizing from weekends/holidays).
- The handler in
handler.gointegrates this calculation when setting Asana sub-task due dates, using configuration fromconfig.gofor the offset and holiday list.
Frequently Asked Questions
How does the action handle weekends when calculating review due dates?
The isHoliday helper function in date.go automatically identifies Saturdays and Sundays using Go's time.Saturday and time.Sunday constants. These days are skipped during the counting loop, ensuring the final due date always falls on a weekday unless explicitly defined as a holiday.
Can I configure specific public holidays to be excluded from the calculation?
Yes. The action accepts a holidays configuration parameter containing a list of YYYY-MM-DD formatted dates. These are stored in a map[string]bool and checked by the isHoliday function alongside weekend detection, allowing you to exclude any non-working days specific to your organization or country.
What happens if I set the due_date to 0 in the configuration?
When n equals 0, the NextBusinessDay function returns the most recent business day on or before the current date. If today is a weekend or holiday, the normalization loop first advances to the next business day, then immediately returns that date because the internal counter (initialized to 1) exceeds the target of 0.
Where in the codebase is the due date actually assigned to the Asana task?
The due date assignment occurs in handler.go, specifically where the handler constructs the Asana sub-task. It calls NextBusinessDay with the configured offset and holiday map, converts the result using asana.Date(), and attaches this timestamp to the newly created review request task.
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 →