From 2513709089ca20ceb95ed910c7396534baae3fc9 Mon Sep 17 00:00:00 2001 From: Praneet Loke <1466314+praneetloke@users.noreply.github.com> Date: Mon, 15 Jun 2020 12:49:09 -0700 Subject: [PATCH] Use the GH webhook payload to parse PR details when CI system is GH Actions (#4817) * Read the file and parse it. Also use the PR Head SHA instead of the GITHUB_REF if the build type is pull_request. * Update changelog --- CHANGELOG.md | 3 ++ sdk/go/common/util/ciutil/github_actions.go | 52 ++++++++++++++++----- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5eb715243..5da921887 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,9 @@ CHANGELOG - Fix `pylint(no-member)` when accessing `resource.id`. [#4813](https://github.com/pulumi/pulumi/pull/4813) +- Fix GitHub Actions environment detection for PRs. + [#4817](https://github.com/pulumi/pulumi/pull/4817) + ## 2.4.0 (2020-06-10) - Turn program generation NYIs into diagnostic errors [#4794](https://github.com/pulumi/pulumi/pull/4794) diff --git a/sdk/go/common/util/ciutil/github_actions.go b/sdk/go/common/util/ciutil/github_actions.go index 9d91d0682..1ff18ec79 100644 --- a/sdk/go/common/util/ciutil/github_actions.go +++ b/sdk/go/common/util/ciutil/github_actions.go @@ -17,6 +17,7 @@ package ciutil import ( "encoding/json" "fmt" + "io/ioutil" "os" "strconv" ) @@ -26,45 +27,72 @@ type githubActionsCI struct { baseCI } +type githubPRHead struct { + SHA string `json:"sha"` + Ref string `json:"ref"` +} + // githubPR represents the `pull_request` payload posted by GitHub to trigger // workflows for PRs. Note that this is only a partial representation as we // don't need anything other than the PR number. // See https://developer.github.com/webhooks/event-payloads/#pull_request. type githubPR struct { - Action string `json:"action"` - Number int64 `json:"number"` + Head githubPRHead `json:"head"` } // githubActionsPullRequestEvent represents the webhook payload for a pull_request event. // https://help.github.com/en/actions/reference/events-that-trigger-workflows#pull-request-event-pull_request type githubActionsPullRequestEvent struct { + Action string `json:"action"` + Number int64 `json:"number"` PullRequest githubPR `json:"pull_request"` } // DetectVars detects the GitHub Actions env vars. -// nolint: lll -// See https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables. +// See https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables. func (t githubActionsCI) DetectVars() Vars { v := Vars{Name: GitHubActions} v.BuildID = os.Getenv("GITHUB_RUN_ID") v.BuildNumber = os.Getenv("GITHUB_RUN_NUMBER") v.BuildType = os.Getenv("GITHUB_EVENT_NAME") - v.SHA = os.Getenv("GITHUB_SHA") v.BranchName = os.Getenv("GITHUB_REF") repoSlug := os.Getenv("GITHUB_REPOSITORY") if repoSlug != "" && v.BuildID != "" { v.BuildURL = fmt.Sprintf("https://github.com/%s/actions/runs/%s", repoSlug, v.BuildID) } - // Try to use the pull_request webhook payload to extract the PR number. - // For Pull Requests, GitHub stores the payload of the webhook that triggered the - // workflow in a path. The path is identified by GITHUB_EVENT_PATH. + v.SHA = os.Getenv("GITHUB_SHA") if v.BuildType == "pull_request" { - eventPath := os.Getenv("GITHUB_EVENT_PATH") - var prEvent githubActionsPullRequestEvent - if err := json.Unmarshal([]byte(eventPath), &prEvent); err == nil { - v.PRNumber = strconv.FormatInt(prEvent.PullRequest.Number, 10) + event := t.GetPREvent() + if event != nil { + prNumber := strconv.FormatInt(event.Number, 10) + v.PRNumber = prNumber + v.SHA = event.PullRequest.Head.SHA + v.BranchName = event.PullRequest.Head.Ref } } return v } + +// TryGetEvent returns the GitHub webhook payload found in the GitHub Actions environment. +// GitHub stores the JSON payload of the webhook that triggered the workflow in a path. +// The path is set as the value of the env var GITHUB_EVENT_PATH. Returns nil if an error +// is encountered or the GITHUB_EVENT_PATH is not set. +func (t githubActionsCI) GetPREvent() *githubActionsPullRequestEvent { + eventPath := os.Getenv("GITHUB_EVENT_PATH") + if eventPath == "" { + return nil + } + + b, err := ioutil.ReadFile(eventPath) + if err != nil { + return nil + } + + var prEvent githubActionsPullRequestEvent + if err := json.Unmarshal(b, &prEvent); err != nil { + return nil + } + + return &prEvent +}