provider/github: github_repository resource
Allows creation of repositories within the organization configured on the provider.
This commit is contained in:
parent
7fddaf04bd
commit
f4ecf72125
|
@ -36,6 +36,7 @@ func Provider() terraform.ResourceProvider {
|
|||
"github_team_membership": resourceGithubTeamMembership(),
|
||||
"github_team_repository": resourceGithubTeamRepository(),
|
||||
"github_membership": resourceGithubMembership(),
|
||||
"github_repository": resourceGithubRepository(),
|
||||
"github_repository_collaborator": resourceGithubRepositoryCollaborator(),
|
||||
},
|
||||
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
package github
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/google/go-github/github"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
func resourceGithubRepository() *schema.Resource {
|
||||
|
||||
return &schema.Resource{
|
||||
Create: resourceGithubRepositoryCreate,
|
||||
Read: resourceGithubRepositoryRead,
|
||||
Update: resourceGithubRepositoryUpdate,
|
||||
Delete: resourceGithubRepositoryDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"description": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"homepage_url": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"private": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
},
|
||||
"has_issues": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
},
|
||||
"has_wiki": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
},
|
||||
"has_downloads": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
},
|
||||
"auto_init": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
},
|
||||
|
||||
"full_name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"default_branch": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"ssh_clone_url": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"svn_url": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"git_clone_url": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"http_clone_url": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceGithubRepositoryObject(d *schema.ResourceData) *github.Repository {
|
||||
name := d.Get("name").(string)
|
||||
description := d.Get("description").(string)
|
||||
homepageUrl := d.Get("homepage_url").(string)
|
||||
private := d.Get("private").(bool)
|
||||
hasIssues := d.Get("has_issues").(bool)
|
||||
hasWiki := d.Get("has_wiki").(bool)
|
||||
hasDownloads := d.Get("has_downloads").(bool)
|
||||
autoInit := d.Get("auto_init").(bool)
|
||||
|
||||
repo := &github.Repository{
|
||||
Name: &name,
|
||||
Description: &description,
|
||||
Homepage: &homepageUrl,
|
||||
Private: &private,
|
||||
HasIssues: &hasIssues,
|
||||
HasWiki: &hasWiki,
|
||||
HasDownloads: &hasDownloads,
|
||||
AutoInit: &autoInit,
|
||||
}
|
||||
|
||||
return repo
|
||||
}
|
||||
|
||||
func resourceGithubRepositoryCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*Organization).client
|
||||
|
||||
repoReq := resourceGithubRepositoryObject(d)
|
||||
log.Printf("[DEBUG] create github repository %s/%s", meta.(*Organization).name, *repoReq.Name)
|
||||
repo, _, err := client.Repositories.Create(meta.(*Organization).name, repoReq)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.SetId(*repo.Name)
|
||||
|
||||
return resourceGithubRepositoryRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceGithubRepositoryRead(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*Organization).client
|
||||
repoName := d.Id()
|
||||
|
||||
log.Printf("[DEBUG] read github repository %s/%s", meta.(*Organization).name, repoName)
|
||||
repo, resp, err := client.Repositories.Get(meta.(*Organization).name, repoName)
|
||||
if err != nil {
|
||||
if resp.StatusCode == 404 {
|
||||
log.Printf(
|
||||
"[WARN] removing %s/%s from state because it no longer exists in github",
|
||||
meta.(*Organization).name,
|
||||
repoName,
|
||||
)
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
d.Set("description", repo.Description)
|
||||
d.Set("homepage_url", repo.Homepage)
|
||||
d.Set("private", repo.Private)
|
||||
d.Set("has_issues", repo.HasIssues)
|
||||
d.Set("has_wiki", repo.HasWiki)
|
||||
d.Set("has_downloads", repo.HasDownloads)
|
||||
d.Set("full_name", repo.FullName)
|
||||
d.Set("default_branch", repo.DefaultBranch)
|
||||
d.Set("ssh_clone_url", repo.SSHURL)
|
||||
d.Set("svn_url", repo.SVNURL)
|
||||
d.Set("git_clone_url", repo.GitURL)
|
||||
d.Set("http_clone_url", repo.CloneURL)
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceGithubRepositoryUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*Organization).client
|
||||
repoReq := resourceGithubRepositoryObject(d)
|
||||
repoName := d.Id()
|
||||
log.Printf("[DEBUG] update github repository %s/%s", meta.(*Organization).name, repoName)
|
||||
_, _, err := client.Repositories.Edit(meta.(*Organization).name, repoName, repoReq)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return resourceGithubRepositoryRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceGithubRepositoryDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*Organization).client
|
||||
repoName := d.Id()
|
||||
log.Printf("[DEBUG] delete github repository %s/%s", meta.(*Organization).name, repoName)
|
||||
_, err := client.Repositories.Delete(meta.(*Organization).name, repoName)
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
package github
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-github/github"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccGithubRepository_basic(t *testing.T) {
|
||||
var repo github.Repository
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckGithubRepositoryDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccGithubRepositoryConfig,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGithubRepositoryExists("github_repository.foo", &repo),
|
||||
testAccCheckGithubRepositoryAttributes(&repo, &testAccGithubRepositoryExpectedAttributes{
|
||||
Name: "foo",
|
||||
Description: "Terraform acceptance tests",
|
||||
Homepage: "http://example.com/",
|
||||
HasIssues: true,
|
||||
HasWiki: true,
|
||||
HasDownloads: true,
|
||||
DefaultBranch: "master",
|
||||
}),
|
||||
),
|
||||
},
|
||||
resource.TestStep{
|
||||
Config: testAccGithubRepositoryUpdateConfig,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGithubRepositoryExists("github_repository.foo", &repo),
|
||||
testAccCheckGithubRepositoryAttributes(&repo, &testAccGithubRepositoryExpectedAttributes{
|
||||
Name: "foo",
|
||||
Description: "Terraform acceptance tests!",
|
||||
Homepage: "http://example.com/",
|
||||
DefaultBranch: "master",
|
||||
}),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckGithubRepositoryExists(n string, repo *github.Repository) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not Found: %s", n)
|
||||
}
|
||||
|
||||
repoName := rs.Primary.ID
|
||||
if repoName == "" {
|
||||
return fmt.Errorf("No repository name is set")
|
||||
}
|
||||
|
||||
org := testAccProvider.Meta().(*Organization)
|
||||
conn := org.client
|
||||
gotRepo, _, err := conn.Repositories.Get(org.name, repoName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*repo = *gotRepo
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
type testAccGithubRepositoryExpectedAttributes struct {
|
||||
Name string
|
||||
Description string
|
||||
Homepage string
|
||||
Private bool
|
||||
HasIssues bool
|
||||
HasWiki bool
|
||||
HasDownloads bool
|
||||
|
||||
DefaultBranch string
|
||||
}
|
||||
|
||||
func testAccCheckGithubRepositoryAttributes(repo *github.Repository, want *testAccGithubRepositoryExpectedAttributes) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
|
||||
if *repo.Name != want.Name {
|
||||
return fmt.Errorf("got repo %q; want %q", *repo.Name, want.Name)
|
||||
}
|
||||
if *repo.Description != want.Description {
|
||||
return fmt.Errorf("got description %q; want %q", *repo.Description, want.Description)
|
||||
}
|
||||
if *repo.Homepage != want.Homepage {
|
||||
return fmt.Errorf("got homepage URL %q; want %q", *repo.Homepage, want.Homepage)
|
||||
}
|
||||
if *repo.Private != want.Private {
|
||||
return fmt.Errorf("got private %#v; want %#v", *repo.Private, want.Private)
|
||||
}
|
||||
if *repo.HasIssues != want.HasIssues {
|
||||
return fmt.Errorf("got has issues %#v; want %#v", *repo.HasIssues, want.HasIssues)
|
||||
}
|
||||
if *repo.HasWiki != want.HasWiki {
|
||||
return fmt.Errorf("got has wiki %#v; want %#v", *repo.HasWiki, want.HasWiki)
|
||||
}
|
||||
if *repo.HasDownloads != want.HasDownloads {
|
||||
return fmt.Errorf("got has downloads %#v; want %#v", *repo.HasDownloads, want.HasDownloads)
|
||||
}
|
||||
|
||||
if *repo.DefaultBranch != want.DefaultBranch {
|
||||
return fmt.Errorf("got default branch %q; want %q", *repo.DefaultBranch, want.DefaultBranch)
|
||||
}
|
||||
|
||||
// For the rest of these, we just want to make sure they've been
|
||||
// populated with something that seems somewhat reasonable.
|
||||
if !strings.HasSuffix(*repo.FullName, "/"+want.Name) {
|
||||
return fmt.Errorf("got full name %q; want to end with '/%s'", *repo.FullName, want.Name)
|
||||
}
|
||||
if !strings.HasSuffix(*repo.CloneURL, "/"+want.Name+".git") {
|
||||
return fmt.Errorf("got Clone URL %q; want to end with '/%s.git'", *repo.CloneURL, want.Name)
|
||||
}
|
||||
if !strings.HasPrefix(*repo.CloneURL, "https://") {
|
||||
return fmt.Errorf("got Clone URL %q; want to start with 'https://'", *repo.CloneURL)
|
||||
}
|
||||
if !strings.HasSuffix(*repo.SSHURL, "/"+want.Name+".git") {
|
||||
return fmt.Errorf("got SSH URL %q; want to end with '/%s.git'", *repo.SSHURL, want.Name)
|
||||
}
|
||||
if !strings.HasPrefix(*repo.SSHURL, "git@github.com:") {
|
||||
return fmt.Errorf("got SSH URL %q; want to start with 'git@github.com:'", *repo.SSHURL)
|
||||
}
|
||||
if !strings.HasSuffix(*repo.GitURL, "/"+want.Name+".git") {
|
||||
return fmt.Errorf("got git URL %q; want to end with '/%s.git'", *repo.GitURL, want.Name)
|
||||
}
|
||||
if !strings.HasPrefix(*repo.GitURL, "git://") {
|
||||
return fmt.Errorf("got git URL %q; want to start with 'git://'", *repo.GitURL)
|
||||
}
|
||||
if !strings.HasSuffix(*repo.SVNURL, "/"+want.Name) {
|
||||
return fmt.Errorf("got svn URL %q; want to end with '/%s'", *repo.SVNURL, want.Name)
|
||||
}
|
||||
if !strings.HasPrefix(*repo.SVNURL, "https://") {
|
||||
return fmt.Errorf("got svn URL %q; want to start with 'https://'", *repo.SVNURL)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckGithubRepositoryDestroy(s *terraform.State) error {
|
||||
conn := testAccProvider.Meta().(*Organization).client
|
||||
orgName := testAccProvider.Meta().(*Organization).name
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "github_repository" {
|
||||
continue
|
||||
}
|
||||
|
||||
gotRepo, resp, err := conn.Repositories.Get(orgName, rs.Primary.ID)
|
||||
if err == nil {
|
||||
if gotRepo != nil && *gotRepo.Name == rs.Primary.ID {
|
||||
return fmt.Errorf("Repository still exists")
|
||||
}
|
||||
}
|
||||
if resp.StatusCode != 404 {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const testAccGithubRepositoryConfig = `
|
||||
resource "github_repository" "foo" {
|
||||
name = "foo"
|
||||
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
|
||||
}
|
||||
`
|
||||
|
||||
const testAccGithubRepositoryUpdateConfig = `
|
||||
resource "github_repository" "foo" {
|
||||
name = "foo"
|
||||
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 = false
|
||||
has_wiki = false
|
||||
has_downloads = false
|
||||
}
|
||||
`
|
Loading…
Reference in New Issue