Borg/pkg/github/release.go
google-labs-jules[bot] 52a07f46be feat: Add ability to download from GitHub releases
This commit introduces a new command `collect github-release` that allows downloading assets from the latest GitHub release of a repository.

The command supports the following features:
- Downloading a specific file from the release using the `--file` flag.
- Downloading all assets from the release and packing them into a DataNode using the `--pack` flag.
- Specifying an output directory for the downloaded files using the `--output` flag.

This commit also includes a project-wide refactoring of the Go module path to `github.com/Snider/Borg` to align with Go's module system best practices.
2025-11-01 19:03:04 +00:00

81 lines
1.8 KiB
Go

package github
import (
"context"
"fmt"
"io"
"net/http"
"os"
"strings"
"github.com/google/go-github/v39/github"
)
// GetLatestRelease gets the latest release for a repository.
func GetLatestRelease(owner, repo string) (*github.RepositoryRelease, error) {
client := github.NewClient(nil)
release, _, err := client.Repositories.GetLatestRelease(context.Background(), owner, repo)
if err != nil {
return nil, err
}
return release, nil
}
// DownloadReleaseAsset downloads a release asset.
func DownloadReleaseAsset(asset *github.ReleaseAsset, path string) error {
client := &http.Client{}
req, err := http.NewRequest("GET", asset.GetBrowserDownloadURL(), nil)
if err != nil {
return err
}
req.Header.Set("Accept", "application/octet-stream")
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("bad status: %s", resp.Status)
}
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return err
}
defer f.Close()
_, err = io.Copy(f, resp.Body)
return err
}
// ParseRepoFromURL parses the owner and repository from a GitHub URL.
func ParseRepoFromURL(u string) (owner, repo string, err error) {
u = strings.TrimSuffix(u, ".git")
prefixesToTrim := []string{
"https://github.com/",
"http://github.com/",
"git://github.com/",
"github.com/",
}
// Handle scp-like and other formats by replacing them first.
u = strings.Replace(u, "git@github.com:", "", 1)
u = strings.Replace(u, "git:github.com:", "", 1)
for _, p := range prefixesToTrim {
if strings.HasPrefix(u, p) {
u = strings.TrimPrefix(u, p)
break
}
}
parts := strings.Split(u, "/")
if len(parts) != 2 {
return "", "", fmt.Errorf("invalid or unsupported github url format: %s", u)
}
return parts[0], parts[1], nil
}