github.com/khulnasoft/codebase@v0.0.0-20231214144635-a707781cbb24/cienv/github_actions.go (about) 1 package cienv 2 3 import ( 4 "encoding/json" 5 "errors" 6 "os" 7 ) 8 9 // https://docs.github.com/en/actions/reference/environment-variables#default-environment-variables 10 type GitHubEvent struct { 11 PullRequest GitHubPullRequest `json:"pull_request"` 12 Repository struct { 13 Owner struct { 14 Login string `json:"login"` 15 } `json:"owner"` 16 Name string `json:"name"` 17 } `json:"repository"` 18 CheckSuite struct { 19 After string `json:"after"` 20 PullRequests []GitHubPullRequest `json:"pull_requests"` 21 } `json:"check_suite"` 22 HeadCommit struct { 23 ID string `json:"id"` 24 } `json:"head_commit"` 25 ActionName string `json:"-"` // this is defined as env GITHUB_EVENT_NAME 26 } 27 28 type GitHubRepo struct { 29 Owner struct { 30 ID int64 `json:"id"` 31 } 32 } 33 34 type GitHubPullRequest struct { 35 Number int `json:"number"` 36 Head struct { 37 Sha string `json:"sha"` 38 Ref string `json:"ref"` 39 Repo GitHubRepo `json:"repo"` 40 } `json:"head"` 41 Base struct { 42 Repo GitHubRepo `json:"repo"` 43 } `json:"base"` 44 } 45 46 // LoadGitHubEvent loads GitHubEvent if it's running in GitHub Actions. 47 func LoadGitHubEvent() (*GitHubEvent, error) { 48 eventPath := os.Getenv("GITHUB_EVENT_PATH") 49 if eventPath == "" { 50 return nil, errors.New("GITHUB_EVENT_PATH not found") 51 } 52 return loadGitHubEventFromPath(eventPath) 53 } 54 55 func loadGitHubEventFromPath(eventPath string) (*GitHubEvent, error) { 56 f, err := os.Open(eventPath) 57 if err != nil { 58 return nil, err 59 } 60 defer f.Close() 61 var event GitHubEvent 62 if err := json.NewDecoder(f).Decode(&event); err != nil { 63 return nil, err 64 } 65 event.ActionName = os.Getenv("GITHUB_EVENT_NAME") 66 return &event, nil 67 } 68 69 func getBuildInfoFromGitHubAction() (*BuildInfo, bool, error) { 70 eventPath := os.Getenv("GITHUB_EVENT_PATH") 71 if eventPath == "" { 72 return nil, false, errors.New("GITHUB_EVENT_PATH not found") 73 } 74 return getBuildInfoFromGitHubActionEventPath(eventPath) 75 } 76 func getBuildInfoFromGitHubActionEventPath(eventPath string) (*BuildInfo, bool, error) { 77 event, err := loadGitHubEventFromPath(eventPath) 78 if err != nil { 79 return nil, false, err 80 } 81 info := &BuildInfo{ 82 Owner: event.Repository.Owner.Login, 83 Repo: event.Repository.Name, 84 PullRequest: event.PullRequest.Number, 85 Branch: event.PullRequest.Head.Ref, 86 SHA: event.PullRequest.Head.Sha, 87 } 88 // For re-run check_suite event. 89 if info.PullRequest == 0 && len(event.CheckSuite.PullRequests) > 0 { 90 pr := event.CheckSuite.PullRequests[0] 91 info.PullRequest = pr.Number 92 info.Branch = pr.Head.Ref 93 info.SHA = pr.Head.Sha 94 } 95 if info.SHA == "" { 96 info.SHA = event.HeadCommit.ID 97 } 98 if info.SHA == "" { 99 info.SHA = os.Getenv("GITHUB_SHA") 100 } 101 return info, info.PullRequest != 0, nil 102 } 103 104 // IsInGitHubAction returns true if codebase is running in GitHub Actions. 105 func IsInGitHubAction() bool { 106 // https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables 107 // > Always set to true when GitHub Actions is running the workflow. 108 // > You can use this variable to differentiate when tests are being run locally or by GitHub Actions. 109 return os.Getenv("GITHUB_ACTIONS") != "" 110 } 111 112 // HasReadOnlyPermissionGitHubToken returns true if codebase is running in GitHub 113 // Actions and running for PullRequests from forked repository with read-only token. 114 // https://docs.github.com/en/actions/reference/events-that-trigger-workflows#pull_request_target 115 func HasReadOnlyPermissionGitHubToken() bool { 116 event, err := LoadGitHubEvent() 117 if err != nil { 118 return false 119 } 120 isForkedRepo := event.PullRequest.Head.Repo.Owner.ID != event.PullRequest.Base.Repo.Owner.ID 121 return isForkedRepo && event.ActionName != "pull_request_target" 122 }