-
Couldn't load subscription status.
- Fork 872
Introduce a working github_repository_prereceive_hook resource #252
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
998c86b
ad7456e
2a9f524
3f53e38
07752d6
7517589
4d222ee
c1b7405
f92cc6a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,165 @@ | ||
| package github | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| "strconv" | ||
|
|
||
| "github.com/google/go-github/v25/github" | ||
| "github.com/hashicorp/terraform/helper/schema" | ||
| "github.com/hashicorp/terraform/helper/validation" | ||
| ) | ||
|
|
||
| func resourceGithubRepositoryPreReceiveHook() *schema.Resource { | ||
| return &schema.Resource{ | ||
| Create: resourceGithubRepositoryPreReceiveHookCreate, | ||
| Read: resourceGithubRepositoryPreReceiveHookRead, | ||
| Update: resourceGithubRepositoryPreReceiveHookCreate, | ||
joestump marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Delete: resourceGithubRepositoryPreReceiveHookDelete, | ||
| Schema: map[string]*schema.Schema{ | ||
| "name": { | ||
| Type: schema.TypeString, | ||
| Required: true, | ||
| ForceNew: true, | ||
| }, | ||
| "repository": { | ||
| Type: schema.TypeString, | ||
| Required: true, | ||
| ForceNew: true, | ||
| }, | ||
| "enforcement": { | ||
| Type: schema.TypeString, | ||
| Required: true, | ||
| ValidateFunc: validation.StringInSlice([]string{"enabled", "disabled", "testing"}, false), | ||
| }, | ||
| "config_url": { | ||
| Type: schema.TypeString, | ||
| Optional: true, | ||
| }, | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| func fetchGitHubRepositoryPreReceiveHookByName(meta interface{}, repoName, hookName string) (*github.PreReceiveHook, error) { | ||
| ctx := context.Background() | ||
| client := meta.(*Organization).client | ||
| orgName := meta.(*Organization).name | ||
|
|
||
| opt := &github.ListOptions{ | ||
| PerPage: 100, | ||
| } | ||
|
|
||
| var hook *github.PreReceiveHook | ||
|
|
||
| for { | ||
| hooks, resp, err := client.Repositories.ListPreReceiveHooks(ctx, orgName, repoName, opt) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| for _, h := range hooks { | ||
| n := *h.Name | ||
| if n == hookName { | ||
| hook = h | ||
| break | ||
| } | ||
| } | ||
|
|
||
| if resp.NextPage == 0 { | ||
| break | ||
| } | ||
| opt.Page = resp.NextPage | ||
| } | ||
|
|
||
| if *hook.ID <= 0 { | ||
| return nil, fmt.Errorf("No pre-receive hook with name %s found on %s/%s", hookName, orgName, repoName) | ||
| } | ||
|
|
||
| return hook, nil | ||
| } | ||
|
|
||
| func resourceGithubRepositoryPreReceiveHookCreate(d *schema.ResourceData, meta interface{}) error { | ||
| err := checkOrganization(meta) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| repoName := d.Get("repository").(string) | ||
| hookName := d.Get("name").(string) | ||
|
|
||
| hook, err := fetchGitHubRepositoryPreReceiveHookByName(meta, repoName, hookName) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| enforcement := d.Get("enforcement").(string) | ||
| hook.Enforcement = &enforcement | ||
|
|
||
| if v, ok := d.GetOk("config_url"); ok { | ||
| configURL := v.(string) | ||
| hook.ConfigURL = &configURL | ||
| } | ||
|
|
||
| ctx := context.Background() | ||
| client := meta.(*Organization).client | ||
| orgName := meta.(*Organization).name | ||
| _, _, err = client.Repositories.UpdatePreReceiveHook(ctx, orgName, repoName, *hook.ID, hook) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| d.SetId(fmt.Sprintf("%s/%s/%s", orgName, repoName, strconv.FormatInt(*hook.ID, 10))) | ||
|
|
||
| return resourceGithubRepositoryPreReceiveHookRead(d, meta) | ||
| } | ||
|
|
||
| func resourceGithubRepositoryPreReceiveHookRead(d *schema.ResourceData, meta interface{}) error { | ||
| err := checkOrganization(meta) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| repoName := d.Get("repository").(string) | ||
| hookName := d.Get("name").(string) | ||
|
|
||
| hook, err := fetchGitHubRepositoryPreReceiveHookByName(meta, repoName, hookName) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| d.Set("enforcement", hook.Enforcement) | ||
|
|
||
| if _, ok := d.GetOk("config_url"); ok { | ||
| d.Set("config_url", hook.ConfigURL) | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func resourceGithubRepositoryPreReceiveHookDelete(d *schema.ResourceData, meta interface{}) error { | ||
| err := checkOrganization(meta) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| repoName := d.Get("repository").(string) | ||
| hookName := d.Get("name").(string) | ||
|
|
||
| hook, err := fetchGitHubRepositoryPreReceiveHookByName(meta, repoName, hookName) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| disabled := "disabled" | ||
| hook.Enforcement = &disabled | ||
|
|
||
| ctx := context.Background() | ||
| client := meta.(*Organization).client | ||
| orgName := meta.(*Organization).name | ||
| _, _, err = client.Repositories.UpdatePreReceiveHook(ctx, orgName, repoName, *hook.ID, hook) | ||
| if err != nil { | ||
joestump marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return err | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| package github | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| "strconv" | ||
| "strings" | ||
| "testing" | ||
|
|
||
| "github.com/hashicorp/terraform/helper/acctest" | ||
| "github.com/hashicorp/terraform/helper/resource" | ||
| "github.com/hashicorp/terraform/terraform" | ||
| ) | ||
|
|
||
| func TestAccGithubRepositoryPreReceiveHook_basic(t *testing.T) { | ||
| randString := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum) | ||
| enforcement := "enabled" | ||
|
|
||
| resource.ParallelTest(t, resource.TestCase{ | ||
| PreCheck: func() { testAccPreCheck(t) }, | ||
| Providers: testAccProviders, | ||
| Steps: []resource.TestStep{ | ||
| { | ||
| Config: testAccGithubRepositoryPreReceiveHookConfig_basic(randString), | ||
| Check: resource.ComposeTestCheckFunc( | ||
| testAccCheckGitHubPreReceiveHookEnforcement("github_repository_prereceive_hook.foo", enforcement), | ||
| resource.TestCheckResourceAttr( | ||
| "github_repository_prereceive_hook.foo", "enforcement", enforcement), | ||
| resource.TestCheckResourceAttrSet( | ||
| "github_repository_prereceive_hook.foo", "id"), | ||
| ), | ||
| }, | ||
| }, | ||
| }) | ||
| } | ||
|
|
||
| func testAccCheckGitHubPreReceiveHookEnforcement(n string, enforcement string) resource.TestCheckFunc { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not required as we should be checking what's in state matches reality. This can be accomplished using an {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a check against the API; not state? I don't have an importer for this resource. I can skip validating against the API entirely though if that's preferred (I copied this pattern from the webhook tests). |
||
| return func(s *terraform.State) error { | ||
| rs, ok := s.RootModule().Resources[n] | ||
|
|
||
| if !ok { | ||
| return fmt.Errorf("Not found: %s", n) | ||
| } | ||
|
|
||
| if rs.Primary.ID == "" { | ||
| return fmt.Errorf("No hook ID is set") | ||
| } | ||
|
|
||
| id := strings.Split(rs.Primary.ID, "/") | ||
| orgName, repoName, i := id[0], id[1], id[2] | ||
|
|
||
| hookID, err := strconv.ParseInt(i, 10, 64) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| org := testAccProvider.Meta().(*Organization) | ||
| client := org.client | ||
|
|
||
| hook, _, err := client.Repositories.GetPreReceiveHook(context.TODO(), orgName, repoName, hookID) | ||
|
|
||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| if *hook.Enforcement != enforcement { | ||
| return fmt.Errorf("Enforcement set to %s instead of %s", *hook.Enforcement, enforcement) | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
| } | ||
|
|
||
| func testAccGithubRepositoryPreReceiveHookConfig_basic(randString string) string { | ||
| return fmt.Sprintf(` | ||
| resource "github_repository" "foo" { | ||
| name = "foo-%s" | ||
| description = "Terraform acceptance tests" | ||
| homepage_url = "http://example.com/" | ||
| # So that acceptance tests can be run in a github organization | ||
| # with no billing | ||
| private = false | ||
| has_issues = true | ||
| has_wiki = true | ||
| has_downloads = true | ||
| } | ||
| resource "github_repository_prereceive_hook" "foo" { | ||
| name = "require-code-review" | ||
| repository = "${github_repository.foo.name}" | ||
| enforcement = "enabled" | ||
| } | ||
| `, randString) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| --- | ||
| layout: "github" | ||
| page_title: "GitHub: github_repository_prereceive_hook" | ||
| sidebar_current: "docs-github-resource-repository-prereceive-hook" | ||
| description: |- | ||
| Creates and manages repository pre-recieve hooks within a GitHub Enterprise organization | ||
| --- | ||
|
|
||
| # github_repository_prereceive_hook | ||
|
|
||
| This resource allows you to create and manage [pre-receive hooks](https://developer.github.com/enterprise/2.17/v3/enterprise-admin/repo_pre_receive_hooks/) for | ||
| repositories within your GitHub Enterprise organizations. | ||
|
|
||
| ~> **NOTE** Pre-recieve hooks are only available on GitHub Enterprise. | ||
|
|
||
| ## Example Usage | ||
|
|
||
| ```hcl | ||
| resource "github_repository" "repo" { | ||
| name = "foo" | ||
| description = "Terraform acceptance tests" | ||
| } | ||
|
|
||
| resource "github_repository_prereceive_hook" "reviews" { | ||
| name = "require-code-review" | ||
| repository = "${github_repository.repo.name}" | ||
| enforcement = "enabled" | ||
| } | ||
| ``` | ||
|
|
||
| ## Argument Reference | ||
|
|
||
| The following arguments are supported: | ||
|
|
||
| * `name` - (Required) The name of the pre-receive hook. | ||
|
|
||
| * `repository` - (Required) The repository of the pre-receive hook. | ||
|
|
||
| * `enforcement` - (Required) The state of enforcement for the hook on this repository. Available keys are `enabled`, `disabled`, and `testing`. | ||
|
|
||
| * `config_url` - (Optional) URL for the endpoint where enforcement is set. |
Uh oh!
There was an error while loading. Please reload this page.