-
Notifications
You must be signed in to change notification settings - Fork 959
Expand file tree
/
Copy pathutil_v4_repository.go
More file actions
186 lines (160 loc) · 5.09 KB
/
util_v4_repository.go
File metadata and controls
186 lines (160 loc) · 5.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package github
import (
"context"
"encoding/base64"
"errors"
"fmt"
"github.com/shurcooL/githubv4"
)
// PullRequestCreationPolicy mirrors the GitHub GraphQL enum type of the same
// name so we can query and mutate the field even when the vendored client
// model lags behind the live schema.
type PullRequestCreationPolicy string
const (
PullRequestCreationPolicyAll PullRequestCreationPolicy = "ALL"
PullRequestCreationPolicyCollaboratorsOnly PullRequestCreationPolicy = "COLLABORATORS_ONLY"
)
// UpdateRepositoryInput intentionally mirrors the GitHub GraphQL input type
// name so the graphql client emits the correct variable type in mutations.
// We only model the fields needed for pullRequestCreationPolicy updates.
type UpdateRepositoryInput struct {
RepositoryID githubv4.ID `json:"repositoryId"`
PullRequestCreationPolicy *PullRequestCreationPolicy `json:"pullRequestCreationPolicy,omitempty"`
ClientMutationID *githubv4.String `json:"clientMutationId,omitempty"`
}
func getRepositoryID(name string, meta any) (githubv4.ID, error) {
// Interpret `name` as a node ID
exists, nodeIDerr := repositoryNodeIDExists(name, meta)
if exists {
return githubv4.ID(name), nil
}
// Interpret `name` as a legacy node ID
exists, _ = repositoryLegacyNodeIDExists(name, meta)
if exists {
return githubv4.ID(name), nil
}
// Could not find repo by node ID, interpret `name` as repo name
var query struct {
Repository struct {
ID githubv4.ID
} `graphql:"repository(owner:$owner, name:$name)"`
}
variables := map[string]any{
"owner": githubv4.String(meta.(*Owner).name),
"name": githubv4.String(name),
}
ctx := context.Background()
client := meta.(*Owner).v4client
nameErr := client.Query(ctx, &query, variables)
if nameErr != nil {
if nodeIDerr != nil {
// Could not find repo by node ID or repo name, return both errors
return nil, errors.New(nodeIDerr.Error() + nameErr.Error())
}
return nil, nameErr
}
return query.Repository.ID, nil
}
func repositoryNodeIDExists(name string, meta any) (bool, error) {
// API check if node ID exists
var query struct {
Node struct {
ID githubv4.ID
} `graphql:"node(id:$id)"`
}
variables := map[string]any{
"id": githubv4.ID(name),
}
ctx := context.Background()
client := meta.(*Owner).v4client
err := client.Query(ctx, &query, variables)
if err != nil {
return false, err
}
return query.Node.ID.(string) == name, nil
}
func flattenPullRequestCreationPolicy(policy PullRequestCreationPolicy) (string, error) {
switch policy {
case PullRequestCreationPolicyAll:
return "all", nil
case PullRequestCreationPolicyCollaboratorsOnly:
return "collaborators_only", nil
case "":
return "", nil
default:
return "", fmt.Errorf("unsupported GraphQL pull request creation policy %q", policy)
}
}
func expandPullRequestCreationPolicy(policy string) (PullRequestCreationPolicy, error) {
switch policy {
case "all":
return PullRequestCreationPolicyAll, nil
case "collaborators_only":
return PullRequestCreationPolicyCollaboratorsOnly, nil
default:
return "", fmt.Errorf("unsupported Terraform pull request creation policy %q", policy)
}
}
func getRepositoryPullRequestCreationPolicy(ctx context.Context, owner, name string, meta any) (string, error) {
var query struct {
Repository struct {
PullRequestCreationPolicy PullRequestCreationPolicy
} `graphql:"repository(owner:$owner, name:$name)"`
}
variables := map[string]any{
"owner": githubv4.String(owner),
"name": githubv4.String(name),
}
client := meta.(*Owner).v4client
if err := client.Query(ctx, &query, variables); err != nil {
return "", err
}
return flattenPullRequestCreationPolicy(query.Repository.PullRequestCreationPolicy)
}
func updateRepositoryPullRequestCreationPolicy(ctx context.Context, repositoryID githubv4.ID, policy string, meta any) error {
expandedPolicy, err := expandPullRequestCreationPolicy(policy)
if err != nil {
return err
}
input := UpdateRepositoryInput{
RepositoryID: repositoryID,
PullRequestCreationPolicy: &expandedPolicy,
}
var mutation struct {
UpdateRepository struct {
Repository struct {
ID githubv4.ID
}
} `graphql:"updateRepository(input:$input)"`
}
client := meta.(*Owner).v4client
return client.Mutate(ctx, &mutation, input, nil)
}
// Maintain compatibility with deprecated Global ID format
// https://github.blog/2021-02-10-new-global-id-format-coming-to-graphql/
func repositoryLegacyNodeIDExists(name string, meta any) (bool, error) {
// Check if the name is a base 64 encoded node ID
if _, err := base64.StdEncoding.DecodeString(name); err != nil {
var corrErr base64.CorruptInputError
ok := errors.As(err, &corrErr)
if ok {
return false, nil
}
return false, err
}
// API check if node ID exists
var query struct {
Node struct {
ID githubv4.ID
} `graphql:"node(id:$id)"`
}
variables := map[string]any{
"id": githubv4.ID(name),
}
ctx := context.Background()
client := meta.(*Owner).v4client
if err := client.Query(ctx, &query, variables); err != nil {
return false, err
}
return query.Node.ID.(string) == name, nil
}