github.com/google/go-github/v64@v64.0.0/github/orgs_rules_test.go (about) 1 // Copyright 2023 The go-github AUTHORS. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 package github 7 8 import ( 9 "context" 10 "fmt" 11 "net/http" 12 "testing" 13 14 "github.com/google/go-cmp/cmp" 15 ) 16 17 func TestOrganizationsService_GetAllOrganizationRulesets(t *testing.T) { 18 client, mux, _, teardown := setup() 19 defer teardown() 20 21 mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { 22 testMethod(t, r, "GET") 23 fmt.Fprint(w, `[{ 24 "id": 26110, 25 "name": "test ruleset", 26 "target": "branch", 27 "source_type": "Organization", 28 "source": "o", 29 "enforcement": "active", 30 "bypass_mode": "none", 31 "node_id": "nid", 32 "_links": { 33 "self": { 34 "href": "https://api.github.com/orgs/o/rulesets/26110" 35 } 36 } 37 }]`) 38 }) 39 40 ctx := context.Background() 41 rulesets, _, err := client.Organizations.GetAllOrganizationRulesets(ctx, "o") 42 if err != nil { 43 t.Errorf("Organizations.GetAllOrganizationRulesets returned error: %v", err) 44 } 45 46 want := []*Ruleset{{ 47 ID: Int64(26110), 48 Name: "test ruleset", 49 Target: String("branch"), 50 SourceType: String("Organization"), 51 Source: "o", 52 Enforcement: "active", 53 NodeID: String("nid"), 54 Links: &RulesetLinks{ 55 Self: &RulesetLink{HRef: String("https://api.github.com/orgs/o/rulesets/26110")}, 56 }, 57 }} 58 if !cmp.Equal(rulesets, want) { 59 t.Errorf("Organizations.GetAllOrganizationRulesets returned %+v, want %+v", rulesets, want) 60 } 61 62 const methodName = "GetAllOrganizationRulesets" 63 64 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 65 got, resp, err := client.Organizations.GetAllOrganizationRulesets(ctx, "o") 66 if got != nil { 67 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 68 } 69 return resp, err 70 }) 71 } 72 73 func TestOrganizationsService_CreateOrganizationRuleset_RepoNames(t *testing.T) { 74 client, mux, _, teardown := setup() 75 defer teardown() 76 77 mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { 78 testMethod(t, r, "POST") 79 fmt.Fprint(w, `{ 80 "id": 21, 81 "name": "ruleset", 82 "target": "branch", 83 "source_type": "Organization", 84 "source": "o", 85 "enforcement": "active", 86 "bypass_actors": [ 87 { 88 "actor_id": 234, 89 "actor_type": "Team" 90 } 91 ], 92 "conditions": { 93 "ref_name": { 94 "include": [ 95 "refs/heads/main", 96 "refs/heads/master" 97 ], 98 "exclude": [ 99 "refs/heads/dev*" 100 ] 101 }, 102 "repository_name": { 103 "include": [ 104 "important_repository", 105 "another_important_repository" 106 ], 107 "exclude": [ 108 "unimportant_repository" 109 ], 110 "protected": true 111 } 112 }, 113 "rules": [ 114 { 115 "type": "creation" 116 }, 117 { 118 "type": "update", 119 "parameters": { 120 "update_allows_fetch_and_merge": true 121 } 122 }, 123 { 124 "type": "deletion" 125 }, 126 { 127 "type": "merge_queue" 128 }, 129 { 130 "type": "required_linear_history" 131 }, 132 { 133 "type": "required_deployments", 134 "parameters": { 135 "required_deployment_environments": ["test"] 136 } 137 }, 138 { 139 "type": "required_signatures" 140 }, 141 { 142 "type": "pull_request", 143 "parameters": { 144 "dismiss_stale_reviews_on_push": true, 145 "require_code_owner_review": true, 146 "require_last_push_approval": true, 147 "required_approving_review_count": 1, 148 "required_review_thread_resolution": true 149 } 150 }, 151 { 152 "type": "required_status_checks", 153 "parameters": { 154 "required_status_checks": [ 155 { 156 "context": "test", 157 "integration_id": 1 158 } 159 ], 160 "strict_required_status_checks_policy": true 161 } 162 }, 163 { 164 "type": "non_fast_forward" 165 }, 166 { 167 "type": "commit_message_pattern", 168 "parameters": { 169 "name": "avoid test commits", 170 "negate": true, 171 "operator": "starts_with", 172 "pattern": "[test]" 173 } 174 }, 175 { 176 "type": "commit_author_email_pattern", 177 "parameters": { 178 "operator": "contains", 179 "pattern": "github" 180 } 181 }, 182 { 183 "type": "committer_email_pattern", 184 "parameters": { 185 "name": "avoid commit emails", 186 "negate": true, 187 "operator": "ends_with", 188 "pattern": "abc" 189 } 190 }, 191 { 192 "type": "branch_name_pattern", 193 "parameters": { 194 "name": "avoid branch names", 195 "negate": true, 196 "operator": "regex", 197 "pattern": "github$" 198 } 199 }, 200 { 201 "type": "tag_name_pattern", 202 "parameters": { 203 "name": "avoid tag names", 204 "negate": true, 205 "operator": "contains", 206 "pattern": "github" 207 } 208 } 209 ] 210 }`) 211 }) 212 213 ctx := context.Background() 214 ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", &Ruleset{ 215 ID: Int64(21), 216 Name: "ruleset", 217 Target: String("branch"), 218 SourceType: String("Organization"), 219 Source: "o", 220 Enforcement: "active", 221 BypassActors: []*BypassActor{ 222 { 223 ActorID: Int64(234), 224 ActorType: String("Team"), 225 }, 226 }, 227 Conditions: &RulesetConditions{ 228 RefName: &RulesetRefConditionParameters{ 229 Include: []string{"refs/heads/main", "refs/heads/master"}, 230 Exclude: []string{"refs/heads/dev*"}, 231 }, 232 RepositoryName: &RulesetRepositoryNamesConditionParameters{ 233 Include: []string{"important_repository", "another_important_repository"}, 234 Exclude: []string{"unimportant_repository"}, 235 Protected: Bool(true), 236 }, 237 }, 238 Rules: []*RepositoryRule{ 239 NewCreationRule(), 240 NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ 241 UpdateAllowsFetchAndMerge: true, 242 }), 243 NewDeletionRule(), 244 NewMergeQueueRule(), 245 NewRequiredLinearHistoryRule(), 246 NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{ 247 RequiredDeploymentEnvironments: []string{"test"}, 248 }), 249 NewRequiredSignaturesRule(), 250 NewPullRequestRule(&PullRequestRuleParameters{ 251 RequireCodeOwnerReview: true, 252 RequireLastPushApproval: true, 253 RequiredApprovingReviewCount: 1, 254 RequiredReviewThreadResolution: true, 255 DismissStaleReviewsOnPush: true, 256 }), 257 NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ 258 RequiredStatusChecks: []RuleRequiredStatusChecks{ 259 { 260 Context: "test", 261 IntegrationID: Int64(1), 262 }, 263 }, 264 StrictRequiredStatusChecksPolicy: true, 265 }), 266 NewNonFastForwardRule(), 267 NewCommitMessagePatternRule(&RulePatternParameters{ 268 Name: String("avoid test commits"), 269 Negate: Bool(true), 270 Operator: "starts_with", 271 Pattern: "[test]", 272 }), 273 NewCommitAuthorEmailPatternRule(&RulePatternParameters{ 274 Operator: "contains", 275 Pattern: "github", 276 }), 277 NewCommitterEmailPatternRule(&RulePatternParameters{ 278 Name: String("avoid commit emails"), 279 Negate: Bool(true), 280 Operator: "ends_with", 281 Pattern: "abc", 282 }), 283 NewBranchNamePatternRule(&RulePatternParameters{ 284 Name: String("avoid branch names"), 285 Negate: Bool(true), 286 Operator: "regex", 287 Pattern: "github$", 288 }), 289 NewTagNamePatternRule(&RulePatternParameters{ 290 Name: String("avoid tag names"), 291 Negate: Bool(true), 292 Operator: "contains", 293 Pattern: "github", 294 }), 295 }, 296 }) 297 if err != nil { 298 t.Errorf("Organizations.CreateOrganizationRuleset returned error: %v", err) 299 } 300 301 want := &Ruleset{ 302 ID: Int64(21), 303 Name: "ruleset", 304 Target: String("branch"), 305 SourceType: String("Organization"), 306 Source: "o", 307 Enforcement: "active", 308 BypassActors: []*BypassActor{ 309 { 310 ActorID: Int64(234), 311 ActorType: String("Team"), 312 }, 313 }, 314 Conditions: &RulesetConditions{ 315 RefName: &RulesetRefConditionParameters{ 316 Include: []string{"refs/heads/main", "refs/heads/master"}, 317 Exclude: []string{"refs/heads/dev*"}, 318 }, 319 RepositoryName: &RulesetRepositoryNamesConditionParameters{ 320 Include: []string{"important_repository", "another_important_repository"}, 321 Exclude: []string{"unimportant_repository"}, 322 Protected: Bool(true), 323 }, 324 }, 325 Rules: []*RepositoryRule{ 326 NewCreationRule(), 327 NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ 328 UpdateAllowsFetchAndMerge: true, 329 }), 330 NewDeletionRule(), 331 NewMergeQueueRule(), 332 NewRequiredLinearHistoryRule(), 333 NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{ 334 RequiredDeploymentEnvironments: []string{"test"}, 335 }), 336 NewRequiredSignaturesRule(), 337 NewPullRequestRule(&PullRequestRuleParameters{ 338 RequireCodeOwnerReview: true, 339 RequireLastPushApproval: true, 340 RequiredApprovingReviewCount: 1, 341 RequiredReviewThreadResolution: true, 342 DismissStaleReviewsOnPush: true, 343 }), 344 NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ 345 RequiredStatusChecks: []RuleRequiredStatusChecks{ 346 { 347 Context: "test", 348 IntegrationID: Int64(1), 349 }, 350 }, 351 StrictRequiredStatusChecksPolicy: true, 352 }), 353 NewNonFastForwardRule(), 354 NewCommitMessagePatternRule(&RulePatternParameters{ 355 Name: String("avoid test commits"), 356 Negate: Bool(true), 357 Operator: "starts_with", 358 Pattern: "[test]", 359 }), 360 NewCommitAuthorEmailPatternRule(&RulePatternParameters{ 361 Operator: "contains", 362 Pattern: "github", 363 }), 364 NewCommitterEmailPatternRule(&RulePatternParameters{ 365 Name: String("avoid commit emails"), 366 Negate: Bool(true), 367 Operator: "ends_with", 368 Pattern: "abc", 369 }), 370 NewBranchNamePatternRule(&RulePatternParameters{ 371 Name: String("avoid branch names"), 372 Negate: Bool(true), 373 Operator: "regex", 374 Pattern: "github$", 375 }), 376 NewTagNamePatternRule(&RulePatternParameters{ 377 Name: String("avoid tag names"), 378 Negate: Bool(true), 379 Operator: "contains", 380 Pattern: "github", 381 }), 382 }, 383 } 384 if !cmp.Equal(ruleset, want) { 385 t.Errorf("Organizations.CreateOrganizationRuleset returned %+v, want %+v", ruleset, want) 386 } 387 388 const methodName = "CreateOrganizationRuleset" 389 390 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 391 got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", nil) 392 if got != nil { 393 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 394 } 395 return resp, err 396 }) 397 } 398 func TestOrganizationsService_CreateOrganizationRuleset_RepoProperty(t *testing.T) { 399 client, mux, _, teardown := setup() 400 defer teardown() 401 402 mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { 403 testMethod(t, r, "POST") 404 fmt.Fprint(w, `{ 405 "id": 21, 406 "name": "ruleset", 407 "target": "branch", 408 "source_type": "Organization", 409 "source": "o", 410 "enforcement": "active", 411 "bypass_actors": [ 412 { 413 "actor_id": 234, 414 "actor_type": "Team" 415 } 416 ], 417 "conditions": { 418 "repository_property": { 419 "include": [ 420 { 421 "name": "testIncludeProp", 422 "source": "custom", 423 "property_values": [ 424 "true" 425 ] 426 } 427 ], 428 "exclude": [ 429 { 430 "name": "testExcludeProp", 431 "source": "custom", 432 "property_values": [ 433 "false" 434 ] 435 } 436 ] 437 } 438 }, 439 "rules": [ 440 { 441 "type": "creation" 442 }, 443 { 444 "type": "update", 445 "parameters": { 446 "update_allows_fetch_and_merge": true 447 } 448 }, 449 { 450 "type": "deletion" 451 }, 452 { 453 "type": "merge_queue" 454 }, 455 { 456 "type": "required_linear_history" 457 }, 458 { 459 "type": "required_deployments", 460 "parameters": { 461 "required_deployment_environments": ["test"] 462 } 463 }, 464 { 465 "type": "required_signatures" 466 }, 467 { 468 "type": "pull_request", 469 "parameters": { 470 "dismiss_stale_reviews_on_push": true, 471 "require_code_owner_review": true, 472 "require_last_push_approval": true, 473 "required_approving_review_count": 1, 474 "required_review_thread_resolution": true 475 } 476 }, 477 { 478 "type": "required_status_checks", 479 "parameters": { 480 "required_status_checks": [ 481 { 482 "context": "test", 483 "integration_id": 1 484 } 485 ], 486 "strict_required_status_checks_policy": true 487 } 488 }, 489 { 490 "type": "non_fast_forward" 491 }, 492 { 493 "type": "commit_message_pattern", 494 "parameters": { 495 "name": "avoid test commits", 496 "negate": true, 497 "operator": "starts_with", 498 "pattern": "[test]" 499 } 500 }, 501 { 502 "type": "commit_author_email_pattern", 503 "parameters": { 504 "operator": "contains", 505 "pattern": "github" 506 } 507 }, 508 { 509 "type": "committer_email_pattern", 510 "parameters": { 511 "name": "avoid commit emails", 512 "negate": true, 513 "operator": "ends_with", 514 "pattern": "abc" 515 } 516 }, 517 { 518 "type": "branch_name_pattern", 519 "parameters": { 520 "name": "avoid branch names", 521 "negate": true, 522 "operator": "regex", 523 "pattern": "github$" 524 } 525 }, 526 { 527 "type": "tag_name_pattern", 528 "parameters": { 529 "name": "avoid tag names", 530 "negate": true, 531 "operator": "contains", 532 "pattern": "github" 533 } 534 } 535 ] 536 }`) 537 }) 538 539 ctx := context.Background() 540 ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", &Ruleset{ 541 ID: Int64(21), 542 Name: "ruleset", 543 Target: String("branch"), 544 SourceType: String("Organization"), 545 Source: "o", 546 Enforcement: "active", 547 BypassActors: []*BypassActor{ 548 { 549 ActorID: Int64(234), 550 ActorType: String("Team"), 551 }, 552 }, 553 Conditions: &RulesetConditions{ 554 RepositoryProperty: &RulesetRepositoryPropertyConditionParameters{ 555 Include: []RulesetRepositoryPropertyTargetParameters{ 556 { 557 Name: "testIncludeProp", 558 Values: []string{"true"}, 559 }, 560 }, 561 Exclude: []RulesetRepositoryPropertyTargetParameters{ 562 { 563 Name: "testExcludeProp", 564 Values: []string{"false"}, 565 }, 566 }, 567 }, 568 }, 569 Rules: []*RepositoryRule{ 570 NewCreationRule(), 571 NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ 572 UpdateAllowsFetchAndMerge: true, 573 }), 574 NewDeletionRule(), 575 NewMergeQueueRule(), 576 NewRequiredLinearHistoryRule(), 577 NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{ 578 RequiredDeploymentEnvironments: []string{"test"}, 579 }), 580 NewRequiredSignaturesRule(), 581 NewPullRequestRule(&PullRequestRuleParameters{ 582 RequireCodeOwnerReview: true, 583 RequireLastPushApproval: true, 584 RequiredApprovingReviewCount: 1, 585 RequiredReviewThreadResolution: true, 586 DismissStaleReviewsOnPush: true, 587 }), 588 NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ 589 RequiredStatusChecks: []RuleRequiredStatusChecks{ 590 { 591 Context: "test", 592 IntegrationID: Int64(1), 593 }, 594 }, 595 StrictRequiredStatusChecksPolicy: true, 596 }), 597 NewNonFastForwardRule(), 598 NewCommitMessagePatternRule(&RulePatternParameters{ 599 Name: String("avoid test commits"), 600 Negate: Bool(true), 601 Operator: "starts_with", 602 Pattern: "[test]", 603 }), 604 NewCommitAuthorEmailPatternRule(&RulePatternParameters{ 605 Operator: "contains", 606 Pattern: "github", 607 }), 608 NewCommitterEmailPatternRule(&RulePatternParameters{ 609 Name: String("avoid commit emails"), 610 Negate: Bool(true), 611 Operator: "ends_with", 612 Pattern: "abc", 613 }), 614 NewBranchNamePatternRule(&RulePatternParameters{ 615 Name: String("avoid branch names"), 616 Negate: Bool(true), 617 Operator: "regex", 618 Pattern: "github$", 619 }), 620 NewTagNamePatternRule(&RulePatternParameters{ 621 Name: String("avoid tag names"), 622 Negate: Bool(true), 623 Operator: "contains", 624 Pattern: "github", 625 }), 626 }, 627 }) 628 if err != nil { 629 t.Errorf("Organizations.CreateOrganizationRuleset returned error: %v", err) 630 } 631 632 want := &Ruleset{ 633 ID: Int64(21), 634 Name: "ruleset", 635 Target: String("branch"), 636 SourceType: String("Organization"), 637 Source: "o", 638 Enforcement: "active", 639 BypassActors: []*BypassActor{ 640 { 641 ActorID: Int64(234), 642 ActorType: String("Team"), 643 }, 644 }, 645 Conditions: &RulesetConditions{ 646 RepositoryProperty: &RulesetRepositoryPropertyConditionParameters{ 647 Include: []RulesetRepositoryPropertyTargetParameters{ 648 { 649 Name: "testIncludeProp", 650 Values: []string{"true"}, 651 }, 652 }, 653 Exclude: []RulesetRepositoryPropertyTargetParameters{ 654 { 655 Name: "testExcludeProp", 656 Values: []string{"false"}, 657 }, 658 }, 659 }, 660 }, 661 Rules: []*RepositoryRule{ 662 NewCreationRule(), 663 NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ 664 UpdateAllowsFetchAndMerge: true, 665 }), 666 NewDeletionRule(), 667 NewMergeQueueRule(), 668 NewRequiredLinearHistoryRule(), 669 NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{ 670 RequiredDeploymentEnvironments: []string{"test"}, 671 }), 672 NewRequiredSignaturesRule(), 673 NewPullRequestRule(&PullRequestRuleParameters{ 674 RequireCodeOwnerReview: true, 675 RequireLastPushApproval: true, 676 RequiredApprovingReviewCount: 1, 677 RequiredReviewThreadResolution: true, 678 DismissStaleReviewsOnPush: true, 679 }), 680 NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ 681 RequiredStatusChecks: []RuleRequiredStatusChecks{ 682 { 683 Context: "test", 684 IntegrationID: Int64(1), 685 }, 686 }, 687 StrictRequiredStatusChecksPolicy: true, 688 }), 689 NewNonFastForwardRule(), 690 NewCommitMessagePatternRule(&RulePatternParameters{ 691 Name: String("avoid test commits"), 692 Negate: Bool(true), 693 Operator: "starts_with", 694 Pattern: "[test]", 695 }), 696 NewCommitAuthorEmailPatternRule(&RulePatternParameters{ 697 Operator: "contains", 698 Pattern: "github", 699 }), 700 NewCommitterEmailPatternRule(&RulePatternParameters{ 701 Name: String("avoid commit emails"), 702 Negate: Bool(true), 703 Operator: "ends_with", 704 Pattern: "abc", 705 }), 706 NewBranchNamePatternRule(&RulePatternParameters{ 707 Name: String("avoid branch names"), 708 Negate: Bool(true), 709 Operator: "regex", 710 Pattern: "github$", 711 }), 712 NewTagNamePatternRule(&RulePatternParameters{ 713 Name: String("avoid tag names"), 714 Negate: Bool(true), 715 Operator: "contains", 716 Pattern: "github", 717 }), 718 }, 719 } 720 if !cmp.Equal(ruleset, want) { 721 t.Errorf("Organizations.CreateOrganizationRuleset returned %+v, want %+v", ruleset, want) 722 } 723 724 const methodName = "CreateOrganizationRuleset" 725 726 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 727 got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", nil) 728 if got != nil { 729 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 730 } 731 return resp, err 732 }) 733 } 734 func TestOrganizationsService_CreateOrganizationRuleset_RepoIDs(t *testing.T) { 735 client, mux, _, teardown := setup() 736 defer teardown() 737 738 mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { 739 testMethod(t, r, "POST") 740 fmt.Fprint(w, `{ 741 "id": 21, 742 "name": "ruleset", 743 "target": "branch", 744 "source_type": "Organization", 745 "source": "o", 746 "enforcement": "active", 747 "bypass_actors": [ 748 { 749 "actor_id": 234, 750 "actor_type": "Team" 751 } 752 ], 753 "conditions": { 754 "ref_name": { 755 "include": [ 756 "refs/heads/main", 757 "refs/heads/master" 758 ], 759 "exclude": [ 760 "refs/heads/dev*" 761 ] 762 }, 763 "repository_id": { 764 "repository_ids": [ 123, 456 ] 765 } 766 }, 767 "rules": [ 768 { 769 "type": "creation" 770 }, 771 { 772 "type": "update", 773 "parameters": { 774 "update_allows_fetch_and_merge": true 775 } 776 }, 777 { 778 "type": "deletion" 779 }, 780 { 781 "type": "merge_queue" 782 }, 783 { 784 "type": "required_linear_history" 785 }, 786 { 787 "type": "required_deployments", 788 "parameters": { 789 "required_deployment_environments": ["test"] 790 } 791 }, 792 { 793 "type": "required_signatures" 794 }, 795 { 796 "type": "pull_request", 797 "parameters": { 798 "dismiss_stale_reviews_on_push": true, 799 "require_code_owner_review": true, 800 "require_last_push_approval": true, 801 "required_approving_review_count": 1, 802 "required_review_thread_resolution": true 803 } 804 }, 805 { 806 "type": "required_status_checks", 807 "parameters": { 808 "required_status_checks": [ 809 { 810 "context": "test", 811 "integration_id": 1 812 } 813 ], 814 "strict_required_status_checks_policy": true 815 } 816 }, 817 { 818 "type": "non_fast_forward" 819 }, 820 { 821 "type": "commit_message_pattern", 822 "parameters": { 823 "name": "avoid test commits", 824 "negate": true, 825 "operator": "starts_with", 826 "pattern": "[test]" 827 } 828 }, 829 { 830 "type": "commit_author_email_pattern", 831 "parameters": { 832 "operator": "contains", 833 "pattern": "github" 834 } 835 }, 836 { 837 "type": "committer_email_pattern", 838 "parameters": { 839 "name": "avoid commit emails", 840 "negate": true, 841 "operator": "ends_with", 842 "pattern": "abc" 843 } 844 }, 845 { 846 "type": "branch_name_pattern", 847 "parameters": { 848 "name": "avoid branch names", 849 "negate": true, 850 "operator": "regex", 851 "pattern": "github$" 852 } 853 }, 854 { 855 "type": "tag_name_pattern", 856 "parameters": { 857 "name": "avoid tag names", 858 "negate": true, 859 "operator": "contains", 860 "pattern": "github" 861 } 862 } 863 ] 864 }`) 865 }) 866 867 ctx := context.Background() 868 ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", &Ruleset{ 869 ID: Int64(21), 870 Name: "ruleset", 871 Target: String("branch"), 872 SourceType: String("Organization"), 873 Source: "o", 874 Enforcement: "active", 875 BypassActors: []*BypassActor{ 876 { 877 ActorID: Int64(234), 878 ActorType: String("Team"), 879 }, 880 }, 881 Conditions: &RulesetConditions{ 882 RefName: &RulesetRefConditionParameters{ 883 Include: []string{"refs/heads/main", "refs/heads/master"}, 884 Exclude: []string{"refs/heads/dev*"}, 885 }, 886 RepositoryID: &RulesetRepositoryIDsConditionParameters{ 887 RepositoryIDs: []int64{123, 456}, 888 }, 889 }, 890 Rules: []*RepositoryRule{ 891 NewCreationRule(), 892 NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ 893 UpdateAllowsFetchAndMerge: true, 894 }), 895 NewDeletionRule(), 896 NewMergeQueueRule(), 897 NewRequiredLinearHistoryRule(), 898 NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{ 899 RequiredDeploymentEnvironments: []string{"test"}, 900 }), 901 NewRequiredSignaturesRule(), 902 NewPullRequestRule(&PullRequestRuleParameters{ 903 RequireCodeOwnerReview: true, 904 RequireLastPushApproval: true, 905 RequiredApprovingReviewCount: 1, 906 RequiredReviewThreadResolution: true, 907 DismissStaleReviewsOnPush: true, 908 }), 909 NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ 910 RequiredStatusChecks: []RuleRequiredStatusChecks{ 911 { 912 Context: "test", 913 IntegrationID: Int64(1), 914 }, 915 }, 916 StrictRequiredStatusChecksPolicy: true, 917 }), 918 NewNonFastForwardRule(), 919 NewCommitMessagePatternRule(&RulePatternParameters{ 920 Name: String("avoid test commits"), 921 Negate: Bool(true), 922 Operator: "starts_with", 923 Pattern: "[test]", 924 }), 925 NewCommitAuthorEmailPatternRule(&RulePatternParameters{ 926 Operator: "contains", 927 Pattern: "github", 928 }), 929 NewCommitterEmailPatternRule(&RulePatternParameters{ 930 Name: String("avoid commit emails"), 931 Negate: Bool(true), 932 Operator: "ends_with", 933 Pattern: "abc", 934 }), 935 NewBranchNamePatternRule(&RulePatternParameters{ 936 Name: String("avoid branch names"), 937 Negate: Bool(true), 938 Operator: "regex", 939 Pattern: "github$", 940 }), 941 NewTagNamePatternRule(&RulePatternParameters{ 942 Name: String("avoid tag names"), 943 Negate: Bool(true), 944 Operator: "contains", 945 Pattern: "github", 946 }), 947 }, 948 }) 949 if err != nil { 950 t.Errorf("Organizations.CreateOrganizationRuleset returned error: %v", err) 951 } 952 953 want := &Ruleset{ 954 ID: Int64(21), 955 Name: "ruleset", 956 Target: String("branch"), 957 SourceType: String("Organization"), 958 Source: "o", 959 Enforcement: "active", 960 BypassActors: []*BypassActor{ 961 { 962 ActorID: Int64(234), 963 ActorType: String("Team"), 964 }, 965 }, 966 Conditions: &RulesetConditions{ 967 RefName: &RulesetRefConditionParameters{ 968 Include: []string{"refs/heads/main", "refs/heads/master"}, 969 Exclude: []string{"refs/heads/dev*"}, 970 }, 971 RepositoryID: &RulesetRepositoryIDsConditionParameters{ 972 RepositoryIDs: []int64{123, 456}, 973 }, 974 }, 975 Rules: []*RepositoryRule{ 976 NewCreationRule(), 977 NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ 978 UpdateAllowsFetchAndMerge: true, 979 }), 980 NewDeletionRule(), 981 NewMergeQueueRule(), 982 NewRequiredLinearHistoryRule(), 983 NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{ 984 RequiredDeploymentEnvironments: []string{"test"}, 985 }), 986 NewRequiredSignaturesRule(), 987 NewPullRequestRule(&PullRequestRuleParameters{ 988 RequireCodeOwnerReview: true, 989 RequireLastPushApproval: true, 990 RequiredApprovingReviewCount: 1, 991 RequiredReviewThreadResolution: true, 992 DismissStaleReviewsOnPush: true, 993 }), 994 NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ 995 RequiredStatusChecks: []RuleRequiredStatusChecks{ 996 { 997 Context: "test", 998 IntegrationID: Int64(1), 999 }, 1000 }, 1001 StrictRequiredStatusChecksPolicy: true, 1002 }), 1003 NewNonFastForwardRule(), 1004 NewCommitMessagePatternRule(&RulePatternParameters{ 1005 Name: String("avoid test commits"), 1006 Negate: Bool(true), 1007 Operator: "starts_with", 1008 Pattern: "[test]", 1009 }), 1010 NewCommitAuthorEmailPatternRule(&RulePatternParameters{ 1011 Operator: "contains", 1012 Pattern: "github", 1013 }), 1014 NewCommitterEmailPatternRule(&RulePatternParameters{ 1015 Name: String("avoid commit emails"), 1016 Negate: Bool(true), 1017 Operator: "ends_with", 1018 Pattern: "abc", 1019 }), 1020 NewBranchNamePatternRule(&RulePatternParameters{ 1021 Name: String("avoid branch names"), 1022 Negate: Bool(true), 1023 Operator: "regex", 1024 Pattern: "github$", 1025 }), 1026 NewTagNamePatternRule(&RulePatternParameters{ 1027 Name: String("avoid tag names"), 1028 Negate: Bool(true), 1029 Operator: "contains", 1030 Pattern: "github", 1031 }), 1032 }, 1033 } 1034 if !cmp.Equal(ruleset, want) { 1035 t.Errorf("Organizations.CreateOrganizationRuleset returned %+v, want %+v", ruleset, want) 1036 } 1037 1038 const methodName = "CreateOrganizationRuleset" 1039 1040 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1041 got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", nil) 1042 if got != nil { 1043 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1044 } 1045 return resp, err 1046 }) 1047 } 1048 1049 func TestOrganizationsService_GetOrganizationRuleset(t *testing.T) { 1050 client, mux, _, teardown := setup() 1051 defer teardown() 1052 1053 mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { 1054 testMethod(t, r, "GET") 1055 fmt.Fprint(w, `{ 1056 "id": 26110, 1057 "name": "test ruleset", 1058 "target": "branch", 1059 "source_type": "Organization", 1060 "source": "o", 1061 "enforcement": "active", 1062 "bypass_mode": "none", 1063 "node_id": "nid", 1064 "_links": { 1065 "self": { 1066 "href": "https://api.github.com/orgs/o/rulesets/26110" 1067 } 1068 }, 1069 "conditions": { 1070 "ref_name": { 1071 "include": [ 1072 "refs/heads/main", 1073 "refs/heads/master" 1074 ], 1075 "exclude": [ 1076 "refs/heads/dev*" 1077 ] 1078 }, 1079 "repository_name": { 1080 "include": [ 1081 "important_repository", 1082 "another_important_repository" 1083 ], 1084 "exclude": [ 1085 "unimportant_repository" 1086 ], 1087 "protected": true 1088 } 1089 }, 1090 "rules": [ 1091 { 1092 "type": "creation" 1093 } 1094 ] 1095 }`) 1096 }) 1097 1098 ctx := context.Background() 1099 rulesets, _, err := client.Organizations.GetOrganizationRuleset(ctx, "o", 26110) 1100 if err != nil { 1101 t.Errorf("Organizations.GetOrganizationRepositoryRuleset returned error: %v", err) 1102 } 1103 1104 want := &Ruleset{ 1105 ID: Int64(26110), 1106 Name: "test ruleset", 1107 Target: String("branch"), 1108 SourceType: String("Organization"), 1109 Source: "o", 1110 Enforcement: "active", 1111 NodeID: String("nid"), 1112 Links: &RulesetLinks{ 1113 Self: &RulesetLink{HRef: String("https://api.github.com/orgs/o/rulesets/26110")}, 1114 }, 1115 Conditions: &RulesetConditions{ 1116 RefName: &RulesetRefConditionParameters{ 1117 Include: []string{"refs/heads/main", "refs/heads/master"}, 1118 Exclude: []string{"refs/heads/dev*"}, 1119 }, 1120 RepositoryName: &RulesetRepositoryNamesConditionParameters{ 1121 Include: []string{"important_repository", "another_important_repository"}, 1122 Exclude: []string{"unimportant_repository"}, 1123 Protected: Bool(true), 1124 }, 1125 }, 1126 Rules: []*RepositoryRule{ 1127 NewCreationRule(), 1128 }, 1129 } 1130 if !cmp.Equal(rulesets, want) { 1131 t.Errorf("Organizations.GetOrganizationRuleset returned %+v, want %+v", rulesets, want) 1132 } 1133 1134 const methodName = "GetOrganizationRuleset" 1135 1136 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1137 got, resp, err := client.Organizations.GetOrganizationRuleset(ctx, "o", 26110) 1138 if got != nil { 1139 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1140 } 1141 return resp, err 1142 }) 1143 } 1144 1145 func TestOrganizationsService_GetOrganizationRulesetWithRepoPropCondition(t *testing.T) { 1146 client, mux, _, teardown := setup() 1147 defer teardown() 1148 1149 mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { 1150 testMethod(t, r, "GET") 1151 fmt.Fprint(w, `{ 1152 "id": 26110, 1153 "name": "test ruleset", 1154 "target": "branch", 1155 "source_type": "Organization", 1156 "source": "o", 1157 "enforcement": "active", 1158 "bypass_mode": "none", 1159 "node_id": "nid", 1160 "_links": { 1161 "self": { 1162 "href": "https://api.github.com/orgs/o/rulesets/26110" 1163 } 1164 }, 1165 "conditions": { 1166 "repository_property": { 1167 "exclude": [], 1168 "include": [ 1169 { 1170 "name": "testIncludeProp", 1171 "source": "custom", 1172 "property_values": [ 1173 "true" 1174 ] 1175 } 1176 ] 1177 } 1178 }, 1179 "rules": [ 1180 { 1181 "type": "creation" 1182 } 1183 ] 1184 }`) 1185 }) 1186 1187 ctx := context.Background() 1188 rulesets, _, err := client.Organizations.GetOrganizationRuleset(ctx, "o", 26110) 1189 if err != nil { 1190 t.Errorf("Organizations.GetOrganizationRepositoryRuleset returned error: %v", err) 1191 } 1192 1193 want := &Ruleset{ 1194 ID: Int64(26110), 1195 Name: "test ruleset", 1196 Target: String("branch"), 1197 SourceType: String("Organization"), 1198 Source: "o", 1199 Enforcement: "active", 1200 NodeID: String("nid"), 1201 Links: &RulesetLinks{ 1202 Self: &RulesetLink{HRef: String("https://api.github.com/orgs/o/rulesets/26110")}, 1203 }, 1204 Conditions: &RulesetConditions{ 1205 RepositoryProperty: &RulesetRepositoryPropertyConditionParameters{ 1206 Include: []RulesetRepositoryPropertyTargetParameters{ 1207 { 1208 Name: "testIncludeProp", 1209 Values: []string{"true"}, 1210 }, 1211 }, 1212 Exclude: []RulesetRepositoryPropertyTargetParameters{}, 1213 }, 1214 }, 1215 Rules: []*RepositoryRule{ 1216 NewCreationRule(), 1217 }, 1218 } 1219 if !cmp.Equal(rulesets, want) { 1220 t.Errorf("Organizations.GetOrganizationRuleset returned %+v, want %+v", rulesets, want) 1221 } 1222 1223 const methodName = "GetOrganizationRuleset" 1224 1225 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1226 got, resp, err := client.Organizations.GetOrganizationRuleset(ctx, "o", 26110) 1227 if got != nil { 1228 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1229 } 1230 return resp, err 1231 }) 1232 } 1233 func TestOrganizationsService_UpdateOrganizationRuleset(t *testing.T) { 1234 client, mux, _, teardown := setup() 1235 defer teardown() 1236 1237 mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { 1238 testMethod(t, r, "PUT") 1239 fmt.Fprint(w, `{ 1240 "id": 26110, 1241 "name": "test ruleset", 1242 "target": "branch", 1243 "source_type": "Organization", 1244 "source": "o", 1245 "enforcement": "active", 1246 "bypass_mode": "none", 1247 "node_id": "nid", 1248 "_links": { 1249 "self": { 1250 "href": "https://api.github.com/orgs/o/rulesets/26110" 1251 } 1252 }, 1253 "conditions": { 1254 "ref_name": { 1255 "include": [ 1256 "refs/heads/main", 1257 "refs/heads/master" 1258 ], 1259 "exclude": [ 1260 "refs/heads/dev*" 1261 ] 1262 }, 1263 "repository_name": { 1264 "include": [ 1265 "important_repository", 1266 "another_important_repository" 1267 ], 1268 "exclude": [ 1269 "unimportant_repository" 1270 ], 1271 "protected": true 1272 } 1273 }, 1274 "rules": [ 1275 { 1276 "type": "creation" 1277 } 1278 ] 1279 }`) 1280 }) 1281 1282 ctx := context.Background() 1283 rulesets, _, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, &Ruleset{ 1284 Name: "test ruleset", 1285 Target: String("branch"), 1286 Enforcement: "active", 1287 Conditions: &RulesetConditions{ 1288 RefName: &RulesetRefConditionParameters{ 1289 Include: []string{"refs/heads/main", "refs/heads/master"}, 1290 Exclude: []string{"refs/heads/dev*"}, 1291 }, 1292 RepositoryName: &RulesetRepositoryNamesConditionParameters{ 1293 Include: []string{"important_repository", "another_important_repository"}, 1294 Exclude: []string{"unimportant_repository"}, 1295 Protected: Bool(true), 1296 }, 1297 }, 1298 Rules: []*RepositoryRule{ 1299 NewCreationRule(), 1300 }, 1301 }) 1302 1303 if err != nil { 1304 t.Errorf("Organizations.UpdateOrganizationRuleset returned error: %v", err) 1305 } 1306 1307 want := &Ruleset{ 1308 ID: Int64(26110), 1309 Name: "test ruleset", 1310 Target: String("branch"), 1311 SourceType: String("Organization"), 1312 Source: "o", 1313 Enforcement: "active", 1314 NodeID: String("nid"), 1315 Links: &RulesetLinks{ 1316 Self: &RulesetLink{HRef: String("https://api.github.com/orgs/o/rulesets/26110")}, 1317 }, 1318 Conditions: &RulesetConditions{ 1319 RefName: &RulesetRefConditionParameters{ 1320 Include: []string{"refs/heads/main", "refs/heads/master"}, 1321 Exclude: []string{"refs/heads/dev*"}, 1322 }, 1323 RepositoryName: &RulesetRepositoryNamesConditionParameters{ 1324 Include: []string{"important_repository", "another_important_repository"}, 1325 Exclude: []string{"unimportant_repository"}, 1326 Protected: Bool(true), 1327 }, 1328 }, 1329 Rules: []*RepositoryRule{ 1330 NewCreationRule(), 1331 }, 1332 } 1333 if !cmp.Equal(rulesets, want) { 1334 t.Errorf("Organizations.UpdateOrganizationRuleset returned %+v, want %+v", rulesets, want) 1335 } 1336 1337 const methodName = "UpdateOrganizationRuleset" 1338 1339 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1340 got, resp, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, nil) 1341 if got != nil { 1342 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1343 } 1344 return resp, err 1345 }) 1346 } 1347 1348 func TestOrganizationsService_UpdateOrganizationRulesetWithRepoProp(t *testing.T) { 1349 client, mux, _, teardown := setup() 1350 defer teardown() 1351 1352 mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { 1353 testMethod(t, r, "PUT") 1354 fmt.Fprint(w, `{ 1355 "id": 26110, 1356 "name": "test ruleset", 1357 "target": "branch", 1358 "source_type": "Organization", 1359 "source": "o", 1360 "enforcement": "active", 1361 "bypass_mode": "none", 1362 "node_id": "nid", 1363 "_links": { 1364 "self": { 1365 "href": "https://api.github.com/orgs/o/rulesets/26110" 1366 } 1367 }, 1368 "conditions": { 1369 "repository_property": { 1370 "exclude": [], 1371 "include": [ 1372 { 1373 "name": "testIncludeProp", 1374 "source": "custom", 1375 "property_values": [ 1376 "true" 1377 ] 1378 } 1379 ] 1380 } 1381 }, 1382 "rules": [ 1383 { 1384 "type": "creation" 1385 } 1386 ] 1387 }`) 1388 }) 1389 1390 ctx := context.Background() 1391 rulesets, _, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, &Ruleset{ 1392 Name: "test ruleset", 1393 Target: String("branch"), 1394 Enforcement: "active", 1395 Conditions: &RulesetConditions{ 1396 RepositoryProperty: &RulesetRepositoryPropertyConditionParameters{ 1397 Include: []RulesetRepositoryPropertyTargetParameters{ 1398 { 1399 Name: "testIncludeProp", 1400 Values: []string{"true"}, 1401 }, 1402 }, 1403 Exclude: []RulesetRepositoryPropertyTargetParameters{}, 1404 }, 1405 }, 1406 Rules: []*RepositoryRule{ 1407 NewCreationRule(), 1408 }, 1409 }) 1410 1411 if err != nil { 1412 t.Errorf("Organizations.UpdateOrganizationRuleset returned error: %v", err) 1413 } 1414 1415 want := &Ruleset{ 1416 ID: Int64(26110), 1417 Name: "test ruleset", 1418 Target: String("branch"), 1419 SourceType: String("Organization"), 1420 Source: "o", 1421 Enforcement: "active", 1422 NodeID: String("nid"), 1423 Links: &RulesetLinks{ 1424 Self: &RulesetLink{HRef: String("https://api.github.com/orgs/o/rulesets/26110")}, 1425 }, 1426 Conditions: &RulesetConditions{ 1427 RepositoryProperty: &RulesetRepositoryPropertyConditionParameters{ 1428 Include: []RulesetRepositoryPropertyTargetParameters{ 1429 { 1430 Name: "testIncludeProp", 1431 Values: []string{"true"}, 1432 }, 1433 }, 1434 Exclude: []RulesetRepositoryPropertyTargetParameters{}, 1435 }, 1436 }, 1437 Rules: []*RepositoryRule{ 1438 NewCreationRule(), 1439 }, 1440 } 1441 if !cmp.Equal(rulesets, want) { 1442 t.Errorf("Organizations.UpdateOrganizationRuleset returned %+v, want %+v", rulesets, want) 1443 } 1444 1445 const methodName = "UpdateOrganizationRuleset" 1446 1447 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1448 got, resp, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, nil) 1449 if got != nil { 1450 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 1451 } 1452 return resp, err 1453 }) 1454 } 1455 func TestOrganizationsService_DeleteOrganizationRuleset(t *testing.T) { 1456 client, mux, _, teardown := setup() 1457 defer teardown() 1458 1459 mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { 1460 testMethod(t, r, "DELETE") 1461 }) 1462 1463 ctx := context.Background() 1464 _, err := client.Organizations.DeleteOrganizationRuleset(ctx, "o", 26110) 1465 if err != nil { 1466 t.Errorf("Organizations.DeleteOrganizationRuleset returned error: %v", err) 1467 } 1468 1469 const methodName = "DeleteOrganizationRuleset" 1470 1471 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 1472 return client.Organizations.DeleteOrganizationRuleset(ctx, "0", 26110) 1473 }) 1474 }