summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-11 18:28:41 +0200
committerPaul Buetow <paul@buetow.org>2026-03-11 18:28:41 +0200
commit9706e53620045c20bf732054a286183c70f77581 (patch)
tree166e822e9d41b0cc980d4481c5c175ec7164a107 /internal
parent1c12325c64bb734dd0ae95a0c803de1ff45d2b4c (diff)
fix(api): add timed shared HTTP client
Diffstat (limited to 'internal')
-rw-r--r--internal/codeberg/codeberg.go80
-rw-r--r--internal/github/github.go77
-rw-r--r--internal/httpclient/client.go30
-rw-r--r--internal/httpclient/client_test.go44
-rw-r--r--internal/release/release.go68
5 files changed, 205 insertions, 94 deletions
diff --git a/internal/codeberg/codeberg.go b/internal/codeberg/codeberg.go
index 7ef583d..9ecb3d8 100644
--- a/internal/codeberg/codeberg.go
+++ b/internal/codeberg/codeberg.go
@@ -9,6 +9,8 @@ import (
"os"
"path/filepath"
"time"
+
+ "codeberg.org/snonux/gitsyncer/internal/httpclient"
)
// Repository represents a Codeberg/Gitea repository
@@ -77,15 +79,16 @@ func (c *Client) HasToken() bool {
func (c *Client) GetRepo(repoName string) (Repository, bool, error) {
var repo Repository
url := fmt.Sprintf("%s/repos/%s/%s", c.baseURL, c.org, repoName)
- req, err := http.NewRequest("GET", url, nil)
+ req, cancel, err := httpclient.NewRequest(http.MethodGet, url, nil)
if err != nil {
return repo, false, err
}
+ defer cancel()
if c.HasToken() {
req.Header.Set("Authorization", "token "+c.token)
}
- resp, err := http.DefaultClient.Do(req)
+ resp, err := httpclient.Do(req)
if err != nil {
return repo, false, err
}
@@ -120,14 +123,15 @@ func (c *Client) UpdateRepoDescription(repoName, description string) error {
return err
}
- req, err := http.NewRequest("PATCH", url, bytes.NewBuffer(body))
+ req, cancel, err := httpclient.NewRequest(http.MethodPatch, url, bytes.NewBuffer(body))
if err != nil {
return err
}
+ defer cancel()
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "token "+c.token)
- resp, err := http.DefaultClient.Do(req)
+ resp, err := httpclient.Do(req)
if err != nil {
return err
}
@@ -149,19 +153,9 @@ func (c *Client) ListPublicRepos() ([]Repository, error) {
for {
url := fmt.Sprintf("%s/orgs/%s/repos?page=%d&limit=%d", c.baseURL, c.org, page, perPage)
- resp, err := http.Get(url)
+ repos, err := c.listReposPage(url)
if err != nil {
- return nil, fmt.Errorf("failed to fetch repositories: %w", err)
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != 200 {
- return nil, fmt.Errorf("API returned status %d", resp.StatusCode)
- }
-
- var repos []Repository
- if err := json.NewDecoder(resp.Body).Decode(&repos); err != nil {
- return nil, fmt.Errorf("failed to parse response: %w", err)
+ return nil, err
}
// Filter only public, non-fork, non-archived, non-empty repos
@@ -191,19 +185,9 @@ func (c *Client) ListUserPublicRepos() ([]Repository, error) {
for {
url := fmt.Sprintf("%s/users/%s/repos?page=%d&limit=%d", c.baseURL, c.org, page, perPage)
- resp, err := http.Get(url)
+ repos, err := c.listReposPage(url)
if err != nil {
- return nil, fmt.Errorf("failed to fetch repositories: %w", err)
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != 200 {
- return nil, fmt.Errorf("API returned status %d", resp.StatusCode)
- }
-
- var repos []Repository
- if err := json.NewDecoder(resp.Body).Decode(&repos); err != nil {
- return nil, fmt.Errorf("failed to parse response: %w", err)
+ return nil, err
}
// Filter only public, non-fork, non-archived, non-empty repos
@@ -233,19 +217,45 @@ func GetRepoNames(repos []Repository) []string {
return names
}
+func (c *Client) listReposPage(url string) ([]Repository, error) {
+ req, cancel, err := httpclient.NewRequest(http.MethodGet, url, nil)
+ if err != nil {
+ return nil, err
+ }
+ defer cancel()
+
+ resp, err := httpclient.Do(req)
+ if err != nil {
+ return nil, fmt.Errorf("failed to fetch repositories: %w", err)
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode != http.StatusOK {
+ return nil, fmt.Errorf("API returned status %d", resp.StatusCode)
+ }
+
+ var repos []Repository
+ if err := json.NewDecoder(resp.Body).Decode(&repos); err != nil {
+ return nil, fmt.Errorf("failed to parse response: %w", err)
+ }
+
+ return repos, nil
+}
+
// RepoExists checks if a repository exists on Codeberg
func (c *Client) RepoExists(repoName string) (bool, error) {
url := fmt.Sprintf("%s/repos/%s/%s", c.baseURL, c.org, repoName)
- req, err := http.NewRequest("GET", url, nil)
+ req, cancel, err := httpclient.NewRequest(http.MethodGet, url, nil)
if err != nil {
return false, err
}
+ defer cancel()
if c.HasToken() {
req.Header.Set("Authorization", "token "+c.token)
}
- resp, err := http.DefaultClient.Do(req)
+ resp, err := httpclient.Do(req)
if err != nil {
return false, err
}
@@ -277,17 +287,18 @@ func (c *Client) CreateRepo(repoName, description string, private bool) error {
return err
}
- req, err := http.NewRequest("POST", url, bytes.NewBuffer(body))
+ req, cancel, err := httpclient.NewRequest(http.MethodPost, url, bytes.NewBuffer(body))
if err != nil {
return err
}
+ defer cancel()
req.Header.Set("Content-Type", "application/json")
if c.HasToken() {
req.Header.Set("Authorization", "token "+c.token)
}
- resp, err := http.DefaultClient.Do(req)
+ resp, err := httpclient.Do(req)
if err != nil {
return err
}
@@ -334,14 +345,15 @@ func (c *Client) DeleteRepo(repoName string) error {
url := fmt.Sprintf("%s/repos/%s/%s", c.baseURL, c.org, repoName)
- req, err := http.NewRequest("DELETE", url, nil)
+ req, cancel, err := httpclient.NewRequest(http.MethodDelete, url, nil)
if err != nil {
return err
}
+ defer cancel()
req.Header.Set("Authorization", "token "+c.token)
- resp, err := http.DefaultClient.Do(req)
+ resp, err := httpclient.Do(req)
if err != nil {
return err
}
diff --git a/internal/github/github.go b/internal/github/github.go
index c886e43..2667658 100644
--- a/internal/github/github.go
+++ b/internal/github/github.go
@@ -9,6 +9,8 @@ import (
"os"
"path/filepath"
"strings"
+
+ "codeberg.org/snonux/gitsyncer/internal/httpclient"
)
// Client handles GitHub API operations
@@ -85,15 +87,16 @@ func (c *Client) RepoExists(repoName string) (bool, error) {
url := fmt.Sprintf("https://api.github.com/repos/%s/%s", c.org, repoName)
fmt.Printf(" Checking URL: %s\n", url)
- req, err := http.NewRequest("GET", url, nil)
+ req, cancel, err := httpclient.NewRequest(http.MethodGet, url, nil)
if err != nil {
return false, err
}
+ defer cancel()
req.Header.Set("Authorization", "Bearer "+c.token)
req.Header.Set("Accept", "application/vnd.github.v3+json")
- resp, err := http.DefaultClient.Do(req)
+ resp, err := httpclient.Do(req)
if err != nil {
return false, err
}
@@ -145,16 +148,17 @@ func (c *Client) CreateRepo(repoName, description string, private bool) error {
return err
}
- req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonBody))
+ req, cancel, err := httpclient.NewRequest(http.MethodPost, url, bytes.NewBuffer(jsonBody))
if err != nil {
return err
}
+ defer cancel()
req.Header.Set("Authorization", "Bearer "+c.token)
req.Header.Set("Accept", "application/vnd.github.v3+json")
req.Header.Set("Content-Type", "application/json")
- resp, err := http.DefaultClient.Do(req)
+ resp, err := httpclient.Do(req)
if err != nil {
return err
}
@@ -196,14 +200,15 @@ func (c *Client) GetRepo(repoName string) (Repository, bool, error) {
}
url := fmt.Sprintf("https://api.github.com/repos/%s/%s", c.org, repoName)
- req, err := http.NewRequest("GET", url, nil)
+ req, cancel, err := httpclient.NewRequest(http.MethodGet, url, nil)
if err != nil {
return repo, false, err
}
+ defer cancel()
req.Header.Set("Authorization", "Bearer "+c.token)
req.Header.Set("Accept", "application/vnd.github.v3+json")
- resp, err := http.DefaultClient.Do(req)
+ resp, err := httpclient.Do(req)
if err != nil {
return repo, false, err
}
@@ -238,15 +243,16 @@ func (c *Client) UpdateRepoDescription(repoName, description string) error {
return err
}
- req, err := http.NewRequest("PATCH", url, bytes.NewBuffer(body))
+ req, cancel, err := httpclient.NewRequest(http.MethodPatch, url, bytes.NewBuffer(body))
if err != nil {
return err
}
+ defer cancel()
req.Header.Set("Authorization", "Bearer "+c.token)
req.Header.Set("Accept", "application/vnd.github.v3+json")
req.Header.Set("Content-Type", "application/json")
- resp, err := http.DefaultClient.Do(req)
+ resp, err := httpclient.Do(req)
if err != nil {
return err
}
@@ -284,30 +290,11 @@ func (c *Client) ListPublicRepos() ([]Repository, error) {
url := fmt.Sprintf("https://api.github.com/users/%s/repos?page=%d&per_page=%d&type=owner", c.org, page, perPage)
fmt.Printf(" Fetching page %d...\n", page)
- req, err := http.NewRequest("GET", url, nil)
+ repos, err := c.listPublicReposPage(url)
if err != nil {
return nil, err
}
- req.Header.Set("Authorization", "Bearer "+c.token)
- req.Header.Set("Accept", "application/vnd.github.v3+json")
-
- resp, err := http.DefaultClient.Do(req)
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != 200 {
- body, _ := io.ReadAll(resp.Body)
- return nil, fmt.Errorf("failed to list repos: status %d: %s", resp.StatusCode, string(body))
- }
-
- var repos []Repository
- if err := json.NewDecoder(resp.Body).Decode(&repos); err != nil {
- return nil, fmt.Errorf("failed to decode response: %w", err)
- }
-
// Filter for public, non-fork, non-archived
for _, repo := range repos {
if !repo.Private && !repo.Fork && !repo.Archived && !repo.Disabled {
@@ -325,6 +312,35 @@ func (c *Client) ListPublicRepos() ([]Repository, error) {
return allRepos, nil
}
+func (c *Client) listPublicReposPage(url string) ([]Repository, error) {
+ req, cancel, err := httpclient.NewRequest(http.MethodGet, url, nil)
+ if err != nil {
+ return nil, err
+ }
+ defer cancel()
+
+ req.Header.Set("Authorization", "Bearer "+c.token)
+ req.Header.Set("Accept", "application/vnd.github.v3+json")
+
+ resp, err := httpclient.Do(req)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode != http.StatusOK {
+ body, _ := io.ReadAll(resp.Body)
+ return nil, fmt.Errorf("failed to list repos: status %d: %s", resp.StatusCode, string(body))
+ }
+
+ var repos []Repository
+ if err := json.NewDecoder(resp.Body).Decode(&repos); err != nil {
+ return nil, fmt.Errorf("failed to decode response: %w", err)
+ }
+
+ return repos, nil
+}
+
// GetRepoNames extracts repository names from a list of repos
func GetRepoNames(repos []Repository) []string {
names := make([]string, len(repos))
@@ -352,15 +368,16 @@ func (c *Client) DeleteRepo(repoName string) error {
url := fmt.Sprintf("https://api.github.com/repos/%s/%s", c.org, repoName)
- req, err := http.NewRequest("DELETE", url, nil)
+ req, cancel, err := httpclient.NewRequest(http.MethodDelete, url, nil)
if err != nil {
return err
}
+ defer cancel()
req.Header.Set("Authorization", "Bearer "+c.token)
req.Header.Set("Accept", "application/vnd.github.v3+json")
- resp, err := http.DefaultClient.Do(req)
+ resp, err := httpclient.Do(req)
if err != nil {
return err
}
diff --git a/internal/httpclient/client.go b/internal/httpclient/client.go
new file mode 100644
index 0000000..5c57cdc
--- /dev/null
+++ b/internal/httpclient/client.go
@@ -0,0 +1,30 @@
+package httpclient
+
+import (
+ "context"
+ "io"
+ "net/http"
+ "time"
+)
+
+const DefaultTimeout = 30 * time.Second
+
+var defaultClient = &http.Client{
+ Timeout: DefaultTimeout,
+}
+
+func Do(req *http.Request) (*http.Response, error) {
+ return defaultClient.Do(req)
+}
+
+func NewRequest(method, url string, body io.Reader) (*http.Request, context.CancelFunc, error) {
+ ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout)
+
+ req, err := http.NewRequestWithContext(ctx, method, url, body)
+ if err != nil {
+ cancel()
+ return nil, nil, err
+ }
+
+ return req, cancel, nil
+}
diff --git a/internal/httpclient/client_test.go b/internal/httpclient/client_test.go
new file mode 100644
index 0000000..a8b2216
--- /dev/null
+++ b/internal/httpclient/client_test.go
@@ -0,0 +1,44 @@
+package httpclient
+
+import (
+ "net/http"
+ "testing"
+ "time"
+)
+
+func TestNewRequest_SetsDeadline(t *testing.T) {
+ req, cancel, err := NewRequest(http.MethodGet, "https://example.com", nil)
+ if err != nil {
+ t.Fatalf("NewRequest returned error: %v", err)
+ }
+ defer cancel()
+
+ deadline, ok := req.Context().Deadline()
+ if !ok {
+ t.Fatal("expected request context to include a deadline")
+ }
+
+ remaining := time.Until(deadline)
+ if remaining <= 0 {
+ t.Fatalf("expected future deadline, got %v", remaining)
+ }
+ if remaining > DefaultTimeout+time.Second {
+ t.Fatalf("expected deadline near %v, got %v", DefaultTimeout, remaining)
+ }
+}
+
+func TestNewRequest_InvalidMethod(t *testing.T) {
+ req, cancel, err := NewRequest("bad method", "https://example.com", nil)
+ if cancel != nil {
+ defer cancel()
+ }
+ if err == nil {
+ t.Fatalf("expected invalid method error, got request %#v", req)
+ }
+}
+
+func TestDo_UsesSharedTimeout(t *testing.T) {
+ if defaultClient.Timeout != DefaultTimeout {
+ t.Fatalf("expected shared timeout %v, got %v", DefaultTimeout, defaultClient.Timeout)
+ }
+}
diff --git a/internal/release/release.go b/internal/release/release.go
index 2acd621..6d6091f 100644
--- a/internal/release/release.go
+++ b/internal/release/release.go
@@ -11,6 +11,8 @@ import (
"regexp"
"sort"
"strings"
+
+ "codeberg.org/snonux/gitsyncer/internal/httpclient"
)
// Tag represents a git tag
@@ -64,12 +66,13 @@ func (m *Manager) EnsureCodebergReleasesEnabled(owner, repo string) error {
// Fetch repository metadata
infoURL := fmt.Sprintf("https://codeberg.org/api/v1/repos/%s/%s", owner, repo)
- getReq, err := http.NewRequest("GET", infoURL, nil)
+ getReq, cancel, err := httpclient.NewRequest(http.MethodGet, infoURL, nil)
if err != nil {
return err
}
+ defer cancel()
getReq.Header.Set("Authorization", "token "+m.codebergToken)
- resp, err := (&http.Client{}).Do(getReq)
+ resp, err := httpclient.Do(getReq)
if err != nil {
return err
}
@@ -95,13 +98,14 @@ func (m *Manager) EnsureCodebergReleasesEnabled(owner, repo string) error {
if err != nil {
return err
}
- patchReq, err := http.NewRequest("PATCH", infoURL, bytes.NewBuffer(body))
+ patchReq, patchCancel, err := httpclient.NewRequest(http.MethodPatch, infoURL, bytes.NewBuffer(body))
if err != nil {
return err
}
+ defer patchCancel()
patchReq.Header.Set("Authorization", "token "+m.codebergToken)
patchReq.Header.Set("Content-Type", "application/json")
- patchResp, err := (&http.Client{}).Do(patchReq)
+ patchResp, err := httpclient.Do(patchReq)
if err != nil {
return err
}
@@ -522,10 +526,11 @@ func (m *Manager) GenerateAIReleaseNotes(repoPath, repoName, tag string, allTags
func (m *Manager) GetGitHubReleases(owner, repo string) ([]string, error) {
url := fmt.Sprintf("https://api.github.com/repos/%s/%s/releases", owner, repo)
- req, err := http.NewRequest("GET", url, nil)
+ req, cancel, err := httpclient.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, err
}
+ defer cancel()
// Add GitHub token if available
if m.githubToken != "" {
@@ -533,8 +538,7 @@ func (m *Manager) GetGitHubReleases(owner, repo string) ([]string, error) {
}
req.Header.Set("Accept", "application/vnd.github.v3+json")
- client := &http.Client{}
- resp, err := client.Do(req)
+ resp, err := httpclient.Do(req)
if err != nil {
return nil, err
}
@@ -567,18 +571,18 @@ func (m *Manager) GetGitHubReleases(owner, repo string) ([]string, error) {
func (m *Manager) GetCodebergReleases(owner, repo string) ([]string, error) {
url := fmt.Sprintf("https://codeberg.org/api/v1/repos/%s/%s/releases", owner, repo)
- req, err := http.NewRequest("GET", url, nil)
+ req, cancel, err := httpclient.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, err
}
+ defer cancel()
// Add Codeberg token if available
if m.codebergToken != "" {
req.Header.Set("Authorization", "token "+m.codebergToken)
}
- client := &http.Client{}
- resp, err := client.Do(req)
+ resp, err := httpclient.Do(req)
if err != nil {
return nil, err
}
@@ -649,17 +653,17 @@ func (m *Manager) CreateGitHubRelease(owner, repo, tag, releaseNotes string) err
return err
}
- req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
+ req, cancel, err := httpclient.NewRequest(http.MethodPost, url, bytes.NewBuffer(jsonData))
if err != nil {
return err
}
+ defer cancel()
req.Header.Set("Authorization", "Bearer "+m.githubToken)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/vnd.github.v3+json")
- client := &http.Client{}
- resp, err := client.Do(req)
+ resp, err := httpclient.Do(req)
if err != nil {
return err
}
@@ -702,17 +706,17 @@ func (m *Manager) CreateCodebergRelease(owner, repo, tag, releaseNotes string) e
return err
}
- req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
+ req, cancel, err := httpclient.NewRequest(http.MethodPost, url, bytes.NewBuffer(jsonData))
if err != nil {
return err
}
+ defer cancel()
req.Header.Set("Authorization", "token "+m.codebergToken)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
- client := &http.Client{}
- resp, err := client.Do(req)
+ resp, err := httpclient.Do(req)
if err != nil {
return err
}
@@ -725,13 +729,14 @@ func (m *Manager) CreateCodebergRelease(owner, repo, tag, releaseNotes string) e
if resp.StatusCode == 404 {
// Probe repository details to distinguish scenarios
probeURL := fmt.Sprintf("https://codeberg.org/api/v1/repos/%s/%s", owner, repo)
- probeReq, perr := http.NewRequest("GET", probeURL, nil)
+ probeReq, probeCancel, perr := httpclient.NewRequest(http.MethodGet, probeURL, nil)
if perr == nil {
+ defer probeCancel()
// Prefer probing with the same token
if m.codebergToken != "" {
probeReq.Header.Set("Authorization", "token "+m.codebergToken)
}
- if probeResp, perr2 := (&http.Client{}).Do(probeReq); perr2 == nil {
+ if probeResp, perr2 := httpclient.Do(probeReq); perr2 == nil {
defer probeResp.Body.Close()
if probeResp.StatusCode == 200 {
// Try to detect if releases are disabled
@@ -749,14 +754,15 @@ func (m *Manager) CreateCodebergRelease(owner, repo, tag, releaseNotes string) e
)
}
// Retry POST after enabling
- retryReq, rerr := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
+ retryReq, retryCancel, rerr := httpclient.NewRequest(http.MethodPost, url, bytes.NewBuffer(jsonData))
if rerr != nil {
return rerr
}
+ defer retryCancel()
retryReq.Header.Set("Authorization", "token "+m.codebergToken)
retryReq.Header.Set("Content-Type", "application/json")
retryReq.Header.Set("Accept", "application/json")
- retryResp, rerr := (&http.Client{}).Do(retryReq)
+ retryResp, rerr := httpclient.Do(retryReq)
if rerr != nil {
return rerr
}
@@ -835,16 +841,16 @@ func (m *Manager) UpdateGitHubRelease(owner, repo, tag, releaseNotes string) err
// First, get the release ID
url := fmt.Sprintf("https://api.github.com/repos/%s/%s/releases/tags/%s", owner, repo, tag)
- req, err := http.NewRequest("GET", url, nil)
+ req, cancel, err := httpclient.NewRequest(http.MethodGet, url, nil)
if err != nil {
return err
}
+ defer cancel()
req.Header.Set("Authorization", "Bearer "+m.githubToken)
req.Header.Set("Accept", "application/vnd.github.v3+json")
- client := &http.Client{}
- resp, err := client.Do(req)
+ resp, err := httpclient.Do(req)
if err != nil {
return err
}
@@ -876,16 +882,17 @@ func (m *Manager) UpdateGitHubRelease(owner, repo, tag, releaseNotes string) err
return err
}
- updateReq, err := http.NewRequest("PATCH", updateURL, bytes.NewBuffer(jsonData))
+ updateReq, updateCancel, err := httpclient.NewRequest(http.MethodPatch, updateURL, bytes.NewBuffer(jsonData))
if err != nil {
return err
}
+ defer updateCancel()
updateReq.Header.Set("Authorization", "Bearer "+m.githubToken)
updateReq.Header.Set("Content-Type", "application/json")
updateReq.Header.Set("Accept", "application/vnd.github.v3+json")
- updateResp, err := client.Do(updateReq)
+ updateResp, err := httpclient.Do(updateReq)
if err != nil {
return err
}
@@ -908,15 +915,15 @@ func (m *Manager) UpdateCodebergRelease(owner, repo, tag, releaseNotes string) e
// First, get the release ID
url := fmt.Sprintf("https://codeberg.org/api/v1/repos/%s/%s/releases/tags/%s", owner, repo, tag)
- req, err := http.NewRequest("GET", url, nil)
+ req, cancel, err := httpclient.NewRequest(http.MethodGet, url, nil)
if err != nil {
return err
}
+ defer cancel()
req.Header.Set("Authorization", "token "+m.codebergToken)
- client := &http.Client{}
- resp, err := client.Do(req)
+ resp, err := httpclient.Do(req)
if err != nil {
return err
}
@@ -948,15 +955,16 @@ func (m *Manager) UpdateCodebergRelease(owner, repo, tag, releaseNotes string) e
return err
}
- updateReq, err := http.NewRequest("PATCH", updateURL, bytes.NewBuffer(jsonData))
+ updateReq, updateCancel, err := httpclient.NewRequest(http.MethodPatch, updateURL, bytes.NewBuffer(jsonData))
if err != nil {
return err
}
+ defer updateCancel()
updateReq.Header.Set("Authorization", "token "+m.codebergToken)
updateReq.Header.Set("Content-Type", "application/json")
- updateResp, err := client.Do(updateReq)
+ updateResp, err := httpclient.Do(updateReq)
if err != nil {
return err
}