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) }