From bd8fefb63a0d7a2902cbfffe25503c00b8d2aa32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Th=C3=B6mmes?= Date: Tue, 24 Sep 2024 08:53:30 +0200 Subject: [PATCH] Extract PR number from event instead of using RefName On normal pull-request events, the `RefName` attribute is usually `$prNumber/merge`. However, when **merging** a pull-request, it becomes the name of the branch the PR is merged into. This beraks the connection between creating and deleting preview apps. This changes the method of figuring out the underlying pull-request by looking at the event payload directly and parsing the respective number out of there. --- delete/main.go | 6 +++++- utils/preview.go | 24 +++++++++++++++++++++++- utils/preview_test.go | 6 +++++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/delete/main.go b/delete/main.go index 0799e3f..7f9d2b4 100644 --- a/delete/main.go +++ b/delete/main.go @@ -37,7 +37,11 @@ func main() { appName := in.appName if appName == "" { repoOwner, repo := ghCtx.Repo() - appName = utils.GenerateAppName(repoOwner, repo, ghCtx.RefName) + prRef, err := utils.PRRefFromContext(ghCtx) + if err != nil { + a.Fatalf("failed to get PR number: %v", err) + } + appName = utils.GenerateAppName(repoOwner, repo, prRef) } app, err := utils.FindAppByName(ctx, do.Apps, appName) diff --git a/utils/preview.go b/utils/preview.go index b35b855..1ebad52 100644 --- a/utils/preview.go +++ b/utils/preview.go @@ -3,6 +3,7 @@ package utils import ( "crypto/sha256" "encoding/hex" + "errors" "fmt" "strings" @@ -18,9 +19,13 @@ import ( // - Setting the reference of all relevant components to point to the PRs ref. func SanitizeSpecForPullRequestPreview(spec *godo.AppSpec, ghCtx *gha.GitHubContext) error { repoOwner, repo := ghCtx.Repo() + prRef, err := PRRefFromContext(ghCtx) + if err != nil { + return fmt.Errorf("failed to get PR number: %w", err) + } // Override app name to something that identifies this PR. - spec.Name = GenerateAppName(repoOwner, repo, ghCtx.RefName) + spec.Name = GenerateAppName(repoOwner, repo, prRef) // Unset any domains as those might collide with production apps. spec.Domains = nil @@ -69,3 +74,20 @@ func GenerateAppName(repoOwner, repo, ref string) string { return baseName[:limit] + suffix } + +// PRRefFromContext extracts the PR number from the given GitHub context. +// It mimics the RefName attribute that GitHub Actions provides but is also available +// on merge events, which isn't the case for the RefName attribute. +// See: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request. +func PRRefFromContext(ghCtx *gha.GitHubContext) (string, error) { + prFields, ok := ghCtx.Event["pull_request"].(map[string]any) + if !ok { + return "", fmt.Errorf("pull_request field didn't exist on event: %v", ghCtx.Event) + } + // The event is parsed as a JSON object and Golang represents numbers as float64. + prNumber, ok := prFields["number"].(float64) + if !ok { + return "", errors.New("missing pull request number") + } + return fmt.Sprintf("%d/merge", int(prNumber)), nil +} diff --git a/utils/preview_test.go b/utils/preview_test.go index 0a3b8ad..32c7c08 100644 --- a/utils/preview_test.go +++ b/utils/preview_test.go @@ -56,8 +56,12 @@ func TestSanitizeSpecForPullRequestPreview(t *testing.T) { ghCtx := &gha.GitHubContext{ Repository: "foo/bar", - RefName: "3/merge", HeadRef: "feature-branch", + Event: map[string]any{ + "pull_request": map[string]any{ + "number": float64(3), + }, + }, } err := SanitizeSpecForPullRequestPreview(spec, ghCtx)