sdk/context.go

189 lines
5.1 KiB
Go

package sdk
import (
"encoding/json"
"errors"
"fmt"
"os"
"strconv"
)
// GitHubContext of current workflow.
// See: https://docs.github.com/en/actions/learn-github-actions/environment-variables
type GitHubContext struct {
Action string `env:"GITHUB_ACTION"`
ActionPath string `env:"GITHUB_ACTION_PATH"`
ActionRepository string `env:"GITHUB_ACTION_REPOSITORY"`
Actions bool `env:"GITHUB_ACTIONS"`
Actor string `env:"GITHUB_ACTOR"`
APIURL string `env:"GITHUB_API_URL,default=https://api.github.com"`
BaseRef string `env:"GITHUB_BASE_REF"`
Env string `env:"GITHUB_ENV"`
EventName string `env:"GITHUB_EVENT_NAME"`
EventPath string `env:"GITHUB_EVENT_PATH"`
GraphqlURL string `env:"GITHUB_GRAPHQL_URL,default=https://api.github.com/graphql"`
HeadRef string `env:"GITHUB_HEAD_REF"`
Job string `env:"GITHUB_JOB"`
Path string `env:"GITHUB_PATH"`
Ref string `env:"GITHUB_REF"`
RefName string `env:"GITHUB_REF_NAME"`
RefProtected bool `env:"GITHUB_REF_PROTECTED"`
RefType string `env:"GITHUB_REF_TYPE"`
Repository string `env:"GITHUB_REPOSITORY"`
RepositoryOwner string `env:"GITHUB_REPOSITORY_OWNER"`
RetentionDays int64 `env:"GITHUB_RETENTION_DAYS"`
RunAttempt int64 `env:"GITHUB_RUN_ATTEMPT"`
RunID int64 `env:"GITHUB_RUN_ID"`
RunNumber int64 `env:"GITHUB_RUN_NUMBER"`
ServerURL string `env:"GITHUB_SERVER_URL,default=https://github.com"`
SHA string `env:"GITHUB_SHA"`
StepSummary string `env:"GITHUB_STEP_SUMMARY"`
Workflow string `env:"GITHUB_WORKFLOW"`
Workspace string `env:"GITHUB_WORKSPACE"`
// Event is populated by parsing the file at EventPath, if it exists.
Event map[string]any
}
// Context returns the context of current action with the payload object
// that triggered the workflow
func (c *Action) Context() (*GitHubContext, error) {
var merr error
context := &GitHubContext{
APIURL: "https://api.github.com",
GraphqlURL: "https://api.github.com/graphql",
ServerURL: "https://github.com",
}
if v := c.env("GITHUB_ACTION"); v != "" {
context.Action = v
}
if v := c.env("GITHUB_ACTION_PATH"); v != "" {
context.ActionPath = v
}
if v := c.env("GITHUB_ACTION_REPOSITORY"); v != "" {
context.ActionRepository = v
}
if v, err := parseBool(c.env("GITHUB_ACTIONS")); err == nil {
context.Actions = v
} else {
merr = errors.Join(merr, err)
}
if v := c.env("GITHUB_ACTOR"); v != "" {
context.Actor = v
}
if v := c.env("GITHUB_API_URL"); v != "" {
context.APIURL = v
}
if v := c.env("GITHUB_BASE_REF"); v != "" {
context.BaseRef = v
}
if v := c.env("GITHUB_ENV"); v != "" {
context.Env = v
}
if v := c.env("GITHUB_EVENT_NAME"); v != "" {
context.EventName = v
}
if v := c.env("GITHUB_EVENT_PATH"); v != "" {
context.EventPath = v
}
if v := c.env("GITHUB_GRAPHQL_URL"); v != "" {
context.GraphqlURL = v
}
if v := c.env("GITHUB_HEAD_REF"); v != "" {
context.HeadRef = v
}
if v := c.env("GITHUB_JOB"); v != "" {
context.Job = v
}
if v := c.env("GITHUB_PATH"); v != "" {
context.Path = v
}
if v := c.env("GITHUB_REF"); v != "" {
context.Ref = v
}
if v := c.env("GITHUB_REF_NAME"); v != "" {
context.RefName = v
}
if v, err := parseBool(c.env("GITHUB_REF_PROTECTED")); err == nil {
context.RefProtected = v
} else {
merr = errors.Join(merr, err)
}
if v := c.env("GITHUB_REF_TYPE"); v != "" {
context.RefType = v
}
if v := c.env("GITHUB_REPOSITORY"); v != "" {
context.Repository = v
}
if v := c.env("GITHUB_REPOSITORY_OWNER"); v != "" {
context.RepositoryOwner = v
}
if v, err := parseInt(c.env("GITHUB_RETENTION_DAYS")); err == nil {
context.RetentionDays = v
} else {
merr = errors.Join(merr, err)
}
if v, err := parseInt(c.env("GITHUB_RUN_ATTEMPT")); err == nil {
context.RunAttempt = v
} else {
merr = errors.Join(merr, err)
}
if v, err := parseInt(c.env("GITHUB_RUN_ID")); err == nil {
context.RunID = v
} else {
merr = errors.Join(merr, err)
}
if v, err := parseInt(c.env("GITHUB_RUN_NUMBER")); err == nil {
context.RunNumber = v
} else {
merr = errors.Join(merr, err)
}
if v := c.env("GITHUB_SERVER_URL"); v != "" {
context.ServerURL = v
}
if v := c.env("GITHUB_SHA"); v != "" {
context.SHA = v
}
if v := c.env("GITHUB_STEP_SUMMARY"); v != "" {
context.StepSummary = v
}
if v := c.env("GITHUB_WORKFLOW"); v != "" {
context.Workflow = v
}
if v := c.env("GITHUB_WORKSPACE"); v != "" {
context.Workspace = v
}
if context.EventPath != "" {
eventData, err := os.ReadFile(context.EventPath)
if err != nil && !os.IsNotExist(err) {
return nil, fmt.Errorf("could not read event file: %w", err)
}
if eventData != nil {
if err := json.Unmarshal(eventData, &context.Event); err != nil {
return nil, fmt.Errorf("failed to unmarshal event payload: %w", err)
}
}
}
return context, merr
}
func parseBool(v string) (bool, error) {
if v == "" {
return false, nil
}
return strconv.ParseBool(v)
}
func parseInt(v string) (int64, error) {
if v == "" {
return 0, nil
}
return strconv.ParseInt(v, 10, 64)
}