Skip to content

Commit b066d1d

Browse files
authored
Merge pull request #429 from paulbalaji/pb/ci-migration
feat(ci): add GitHub Actions -> Depot CI migration workflow
2 parents a0b2b54 + c330b20 commit b066d1d

26 files changed

+4265
-0
lines changed

pkg/api/ci.go

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
package api
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"encoding/json"
7+
"fmt"
8+
"io"
9+
"net/http"
10+
"strings"
11+
)
12+
13+
var baseURLFunc = getBaseURL
14+
15+
func ciRequest[T any](ctx context.Context, token, orgID, path string, payload interface{}) (*T, error) {
16+
var requestBody io.Reader
17+
18+
if payload != nil {
19+
jsonBytes, err := json.Marshal(payload)
20+
if err != nil {
21+
return nil, err
22+
}
23+
requestBody = bytes.NewReader(jsonBytes)
24+
}
25+
26+
url := baseURLFunc() + "/" + path
27+
client := &http.Client{}
28+
req, err := http.NewRequestWithContext(ctx, "POST", url, requestBody)
29+
if err != nil {
30+
return nil, err
31+
}
32+
33+
req.Header.Add("Content-Type", "application/json")
34+
if token != "" {
35+
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
36+
}
37+
if orgID != "" {
38+
req.Header.Add("x-depot-org", orgID)
39+
}
40+
req.Header.Add("User-Agent", Agent())
41+
req.Header.Add("Depot-User-Agent", Agent())
42+
43+
resp, err := client.Do(req)
44+
if err != nil {
45+
return nil, err
46+
}
47+
defer resp.Body.Close()
48+
49+
infoMessage := resp.Header.Get("X-Depot-Info-Message")
50+
if infoMessage != "" {
51+
fmt.Println(infoStyle.Render(infoMessage))
52+
}
53+
54+
warnMessage := resp.Header.Get("X-Depot-Warn-Message")
55+
if warnMessage != "" {
56+
fmt.Println(warnStyle.Render(warnMessage))
57+
}
58+
59+
body, err := io.ReadAll(resp.Body)
60+
if err != nil {
61+
return nil, err
62+
}
63+
64+
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
65+
var errResp ErrorResponse
66+
if err := json.Unmarshal(body, &errResp); err == nil && strings.TrimSpace(errResp.Error) != "" {
67+
return nil, fmt.Errorf("%s", errResp.Error)
68+
}
69+
70+
var connectErr struct {
71+
Code string `json:"code"`
72+
Message string `json:"message"`
73+
}
74+
if err := json.Unmarshal(body, &connectErr); err == nil && strings.TrimSpace(connectErr.Message) != "" {
75+
return nil, fmt.Errorf("%s", connectErr.Message)
76+
}
77+
78+
return nil, fmt.Errorf("API error: status %d", resp.StatusCode)
79+
}
80+
81+
var response T
82+
if len(bytes.TrimSpace(body)) == 0 {
83+
return &response, nil
84+
}
85+
if err := json.Unmarshal(body, &response); err != nil {
86+
return nil, err
87+
}
88+
89+
return &response, nil
90+
}
91+
92+
// CIAddSecret adds a single CI secret to an organization
93+
func CIAddSecret(ctx context.Context, token, orgID, name, value string) error {
94+
return CIAddSecretWithDescription(ctx, token, orgID, name, value, "")
95+
}
96+
97+
// CIAddSecretWithDescription adds a single CI secret to an organization, with an optional description.
98+
func CIAddSecretWithDescription(ctx context.Context, token, orgID, name, value, description string) error {
99+
payload := CISecretAddRequest{
100+
Name: name,
101+
Value: value,
102+
Description: description,
103+
}
104+
_, err := ciRequest[interface{}](ctx, token, orgID, "depot.ci.v1.SecretService/AddSecret", payload)
105+
return err
106+
}
107+
108+
// CIListSecrets lists all CI secrets for an organization
109+
func CIListSecrets(ctx context.Context, token, orgID string) ([]CISecretMeta, error) {
110+
resp, err := ciRequest[CISecretListResponse](ctx, token, orgID, "depot.ci.v1.SecretService/ListSecrets", map[string]interface{}{})
111+
if err != nil {
112+
return nil, err
113+
}
114+
if resp == nil {
115+
return []CISecretMeta{}, nil
116+
}
117+
return resp.Secrets, nil
118+
}
119+
120+
// CIDeleteSecret deletes a CI secret from an organization
121+
func CIDeleteSecret(ctx context.Context, token, orgID, name string) error {
122+
payload := map[string]string{
123+
"name": name,
124+
}
125+
_, err := ciRequest[interface{}](ctx, token, orgID, "depot.ci.v1.SecretService/DeleteSecret", payload)
126+
return err
127+
}
128+
129+
// CIAddVariable adds a single CI variable to an organization
130+
func CIAddVariable(ctx context.Context, token, orgID, name, value string) error {
131+
payload := CIVariableAddRequest{
132+
Name: name,
133+
Value: value,
134+
}
135+
_, err := ciRequest[interface{}](ctx, token, orgID, "depot.ci.v1.VariableService/AddVariable", payload)
136+
return err
137+
}
138+
139+
// CIListVariables lists all CI variables for an organization
140+
func CIListVariables(ctx context.Context, token, orgID string) ([]CIVariableMeta, error) {
141+
resp, err := ciRequest[CIVariableListResponse](ctx, token, orgID, "depot.ci.v1.VariableService/ListVariables", map[string]interface{}{})
142+
if err != nil {
143+
return nil, err
144+
}
145+
if resp == nil {
146+
return []CIVariableMeta{}, nil
147+
}
148+
return resp.Variables, nil
149+
}
150+
151+
// CIDeleteVariable deletes a CI variable from an organization
152+
func CIDeleteVariable(ctx context.Context, token, orgID, name string) error {
153+
payload := map[string]string{
154+
"name": name,
155+
}
156+
_, err := ciRequest[interface{}](ctx, token, orgID, "depot.ci.v1.VariableService/DeleteVariable", payload)
157+
return err
158+
}

0 commit comments

Comments
 (0)