44c05fece4
Adds error handling for non-OK HTTP status codes in the client. Implements custom error messages by reading the response body when the status code indicates an error, ensuring better debugging and clarity during failures. Enhances unit tests to cover unauthorized access and incorrect body length scenarios, validating the error handling mechanism.
123 lines
3.3 KiB
Go
123 lines
3.3 KiB
Go
package gitlab
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func New(token string) *RestClient {
|
|
return &RestClient{token: token, client: http.DefaultClient, baseUrl: "https://gitlab.com"}
|
|
}
|
|
|
|
type RestClient struct {
|
|
client *http.Client
|
|
token string
|
|
baseUrl string
|
|
}
|
|
|
|
func (r *RestClient) UpdateCleanupPolicy(project string, versions []string) error {
|
|
options := ProjectConfig{
|
|
ContainerExpirationPolicyAttributes: ContainerExpirationPolicyAttributes{
|
|
Cadence: "1d",
|
|
Enabled: true,
|
|
KeepN: 10,
|
|
OlderThan: "14d",
|
|
NameRegex: ".*",
|
|
NameRegexKeep: fmt.Sprintf("(main|master|%s)", strings.Join(versions, "|")),
|
|
},
|
|
}
|
|
buff := &bytes.Buffer{}
|
|
encoder := json.NewEncoder(buff)
|
|
err := encoder.Encode(&options)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return r.projectApiCall("PUT", project, "", io.NopCloser(buff), nil)
|
|
}
|
|
|
|
func (r *RestClient) GetTags(project string) ([]Tag, error) {
|
|
var tags []Tag
|
|
err := r.projectApiCall("GET", project, "/repository/tags", nil, &tags)
|
|
return tags, err
|
|
}
|
|
|
|
func (r *RestClient) projectApiCall(method, project string, api string, body io.ReadCloser, response interface{}) error {
|
|
encoded := url.QueryEscape(project)
|
|
reqUrl, err := url.Parse(fmt.Sprintf("%s/api/v4/projects/%s%s", r.baseUrl, encoded, api))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
header := http.Header{}
|
|
header.Add("Content-Type", "application/json;charset=UTF-8")
|
|
header.Add("PRIVATE-TOKEN", r.token)
|
|
req := &http.Request{
|
|
Method: method,
|
|
URL: reqUrl,
|
|
Header: header,
|
|
Body: body,
|
|
}
|
|
resp, err := r.client.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if resp.StatusCode == http.StatusOK && response != nil {
|
|
decoder := json.NewDecoder(resp.Body)
|
|
err = decoder.Decode(response)
|
|
} else if resp.StatusCode != http.StatusOK {
|
|
buff, err2 := io.ReadAll(resp.Body)
|
|
if err2 != nil {
|
|
return fmt.Errorf("error reading body: %w", err2)
|
|
}
|
|
return fmt.Errorf("status %d: %s", resp.StatusCode, string(buff))
|
|
}
|
|
return err
|
|
}
|
|
|
|
type ProjectConfig struct {
|
|
ContainerExpirationPolicyAttributes ContainerExpirationPolicyAttributes `json:"container_expiration_policy_attributes"`
|
|
}
|
|
|
|
type ContainerExpirationPolicyAttributes struct {
|
|
Cadence string `json:"cadence"`
|
|
Enabled bool `json:"enabled"`
|
|
KeepN int `json:"keep_n"`
|
|
OlderThan string `json:"older_than"`
|
|
NameRegex string `json:"name_regex"`
|
|
NameRegexKeep string `json:"name_regex_keep"`
|
|
}
|
|
|
|
type Tag struct {
|
|
Commit Commit `json:"commit"`
|
|
Release Release `json:"release"`
|
|
Name string `json:"name"`
|
|
Target string `json:"target"`
|
|
Message interface{} `json:"message"`
|
|
Protected bool `json:"protected"`
|
|
}
|
|
|
|
type Commit struct {
|
|
ID string `json:"id"`
|
|
ShortID string `json:"short_id"`
|
|
Title string `json:"title"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
ParentIds []string `json:"parent_ids"`
|
|
Message string `json:"message"`
|
|
AuthorName string `json:"author_name"`
|
|
AuthorEmail string `json:"author_email"`
|
|
AuthoredDate string `json:"authored_date"`
|
|
CommitterName string `json:"committer_name"`
|
|
CommitterEmail string `json:"committer_email"`
|
|
CommittedDate string `json:"committed_date"`
|
|
}
|
|
|
|
type Release struct {
|
|
TagName string `json:"tag_name"`
|
|
Description string `json:"description"`
|
|
}
|