mirror of
https://github.com/tronbyt/server.git
synced 2025-12-19 08:25:46 +01:00
feat: add GITHUB_TOKEN configuration for git auth
This allows using a personal access token for private repositories and higher API rate limits. Fixes #501
This commit is contained in:
@@ -221,7 +221,7 @@ func main() {
|
||||
// Clone/Update System Apps Repo
|
||||
systemAppsDir := filepath.Join(*dataDir, "system-apps")
|
||||
shouldUpdate := cfg.Production == "1"
|
||||
if err := gitutils.EnsureRepo(systemAppsDir, cfg.SystemAppsRepo, shouldUpdate); err != nil {
|
||||
if err := gitutils.EnsureRepo(systemAppsDir, cfg.SystemAppsRepo, cfg.GitHubToken, shouldUpdate); err != nil {
|
||||
slog.Error("Failed to update system apps repo", "error", err)
|
||||
// Continue anyway
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ type Settings struct {
|
||||
MaxUsers int `env:"MAX_USERS" envDefault:"0"`
|
||||
SingleUserAutoLogin string `env:"SINGLE_USER_AUTO_LOGIN" envDefault:"0"`
|
||||
SystemAppsRepo string `env:"SYSTEM_APPS_REPO" envDefault:"https://github.com/tronbyt/apps.git"`
|
||||
GitHubToken string `env:"GITHUB_TOKEN"`
|
||||
RedisURL string `env:"REDIS_URL"`
|
||||
Host string `env:"TRONBYT_HOST" envDefault:""`
|
||||
Port string `env:"TRONBYT_PORT" envDefault:"8000"`
|
||||
|
||||
@@ -4,11 +4,14 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/go-git/go-git/v6"
|
||||
"github.com/go-git/go-git/v6/plumbing"
|
||||
"github.com/go-git/go-git/v6/plumbing/transport"
|
||||
"github.com/go-git/go-git/v6/plumbing/transport/http"
|
||||
)
|
||||
|
||||
// logWriter implements io.Writer to redirect git progress to slog.
|
||||
@@ -89,16 +92,31 @@ func GetRepoInfo(path string, remoteURL string) (*RepoInfo, error) {
|
||||
}
|
||||
|
||||
// EnsureRepo clones a repo if it doesn't exist, or pulls if it does and update is true.
|
||||
func EnsureRepo(path string, url string, update bool) error {
|
||||
slog.Info("Checking git repo", "path", path, "url", url)
|
||||
func EnsureRepo(path string, repoURL string, token string, update bool) error {
|
||||
slog.Info("Checking git repo", "path", path, "url", repoURL)
|
||||
|
||||
var auth transport.AuthMethod
|
||||
|
||||
u, err := url.Parse(repoURL)
|
||||
if err == nil && u.User == nil {
|
||||
if token != "" && (u.Scheme == "http" || u.Scheme == "https") && u.Host == "github.com" {
|
||||
auth = &http.BasicAuth{
|
||||
Username: token,
|
||||
Password: "", // For GitHub PATs, the password can be empty.
|
||||
}
|
||||
}
|
||||
} else if err != nil {
|
||||
slog.Warn("Failed to parse repo URL", "url", repoURL, "error", err)
|
||||
}
|
||||
|
||||
// Check if path exists
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
slog.Info("Cloning repo", "url", url)
|
||||
slog.Info("Cloning repo", "url", repoURL)
|
||||
_, err := git.PlainClone(path, &git.CloneOptions{
|
||||
URL: url,
|
||||
URL: repoURL,
|
||||
Progress: &logWriter{},
|
||||
Depth: 1,
|
||||
Auth: auth,
|
||||
})
|
||||
|
||||
return err
|
||||
@@ -116,14 +134,14 @@ func EnsureRepo(path string, url string, update bool) error {
|
||||
rem, err := r.Remote("origin")
|
||||
if err == nil {
|
||||
urls := rem.Config().URLs
|
||||
if len(urls) > 0 && urls[0] != url {
|
||||
slog.Warn("Repo remote URL mismatch, re-cloning", "current", urls[0], "new", url)
|
||||
if len(urls) > 0 && urls[0] != repoURL {
|
||||
slog.Warn("Repo remote URL mismatch, re-cloning", "current", urls[0], "new", repoURL)
|
||||
// Remove and re-clone
|
||||
if err := os.RemoveAll(path); err != nil {
|
||||
return fmt.Errorf("failed to remove old repo: %w", err)
|
||||
}
|
||||
|
||||
return EnsureRepo(path, url, update)
|
||||
return EnsureRepo(path, repoURL, token, update)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,6 +163,7 @@ func EnsureRepo(path string, url string, update bool) error {
|
||||
Progress: &logWriter{},
|
||||
Depth: 1,
|
||||
Force: true,
|
||||
Auth: auth,
|
||||
})
|
||||
|
||||
// Handle fetch errors
|
||||
@@ -155,7 +174,7 @@ func EnsureRepo(path string, url string, update bool) error {
|
||||
if err := os.RemoveAll(path); err != nil {
|
||||
return fmt.Errorf("failed to remove broken repo: %w", err)
|
||||
}
|
||||
return EnsureRepo(path, url, update)
|
||||
return EnsureRepo(path, repoURL, token, update)
|
||||
}
|
||||
return fmt.Errorf("failed to fetch repo: %w", err)
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ func (s *Server) UpdateFirmwareBinaries() error {
|
||||
return err
|
||||
}
|
||||
|
||||
token := os.Getenv("GITHUB_TOKEN")
|
||||
token := s.Config.GitHubToken
|
||||
if token != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func (s *Server) doUpdateCheck() {
|
||||
return
|
||||
}
|
||||
|
||||
githubToken := os.Getenv("GITHUB_TOKEN")
|
||||
githubToken := s.Config.GitHubToken
|
||||
if githubToken != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+githubToken)
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ func (s *Server) handleSetUserRepo(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
appsPath := filepath.Join(s.DataDir, "users", user.Username, "apps")
|
||||
if err := gitutils.EnsureRepo(appsPath, repoURL, true); err != nil {
|
||||
if err := gitutils.EnsureRepo(appsPath, repoURL, s.Config.GitHubToken, true); err != nil {
|
||||
slog.Error("Failed to sync user repo", "error", err)
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ func (s *Server) handleRefreshUserRepo(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if user.AppRepoURL != "" {
|
||||
appsPath := filepath.Join(s.DataDir, "users", user.Username, "apps")
|
||||
if err := gitutils.EnsureRepo(appsPath, user.AppRepoURL, true); err != nil {
|
||||
if err := gitutils.EnsureRepo(appsPath, user.AppRepoURL, s.Config.GitHubToken, true); err != nil {
|
||||
slog.Error("Failed to refresh user repo", "error", err)
|
||||
}
|
||||
}
|
||||
@@ -355,7 +355,7 @@ func (s *Server) handleSetSystemRepo(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
appsPath := filepath.Join(s.DataDir, "system-apps")
|
||||
if err := gitutils.EnsureRepo(appsPath, repoURL, true); err != nil {
|
||||
if err := gitutils.EnsureRepo(appsPath, repoURL, s.Config.GitHubToken, true); err != nil {
|
||||
slog.Error("Failed to update system repo", "error", err)
|
||||
}
|
||||
|
||||
@@ -385,7 +385,7 @@ func (s *Server) handleRefreshSystemRepo(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
appsPath := filepath.Join(s.DataDir, "system-apps")
|
||||
if err := gitutils.EnsureRepo(appsPath, repoURL, true); err != nil {
|
||||
if err := gitutils.EnsureRepo(appsPath, repoURL, s.Config.GitHubToken, true); err != nil {
|
||||
slog.Error("Failed to refresh system repo", "error", err)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user