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