summaryrefslogtreecommitdiffstats
path: root/pkg/model/github_context.go
diff options
context:
space:
mode:
authorDaniel Baumann <daniel@debian.org>2024-10-20 23:07:42 +0200
committerDaniel Baumann <daniel@debian.org>2024-11-09 15:38:42 +0100
commit714c83b2736d7e308bc33c49057952490eb98be2 (patch)
tree1d9ba7035798368569cd49056f4d596efc908cd8 /pkg/model/github_context.go
parentInitial commit. (diff)
downloadforgejo-act-debian.tar.xz
forgejo-act-debian.zip
Adding upstream version 1.21.4.HEADupstream/1.21.4upstreamdebian
Signed-off-by: Daniel Baumann <daniel@debian.org>
Diffstat (limited to 'pkg/model/github_context.go')
-rw-r--r--pkg/model/github_context.go213
1 files changed, 213 insertions, 0 deletions
diff --git a/pkg/model/github_context.go b/pkg/model/github_context.go
new file mode 100644
index 0000000..71221a5
--- /dev/null
+++ b/pkg/model/github_context.go
@@ -0,0 +1,213 @@
+package model
+
+import (
+ "context"
+ "fmt"
+ "strings"
+
+ "github.com/nektos/act/pkg/common"
+ "github.com/nektos/act/pkg/common/git"
+)
+
+type GithubContext struct {
+ Event map[string]interface{} `json:"event"`
+ EventPath string `json:"event_path"`
+ Workflow string `json:"workflow"`
+ RunID string `json:"run_id"`
+ RunNumber string `json:"run_number"`
+ Actor string `json:"actor"`
+ Repository string `json:"repository"`
+ EventName string `json:"event_name"`
+ Sha string `json:"sha"`
+ Ref string `json:"ref"`
+ RefName string `json:"ref_name"`
+ RefType string `json:"ref_type"`
+ HeadRef string `json:"head_ref"`
+ BaseRef string `json:"base_ref"`
+ Token string `json:"token"`
+ Workspace string `json:"workspace"`
+ Action string `json:"action"`
+ ActionPath string `json:"action_path"`
+ ActionRef string `json:"action_ref"`
+ ActionRepository string `json:"action_repository"`
+ Job string `json:"job"`
+ JobName string `json:"job_name"`
+ RepositoryOwner string `json:"repository_owner"`
+ RetentionDays string `json:"retention_days"`
+ RunnerPerflog string `json:"runner_perflog"`
+ RunnerTrackingID string `json:"runner_tracking_id"`
+ ServerURL string `json:"server_url"`
+ APIURL string `json:"api_url"`
+ GraphQLURL string `json:"graphql_url"`
+}
+
+func asString(v interface{}) string {
+ if v == nil {
+ return ""
+ } else if s, ok := v.(string); ok {
+ return s
+ }
+ return ""
+}
+
+func nestedMapLookup(m map[string]interface{}, ks ...string) (rval interface{}) {
+ var ok bool
+
+ if len(ks) == 0 { // degenerate input
+ return nil
+ }
+ if rval, ok = m[ks[0]]; !ok {
+ return nil
+ } else if len(ks) == 1 { // we've reached the final key
+ return rval
+ } else if m, ok = rval.(map[string]interface{}); !ok {
+ return nil
+ } else { // 1+ more keys
+ return nestedMapLookup(m, ks[1:]...)
+ }
+}
+
+func withDefaultBranch(ctx context.Context, b string, event map[string]interface{}) map[string]interface{} {
+ repoI, ok := event["repository"]
+ if !ok {
+ repoI = make(map[string]interface{})
+ }
+
+ repo, ok := repoI.(map[string]interface{})
+ if !ok {
+ common.Logger(ctx).Warnf("unable to set default branch to %v", b)
+ return event
+ }
+
+ // if the branch is already there return with no changes
+ if _, ok = repo["default_branch"]; ok {
+ return event
+ }
+
+ repo["default_branch"] = b
+ event["repository"] = repo
+
+ return event
+}
+
+var findGitRef = git.FindGitRef
+var findGitRevision = git.FindGitRevision
+
+func (ghc *GithubContext) SetRef(ctx context.Context, defaultBranch string, repoPath string) {
+ logger := common.Logger(ctx)
+
+ // https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows
+ // https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads
+ switch ghc.EventName {
+ case "pull_request_target":
+ ghc.Ref = fmt.Sprintf("refs/heads/%s", ghc.BaseRef)
+ case "pull_request", "pull_request_review", "pull_request_review_comment":
+ ghc.Ref = fmt.Sprintf("refs/pull/%.0f/merge", ghc.Event["number"])
+ case "deployment", "deployment_status":
+ ghc.Ref = asString(nestedMapLookup(ghc.Event, "deployment", "ref"))
+ case "release":
+ ghc.Ref = fmt.Sprintf("refs/tags/%s", asString(nestedMapLookup(ghc.Event, "release", "tag_name")))
+ case "push", "create", "workflow_dispatch":
+ ghc.Ref = asString(ghc.Event["ref"])
+ default:
+ defaultBranch := asString(nestedMapLookup(ghc.Event, "repository", "default_branch"))
+ if defaultBranch != "" {
+ ghc.Ref = fmt.Sprintf("refs/heads/%s", defaultBranch)
+ }
+ }
+
+ if ghc.Ref == "" {
+ ref, err := findGitRef(ctx, repoPath)
+ if err != nil {
+ logger.Warningf("unable to get git ref: %v", err)
+ } else {
+ logger.Debugf("using github ref: %s", ref)
+ ghc.Ref = ref
+ }
+
+ // set the branch in the event data
+ if defaultBranch != "" {
+ ghc.Event = withDefaultBranch(ctx, defaultBranch, ghc.Event)
+ } else {
+ ghc.Event = withDefaultBranch(ctx, "master", ghc.Event)
+ }
+
+ if ghc.Ref == "" {
+ ghc.Ref = fmt.Sprintf("refs/heads/%s", asString(nestedMapLookup(ghc.Event, "repository", "default_branch")))
+ }
+ }
+}
+
+func (ghc *GithubContext) SetSha(ctx context.Context, repoPath string) {
+ logger := common.Logger(ctx)
+
+ // https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows
+ // https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads
+ switch ghc.EventName {
+ case "pull_request_target":
+ ghc.Sha = asString(nestedMapLookup(ghc.Event, "pull_request", "base", "sha"))
+ case "deployment", "deployment_status":
+ ghc.Sha = asString(nestedMapLookup(ghc.Event, "deployment", "sha"))
+ case "push", "create", "workflow_dispatch":
+ if deleted, ok := ghc.Event["deleted"].(bool); ok && !deleted {
+ ghc.Sha = asString(ghc.Event["after"])
+ }
+ }
+
+ if ghc.Sha == "" {
+ _, sha, err := findGitRevision(ctx, repoPath)
+ if err != nil {
+ logger.Warningf("unable to get git revision: %v", err)
+ } else {
+ ghc.Sha = sha
+ }
+ }
+}
+
+func (ghc *GithubContext) SetRepositoryAndOwner(ctx context.Context, githubInstance string, remoteName string, repoPath string) {
+ if ghc.Repository == "" {
+ repo, err := git.FindGithubRepo(ctx, repoPath, githubInstance, remoteName)
+ if err != nil {
+ common.Logger(ctx).Warningf("unable to get git repo (githubInstance: %v; remoteName: %v, repoPath: %v): %v", githubInstance, remoteName, repoPath, err)
+ return
+ }
+ ghc.Repository = repo
+ }
+ ghc.RepositoryOwner = strings.Split(ghc.Repository, "/")[0]
+}
+
+func (ghc *GithubContext) SetRefTypeAndName() {
+ var refType, refName string
+
+ // https://docs.github.com/en/actions/learn-github-actions/environment-variables
+ if strings.HasPrefix(ghc.Ref, "refs/tags/") {
+ refType = "tag"
+ refName = ghc.Ref[len("refs/tags/"):]
+ } else if strings.HasPrefix(ghc.Ref, "refs/heads/") {
+ refType = "branch"
+ refName = ghc.Ref[len("refs/heads/"):]
+ } else if strings.HasPrefix(ghc.Ref, "refs/pull/") {
+ refType = ""
+ refName = ghc.Ref[len("refs/pull/"):]
+ }
+
+ if ghc.RefType == "" {
+ ghc.RefType = refType
+ }
+
+ if ghc.RefName == "" {
+ ghc.RefName = refName
+ }
+}
+
+func (ghc *GithubContext) SetBaseAndHeadRef() {
+ if ghc.EventName == "pull_request" || ghc.EventName == "pull_request_target" {
+ if ghc.BaseRef == "" {
+ ghc.BaseRef = asString(nestedMapLookup(ghc.Event, "pull_request", "base", "ref"))
+ }
+
+ if ghc.HeadRef == "" {
+ ghc.HeadRef = asString(nestedMapLookup(ghc.Event, "pull_request", "head", "ref"))
+ }
+ }
+}