-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: code refactoring and cleanup (#156)
- Loading branch information
1 parent
90aa6d8
commit b08bdd7
Showing
4 changed files
with
106 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,14 +9,17 @@ import ( | |
"strings" | ||
"time" | ||
|
||
"github.com/charmbracelet/log" | ||
git "github.com/go-git/go-git/v5" | ||
github "github.com/google/go-github/v56/github" | ||
oauth2 "golang.org/x/oauth2" | ||
) | ||
|
||
const ( | ||
httpgithubprefix = "https://github.com/" | ||
gitgithubprefix = "[email protected]:" | ||
httpgithubprefix = "https://github.com/" | ||
gitgithubprefix = "[email protected]:" | ||
githubRefPattern = `refs/pull/(\d+)/merge` | ||
githubCommentIdentifier = "Deployed by [Initium](https://initium.nearform.com)" // used to find and update existing comments | ||
) | ||
|
||
func initRepo() (*git.Repository, error) { | ||
|
@@ -115,95 +118,109 @@ func GetGithubOrg() (string, error) { | |
return splitRemote[0], nil | ||
} | ||
|
||
func PublishCommentPRGithub (url string) error { | ||
var message, owner, repo string | ||
var prNumber int | ||
func buildMarkdownMessage(url string) (string, error) { | ||
commitSha, err := GetHash() | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
// Build message | ||
message = fmt.Sprintf("Application URL: %s\n", url) + fmt.Sprintf("Commit hash: %s\n", commitSha) + fmt.Sprintf("Timestamp: %v\n", time.Now()) | ||
message := fmt.Sprintf(githubCommentIdentifier+` | ||
|Application URL | %s | | ||
|:-----------------|:----| | ||
|Commit hash | %s | | ||
|Timestamp | %s | | ||
`, url, commitSha, time.Now().UTC()) | ||
return message, nil | ||
} | ||
|
||
// Check GITHUB_TOKEN | ||
func PublishCommentPRGithub(url string) error { | ||
token := os.Getenv("GITHUB_TOKEN") | ||
prRef := os.Getenv("GITHUB_REF") | ||
repoInfo := os.Getenv("GITHUB_REPOSITORY") | ||
|
||
if token == "" { | ||
return fmt.Errorf("Please set up the GITHUB_TOKEN environment variable") | ||
return fmt.Errorf("GITHUB_TOKEN environment variable not set") | ||
} | ||
|
||
// Create an authenticated GitHub client | ||
ctx := context.Background() | ||
ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token}) | ||
tc := oauth2.NewClient(ctx, ts) | ||
client := github.NewClient(tc) | ||
// Extract pull request number | ||
prNumber, err := extractPullRequestNumber(prRef) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Get required data to publish a comment | ||
repoInfo := os.Getenv("GITHUB_REPOSITORY") | ||
repoParts := strings.Split(repoInfo, "/") | ||
if len(repoParts) == 2 { | ||
owner = repoParts[0] | ||
repo = repoParts[1] | ||
} else { | ||
return fmt.Errorf("Invalid repository information") | ||
} | ||
|
||
// Check if the workflow was triggered by a pull request event | ||
eventName := os.Getenv("GITHUB_EVENT_NAME") | ||
if eventName == "pull_request" { | ||
// Get the pull request ref | ||
prRef := os.Getenv("GITHUB_REF") | ||
|
||
// Extract the pull request number using a regular expression | ||
re := regexp.MustCompile(`refs/pull/(\d+)/merge`) | ||
matches := re.FindStringSubmatch(prRef) | ||
|
||
if len(matches) == 2 { | ||
prNumber, err = strconv.Atoi(matches[1]) | ||
if err != nil { | ||
return fmt.Errorf("Error converting string to int: %v", err) | ||
} | ||
} else { | ||
return fmt.Errorf("Unable to extract pull request number from GITHUB_REF") | ||
} | ||
} else { | ||
return fmt.Errorf("This workflow was not triggered by a pull request event") | ||
message, err := buildMarkdownMessage(url) | ||
if err != nil { | ||
return fmt.Errorf("cannot build the message: %v", err) | ||
} | ||
|
||
// Create comment with body | ||
comment := &github.IssueComment{ | ||
Body: github.String(message), | ||
} | ||
|
||
// List comments on the PR | ||
// Get required data to publish a comment | ||
repoParts := strings.Split(repoInfo, "/") | ||
if len(repoParts) != 2 { | ||
return fmt.Errorf("invalid repository information %s", repoInfo) | ||
} | ||
owner := repoParts[0] | ||
repo := repoParts[1] | ||
|
||
// Create an authenticated GitHub client | ||
ctx := context.Background() | ||
client := createGithubClient(ctx, token) | ||
|
||
// Check if we have to update an existing comment | ||
comments, _, err := client.Issues.ListComments(ctx, owner, repo, prNumber, nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
commentID := findExistingCommentIDPRGithub(comments, "Application URL:") // Search for app URL comment | ||
|
||
if commentID != 0 { | ||
// Update existing comment | ||
updatedComment, _, err := client.Issues.EditComment(ctx, owner, repo, commentID, comment) | ||
matchingComments := findExistingGithubComments(comments, githubCommentIdentifier) // Search for app URL comment | ||
if n := len(matchingComments); n != 0 { | ||
log.Infof("%d matching comment[s] found %v, will always update the last one", n, matchingComments) | ||
updatedComment, _, err := client.Issues.EditComment(ctx, owner, repo, matchingComments[n-1], comment) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Printf("Comment updated successfully: %s\n", updatedComment.GetHTMLURL()) | ||
} else { | ||
// Publish a new comment | ||
newComment, _, err := client.Issues.CreateComment(ctx, owner, repo, prNumber, comment) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Printf("Comment published: %s\n", newComment.GetHTMLURL()) | ||
log.Infof("Comment updated successfully: %s\n", updatedComment.GetHTMLURL()) | ||
return nil | ||
} | ||
|
||
// Publish a new comment | ||
newComment, _, err := client.Issues.CreateComment(ctx, owner, repo, prNumber, comment) | ||
if err != nil { | ||
return err | ||
} | ||
log.Infof("Comment published: %s\n", newComment.GetHTMLURL()) | ||
return nil | ||
} | ||
|
||
func findExistingCommentIDPRGithub(comments []*github.IssueComment, targetBody string) int64 { | ||
func createGithubClient(ctx context.Context, token string) *github.Client { | ||
ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token}) | ||
tc := oauth2.NewClient(ctx, ts) | ||
return github.NewClient(tc) | ||
} | ||
|
||
func extractPullRequestNumber(prRef string) (int, error) { | ||
matches := regexp.MustCompile(githubRefPattern).FindStringSubmatch(prRef) | ||
if len(matches) != 2 { | ||
return 0, fmt.Errorf("unable to extract pull request number from GITHUB_REF %s", prRef) | ||
} | ||
|
||
prNumber, err := strconv.Atoi(matches[1]) | ||
if err != nil { | ||
return 0, fmt.Errorf("error converting string to int: %v", err) | ||
} | ||
return prNumber, nil | ||
} | ||
|
||
func findExistingGithubComments(comments []*github.IssueComment, targetString string) []int64 { | ||
matchingComments := []int64{} | ||
for _, comment := range comments { | ||
if strings.Contains(comment.GetBody(), targetBody) { | ||
return comment.GetID() | ||
body := comment.GetBody() | ||
if strings.Contains(body, targetString) && strings.Contains(body, "initium") { | ||
matchingComments = append(matchingComments, comment.GetID()) | ||
} | ||
} | ||
return 0 | ||
return matchingComments | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters