Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/aws/aws-sdk-go-v2/config v1.27.7
github.com/aws/aws-sdk-go-v2/service/sns v1.29.2
github.com/aws/aws-sdk-go-v2/service/sqs v1.31.2
github.com/google/go-github/v60 v60.0.0
github.com/gruntwork-io/terratest v0.46.11
github.com/hashicorp/terraform-json v0.13.0
github.com/stretchr/testify v1.8.4
Expand Down Expand Up @@ -47,7 +48,8 @@ require (
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-cmp v0.6.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/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
Expand Down
7 changes: 6 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,13 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
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-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github/v60 v60.0.0 h1:oLG98PsLauFvvu4D/YPxq374jhSxFYdzQGNCyONLfn8=
github.com/google/go-github/v60 v60.0.0/go.mod h1:ByhX2dP9XT9o/ll2yXAu2VD8l5eNVg8hD4Cr0S/LmQk=
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
58 changes: 58 additions & 0 deletions pkg/gh/release.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package gh

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

"github.com/google/go-github/v60/github"
"golang.org/x/oauth2"
)

// FetchReleases fetches GitHub releases for a given repo URL.
// If `onlyLatest` is true, it returns the most recent release.
// Otherwise, it returns all releases.
func FetchReleases(repoURL string, onlyLatest bool) ([]*github.RepositoryRelease, error) {
ctx := context.Background()

// Setup GitHub client with authentication
tc := oauth2.NewClient(ctx, oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")},
))
client := github.NewClient(tc)

owner, repo, err := GetOwnerAndRepoFromURL(repoURL)
if err != nil {
return nil, fmt.Errorf("failed to parse GitHub URL: %w", err)
}

if onlyLatest {
release, _, err := client.Repositories.GetLatestRelease(ctx, owner, repo)
if err != nil {
return nil, fmt.Errorf("error fetching the latest release: %w", err)
}
return []*github.RepositoryRelease{release}, nil
}

releases, _, err := client.Repositories.ListReleases(ctx, owner, repo, &github.ListOptions{})
if err != nil {
return nil, fmt.Errorf("error fetching releases: %w", err)
}

return releases, nil
}

// GetOwnerAndRepoFromURL extracts the owner and repo name from a GitHub URL
func GetOwnerAndRepoFromURL(repoURL string) (string, string, error) {
u, err := url.Parse(repoURL)
if err != nil {
return "", "", fmt.Errorf("error parsing URL: %w", err)
}
parts := strings.Split(strings.Trim(u.Path, "/"), "/")
if len(parts) != 2 {
return "", "", fmt.Errorf("invalid GitHub repo URL format")
}
return parts[0], parts[1], nil
}
41 changes: 30 additions & 11 deletions pkg/utils/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,43 @@ import (
"path/filepath"
)

// IsAGitRepository checks if the given directory is a git repository.
func IsAGitRepository(repoRoot string) error {
// IsAGitRepository checks if the given directory or any of its parent directories up to `levels` is a git repository.
// It returns the git root directory, the subdirectory passed relative to the git root, and any error encountered.
func IsAGitRepository(repoRoot string, levels int) (gitRoot string, subDir string, err error) {
if repoRoot == "" {
return fmt.Errorf("directory path cannot be empty")
return "", "", fmt.Errorf("directory path cannot be empty")
}

if err := DirExistAndHasContent(repoRoot); err != nil {
return err
originalPath, err := filepath.Abs(repoRoot)
if err != nil {
return "", "", fmt.Errorf("failed to resolve absolute path for %s: %v", repoRoot, err)
}

_, err := os.Stat(filepath.Join(repoRoot, ".git"))
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("directory %s is not a git repository", repoRoot)
if err := DirExistAndHasContent(originalPath); err != nil {
return "", "", err
}

currentPath := originalPath
for i := 0; i <= levels; i++ {
_, err := os.Stat(filepath.Join(currentPath, ".git"))
if err == nil {
relPath, _ := filepath.Rel(currentPath, originalPath)
return currentPath, relPath, nil
}

return fmt.Errorf("unexpected error when checking the directory %s: %v", repoRoot, err)
if !os.IsNotExist(err) {
// If the error is not because the .git directory doesn't exist, return it.
return "", "", fmt.Errorf("unexpected error when checking the directory %s: %v", currentPath, err)
}

// Move up one directory level
parentDir := filepath.Dir(currentPath)
if parentDir == currentPath {
// If the parent directory is the same as the current one, we've reached the filesystem root
break
}
currentPath = parentDir
}

return nil
return "", "", fmt.Errorf("no git repository found within %d levels of directory %s", levels, repoRoot)
}