Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: post application url and commit hash as a PR comment after every deploy #148

Merged
merged 30 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion assets/github/onbranch.tmpl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This file is generate by https://github.com/nearform/initium-cli
# This file is generated by https://github.com/nearform/initium-cli
name: Deploy on PR

on:
Expand All @@ -8,6 +8,8 @@ on:
permissions:
contents: read
packages: write
issues: write
pull-requests: write

jobs:
on_pr:
Expand All @@ -24,6 +26,7 @@ jobs:
with:
args: onbranch
env:
GITHUB_TOKEN: {{ `${{ secrets.GITHUB_TOKEN }}` }}
INITIUM_REGISTRY_USER: {{ `${{ github.actor }}` }}
INITIUM_REGISTRY_PASSWORD: {{ `${{ secrets.GITHUB_TOKEN }}` }}
INITIUM_CLUSTER_ENDPOINT: {{ `${{ secrets.CLUSTER_ENDPOINT }}` }}
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ require (
github.com/google/gnostic v0.6.9 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-containerregistry v0.13.0 // indirect
github.com/google/go-github/v56 v56.0.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/imdario/mergo v0.3.15 // indirect
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,17 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-containerregistry v0.13.0 h1:y1C7Z3e149OJbOPDBxLYR8ITPz8dTKqQwjErKVHJC8k=
github.com/google/go-containerregistry v0.13.0/go.mod h1:J9FQ+eSS4a1aC2GNZxvNpbWhgp0487v+cgiilB4FqDo=
github.com/google/go-github/v56 v56.0.0 h1:TysL7dMa/r7wsQi44BjqlwaHvwlFlqkK8CtBWCX3gb4=
github.com/google/go-github/v56 v56.0.0/go.mod h1:D8cdcX98YWJvi7TLo7zM4/h8ZTx6u6fwGEkCdisopo0=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
Expand Down
20 changes: 19 additions & 1 deletion src/cli/onbranch.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package cli

import (
"fmt"
"net/url"
"os"

"github.com/nearform/initium-cli/src/services/git"
"github.com/nearform/initium-cli/src/utils"
Expand Down Expand Up @@ -29,7 +31,23 @@ func (c icli) buildPushDeploy(cCtx *cli.Context) error {
if cCtx.Bool(stopOnPushFlag) {
return err
}
return c.Deploy(cCtx)

err = c.Deploy(cCtx)
appUrl, urlErr := url.Parse(err.Error()) // Check if it contains the app URL or it's a legit error
if urlErr != nil {
fmt.Println("No app URL available")
return err
}

// Check if the CI environment variable is set to GitHub Actions
if os.Getenv("CI") == "true" && os.Getenv("GITHUB_ACTIONS") == "true" {
err = git.PublishCommentPRGithub(appUrl.String())
} else {
fmt.Printf("You can reach the app via %s\n", appUrl.String())
err = nil
}

return err
}

func (c icli) OnBranchCMD() *cli.Command {
Expand Down
99 changes: 99 additions & 0 deletions src/services/git/repo.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package git

import (
"context"
"fmt"
"os"
"regexp"
"strconv"
"strings"
"time"

git "github.com/go-git/go-git/v5"
github "github.com/google/go-github/v56/github"
oauth2 "golang.org/x/oauth2"
)

const (
Expand Down Expand Up @@ -108,3 +114,96 @@ func GetGithubOrg() (string, error) {
splitRemote := strings.Split(remote, "/")
return splitRemote[0], nil
}

func PublishCommentPRGithub (url string) error {
var message, owner, repo string
var prNumber int
commitSha, err := GetHash()

// Build message
message = fmt.Sprintf("Application URL: %s\n", url) + fmt.Sprintf("Commit hash: %s\n", commitSha) + fmt.Sprintf("Timestamp: %v\n", time.Now())

// Check GITHUB_TOKEN
token := os.Getenv("GITHUB_TOKEN")
if token == "" {
return fmt.Errorf("Please set up the GITHUB_TOKEN environment variable")
}

// Create an authenticated GitHub client
ctx := context.Background()
ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token})
tc := oauth2.NewClient(ctx, ts)
client := github.NewClient(tc)

// 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")
}

// Create comment with body
comment := &github.IssueComment{
Body: github.String(message),
}

// List comments on the PR
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)
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())
}

return nil
}

func findExistingCommentIDPRGithub(comments []*github.IssueComment, targetBody string) int64 {
for _, comment := range comments {
if strings.Contains(comment.GetBody(), targetBody) {
return comment.GetID()
}
}
return 0
}
5 changes: 1 addition & 4 deletions src/services/k8s/knative.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,14 +253,11 @@ func Apply(serviceManifest *servingv1.Service, config *rest.Config) error {
return err
}
if service.Status.URL != nil {
fmt.Printf("You can reach it via %s\n", service.Status.URL)
break
return fmt.Errorf("%s", service.Status.URL) // Overload error return variable with URL string
}

time.Sleep(time.Millisecond * 500)
}

return nil
}

func Clean(namespace string, config *rest.Config, project *project.Project) error {
Expand Down