Skip to content

Commit a58deef

Browse files
committed
Update branch protection for archiving repos
1 parent 94f71cf commit a58deef

File tree

4 files changed

+107
-11
lines changed

4 files changed

+107
-11
lines changed

github/resource_github_branch_protection.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ func resourceGithubBranchProtection() *schema.Resource {
133133
PROTECTION_REQUIRED_STATUS_CHECK_CONTEXTS: {
134134
Type: schema.TypeSet,
135135
Optional: true,
136+
Computed: true,
137+
Deprecated: "GitHub is deprecating the use of `contexts`. Use a `checks` array instead.",
136138
Description: "The list of status checks to require in order to merge into this branch. No status checks are required by default.",
137139
Elem: &schema.Schema{Type: schema.TypeString},
138140
},
@@ -293,6 +295,12 @@ func resourceGithubBranchProtectionRead(d *schema.ResourceData, meta any) error
293295
}
294296
protection := query.Node.Node
295297

298+
if protection.Repository.IsArchived {
299+
log.Printf("[INFO] Removing branch protection (%s) from state because the repository (%s) is archived", d.Id(), protection.Repository.Name)
300+
d.SetId("")
301+
return nil
302+
}
303+
296304
err = d.Set(PROTECTION_PATTERN, protection.Pattern)
297305
if err != nil {
298306
log.Printf("[DEBUG] Problem setting '%s' in %s %s branch protection (%s)", PROTECTION_PATTERN, protection.Repository.Name, protection.Pattern, d.Id())
@@ -366,6 +374,25 @@ func resourceGithubBranchProtectionRead(d *schema.ResourceData, meta any) error
366374
}
367375

368376
func resourceGithubBranchProtectionUpdate(d *schema.ResourceData, meta any) error {
377+
var query struct {
378+
Node struct {
379+
Node BranchProtectionRule `graphql:"... on BranchProtectionRule"`
380+
} `graphql:"node(id: $id)"`
381+
}
382+
variables := map[string]any{
383+
"id": d.Id(),
384+
}
385+
ctx := context.WithValue(context.Background(), ctxId, d.Id())
386+
client := meta.(*Owner).v4client
387+
err := client.Query(ctx, &query, variables)
388+
if err == nil {
389+
protection := query.Node.Node
390+
if protection.Repository.IsArchived {
391+
log.Printf("[INFO] Skipping update of branch protection (%s) because the repository (%s) is archived", d.Id(), protection.Repository.Name)
392+
return nil
393+
}
394+
}
395+
369396
var mutate struct {
370397
UpdateBranchProtectionRule struct {
371398
BranchProtectionRule struct {
@@ -444,6 +471,25 @@ func resourceGithubBranchProtectionUpdate(d *schema.ResourceData, meta any) erro
444471
}
445472

446473
func resourceGithubBranchProtectionDelete(d *schema.ResourceData, meta any) error {
474+
var query struct {
475+
Node struct {
476+
Node BranchProtectionRule `graphql:"... on BranchProtectionRule"`
477+
} `graphql:"node(id: $id)"`
478+
}
479+
variables := map[string]any{
480+
"id": d.Id(),
481+
}
482+
ctx := context.WithValue(context.Background(), ctxId, d.Id())
483+
client := meta.(*Owner).v4client
484+
err := client.Query(ctx, &query, variables)
485+
if err == nil {
486+
protection := query.Node.Node
487+
if protection.Repository.IsArchived {
488+
log.Printf("[INFO] Skipping deletion of branch protection (%s) because the repository (%s) is archived", d.Id(), protection.Repository.Name)
489+
return nil
490+
}
491+
}
492+
447493
var mutate struct {
448494
DeleteBranchProtectionRule struct { // Empty struct does not work
449495
ClientMutationId githubv4.ID

github/resource_github_branch_protection_v3.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,26 @@ func resourceGithubBranchProtectionV3Read(d *schema.ResourceData, meta any) erro
275275
orgName := meta.(*Owner).name
276276

277277
ctx := context.WithValue(context.Background(), ctxId, d.Id())
278+
279+
repo, _, err := client.Repositories.Get(ctx, orgName, repoName)
280+
if err != nil {
281+
var ghErr *github.ErrorResponse
282+
if errors.As(err, &ghErr) {
283+
if ghErr.Response.StatusCode == http.StatusNotFound {
284+
log.Printf("[INFO] Removing branch protection %s/%s (%s) from state because the repository no longer exists",
285+
orgName, repoName, branch)
286+
d.SetId("")
287+
return nil
288+
}
289+
}
290+
return err
291+
}
292+
if repo.GetArchived() {
293+
log.Printf("[INFO] Removing branch protection %s/%s (%s) from state because the repository is archived", orgName, repoName, branch)
294+
d.SetId("")
295+
return nil
296+
}
297+
278298
if !d.IsNewResource() {
279299
ctx = context.WithValue(ctx, ctxEtag, d.Get("etag").(string))
280300
}
@@ -349,6 +369,16 @@ func resourceGithubBranchProtectionV3Update(d *schema.ResourceData, meta any) er
349369
if err != nil {
350370
return err
351371
}
372+
orgName := meta.(*Owner).name
373+
ctx := context.WithValue(context.Background(), ctxId, d.Id())
374+
375+
repo, _, err := client.Repositories.Get(ctx, orgName, repoName)
376+
if err == nil {
377+
if repo.GetArchived() {
378+
log.Printf("[INFO] Skipping update of branch protection %s/%s (%s) because the repository is archived", orgName, repoName, branch)
379+
return nil
380+
}
381+
}
352382

353383
protectionRequest, err := buildProtectionRequest(d)
354384
if err != nil {
@@ -407,6 +437,14 @@ func resourceGithubBranchProtectionV3Delete(d *schema.ResourceData, meta any) er
407437
orgName := meta.(*Owner).name
408438
ctx := context.WithValue(context.Background(), ctxId, d.Id())
409439

440+
repo, _, err := client.Repositories.Get(ctx, orgName, repoName)
441+
if err == nil {
442+
if repo.GetArchived() {
443+
log.Printf("[INFO] Skipping deletion of branch protection %s/%s (%s) because the repository is archived", orgName, repoName, branch)
444+
return nil
445+
}
446+
}
447+
410448
_, err = client.Repositories.RemoveBranchProtection(ctx,
411449
orgName, repoName, branch)
412450
return err

github/resource_github_branch_protection_v3_utils.go

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,29 @@ func flattenAndSetRequiredStatusChecks(d *schema.ResourceData, protection *githu
5050

5151
// TODO: Remove once contexts is fully deprecated.
5252
// Flatten contexts
53-
for _, c := range *rsc.Contexts {
54-
// Parse into contexts
55-
contexts = append(contexts, c)
53+
if rsc.Contexts != nil {
54+
for _, c := range *rsc.Contexts {
55+
// Parse into contexts
56+
contexts = append(contexts, c)
57+
}
58+
}
59+
60+
// Fallback to populating contexts from checks if it's empty (e.g. archived repo)
61+
if len(contexts) == 0 && rsc.Checks != nil {
62+
for _, chk := range *rsc.Checks {
63+
contexts = append(contexts, chk.Context)
64+
}
5665
}
5766

5867
// Flatten checks
59-
for _, chk := range *rsc.Checks {
60-
// Parse into checks
61-
if chk.AppID != nil {
62-
checks = append(checks, fmt.Sprintf("%s:%d", chk.Context, *chk.AppID))
63-
} else {
64-
checks = append(checks, chk.Context)
68+
if rsc.Checks != nil {
69+
for _, chk := range *rsc.Checks {
70+
// Parse into checks
71+
if chk.AppID != nil {
72+
checks = append(checks, fmt.Sprintf("%s:%d", chk.Context, *chk.AppID))
73+
} else {
74+
checks = append(checks, chk.Context)
75+
}
6576
}
6677
}
6778

github/util_v4_branch_protection.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ type PushActorTypes struct {
5656

5757
type BranchProtectionRule struct {
5858
Repository struct {
59-
ID githubv4.String
60-
Name githubv4.String
59+
ID githubv4.String
60+
Name githubv4.String
61+
IsArchived githubv4.Boolean
6162
}
6263
PushAllowances struct {
6364
Nodes []PushActorTypes

0 commit comments

Comments
 (0)