forked from integrations/terraform-provider-github
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add github_branch data and resource (integrations#364)
* add github_repository_branch data and resource * rename github_repository_branch to github_branch and adjust tests to use required fixtures * nit * Trigger travis * Trigger travis * add github_branch documentation * revert go.sum change. * remove sha attribute * fix importing * include doc links * fix broken doc link * clean up github_branch: - add etag and sha attributes back - make errors more verbose for easier debugging - expand test case - require branch for data source * review * review * review * fix client references for github v3 client * fix util call * nit * fix import id when specifying source_branch
- Loading branch information
1 parent
4c352c3
commit 54bbd47
Showing
8 changed files
with
656 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package github | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"log" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | ||
) | ||
|
||
func dataSourceGithubBranch() *schema.Resource { | ||
return &schema.Resource{ | ||
Read: dataSourceGithubBranchRead, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"repository": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"branch": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"etag": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"ref": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"sha": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func dataSourceGithubBranchRead(d *schema.ResourceData, meta interface{}) error { | ||
err := checkOrganization(meta) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
client := meta.(*Organization).v3client | ||
orgName := meta.(*Organization).name | ||
repoName := d.Get("repository").(string) | ||
branchName := d.Get("branch").(string) | ||
branchRefName := "refs/heads/" + branchName | ||
|
||
log.Printf("[DEBUG] Reading GitHub branch reference %s/%s (%s)", | ||
orgName, repoName, branchRefName) | ||
ref, resp, err := client.Git.GetRef( | ||
context.TODO(), orgName, repoName, branchRefName) | ||
if err != nil { | ||
return fmt.Errorf("Error reading GitHub branch reference %s/%s (%s): %s", | ||
orgName, repoName, branchRefName, err) | ||
} | ||
|
||
d.SetId(buildTwoPartID(repoName, branchName)) | ||
d.Set("etag", resp.Header.Get("ETag")) | ||
d.Set("ref", *ref.Ref) | ||
d.Set("sha", *ref.Object.SHA) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package github | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource" | ||
) | ||
|
||
func TestAccGithubBranchDataSource_basic(t *testing.T) { | ||
|
||
var ( | ||
name = "main" | ||
repo = "test-repo" | ||
rn = "data.github_branch." + name | ||
) | ||
|
||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccCheckGithubBranchDataSourceConfig(name, repo, "master"), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr(rn, "repository", repo), | ||
resource.TestCheckResourceAttr(rn, "branch", "master"), | ||
resource.TestCheckResourceAttrSet(rn, "etag"), | ||
resource.TestCheckResourceAttrSet(rn, "ref"), | ||
resource.TestCheckResourceAttrSet(rn, "sha"), | ||
), | ||
}, | ||
{ | ||
Config: testAccCheckGithubBranchDataSourceConfig(name, repo, "master"), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr(rn, "repository", repo), | ||
resource.TestCheckResourceAttr(rn, "branch", "master"), | ||
resource.TestCheckResourceAttrSet(rn, "etag"), | ||
resource.TestCheckResourceAttrSet(rn, "ref"), | ||
resource.TestCheckResourceAttrSet(rn, "sha"), | ||
), | ||
}, | ||
{ | ||
Config: testAccCheckGithubBranchDataSourceConfig(name, repo, "test-branch"), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr(rn, "repository", repo), | ||
resource.TestCheckResourceAttr(rn, "branch", "test-branch"), | ||
resource.TestCheckResourceAttrSet(rn, "etag"), | ||
resource.TestCheckResourceAttrSet(rn, "ref"), | ||
resource.TestCheckResourceAttrSet(rn, "sha"), | ||
), | ||
}, | ||
{ | ||
Config: testAccCheckGithubBranchDataSourceConfig(name, repo, "test-branch"), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr(rn, "repository", repo), | ||
resource.TestCheckResourceAttr(rn, "branch", "test-branch"), | ||
resource.TestCheckResourceAttrSet(rn, "etag"), | ||
resource.TestCheckResourceAttrSet(rn, "ref"), | ||
resource.TestCheckResourceAttrSet(rn, "sha"), | ||
), | ||
}, | ||
}, | ||
}) | ||
|
||
} | ||
|
||
func testAccCheckGithubBranchDataSourceConfig(name, repo, branch string) string { | ||
return fmt.Sprintf(` | ||
data "github_branch" "%s" { | ||
repository = "%s" | ||
branch = "%s" | ||
} | ||
`, name, repo, branch) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
package github | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
"strings" | ||
|
||
"github.com/google/go-github/v29/github" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | ||
) | ||
|
||
func resourceGithubBranch() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceGithubBranchCreate, | ||
Read: resourceGithubBranchRead, | ||
Delete: resourceGithubBranchDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: resourceGithubBranchImport, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"repository": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"branch": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"source_branch": { | ||
Type: schema.TypeString, | ||
Default: "master", | ||
Optional: true, | ||
ForceNew: true, | ||
}, | ||
"source_sha": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
ForceNew: true, | ||
Computed: true, | ||
}, | ||
"etag": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"ref": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"sha": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceGithubBranchCreate(d *schema.ResourceData, meta interface{}) error { | ||
err := checkOrganization(meta) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
ctx := context.Background() | ||
if !d.IsNewResource() { | ||
ctx = context.WithValue(ctx, ctxId, d.Id()) | ||
} | ||
|
||
client := meta.(*Organization).v3client | ||
orgName := meta.(*Organization).name | ||
repoName := d.Get("repository").(string) | ||
branchName := d.Get("branch").(string) | ||
branchRefName := "refs/heads/" + branchName | ||
sourceBranchName := d.Get("source_branch").(string) | ||
sourceBranchRefName := "refs/heads/" + sourceBranchName | ||
|
||
if _, hasSourceSHA := d.GetOk("source_sha"); !hasSourceSHA { | ||
log.Printf("[DEBUG] Querying GitHub branch reference %s/%s (%s) to derive source_sha", | ||
orgName, repoName, sourceBranchRefName) | ||
ref, _, err := client.Git.GetRef(ctx, orgName, repoName, sourceBranchRefName) | ||
if err != nil { | ||
return fmt.Errorf("Error querying GitHub branch reference %s/%s (%s): %s", | ||
orgName, repoName, sourceBranchRefName, err) | ||
} | ||
d.Set("source_sha", *ref.Object.SHA) | ||
} | ||
sourceBranchSHA := d.Get("source_sha").(string) | ||
|
||
log.Printf("[DEBUG] Creating GitHub branch reference %s/%s (%s)", | ||
orgName, repoName, branchRefName) | ||
_, _, err = client.Git.CreateRef(ctx, orgName, repoName, &github.Reference{ | ||
Ref: &branchRefName, | ||
Object: &github.GitObject{SHA: &sourceBranchSHA}, | ||
}) | ||
if err != nil { | ||
return fmt.Errorf("Error creating GitHub branch reference %s/%s (%s): %s", | ||
orgName, repoName, branchRefName, err) | ||
} | ||
|
||
d.SetId(buildTwoPartID(repoName, branchName)) | ||
|
||
return resourceGithubBranchRead(d, meta) | ||
} | ||
|
||
func resourceGithubBranchRead(d *schema.ResourceData, meta interface{}) error { | ||
err := checkOrganization(meta) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
ctx := context.WithValue(context.Background(), ctxId, d.Id()) | ||
if !d.IsNewResource() { | ||
ctx = context.WithValue(ctx, ctxEtag, d.Get("etag").(string)) | ||
} | ||
|
||
client := meta.(*Organization).v3client | ||
orgName := meta.(*Organization).name | ||
repoName, branchName, err := parseTwoPartID(d.Id(), "repository", "branch") | ||
if err != nil { | ||
return err | ||
} | ||
branchRefName := "refs/heads/" + branchName | ||
|
||
log.Printf("[DEBUG] Querying GitHub branch reference %s/%s (%s)", | ||
orgName, repoName, branchRefName) | ||
ref, resp, err := client.Git.GetRef(ctx, orgName, repoName, branchRefName) | ||
if err != nil { | ||
if ghErr, ok := err.(*github.ErrorResponse); ok { | ||
if ghErr.Response.StatusCode == http.StatusNotModified { | ||
return nil | ||
} | ||
if ghErr.Response.StatusCode == http.StatusNotFound { | ||
log.Printf("[WARN] Removing branch %s/%s (%s) from state because it no longer exists in Github", | ||
orgName, repoName, branchName) | ||
d.SetId("") | ||
return nil | ||
} | ||
} | ||
return fmt.Errorf("Error querying GitHub branch reference %s/%s (%s): %s", | ||
orgName, repoName, branchRefName, err) | ||
} | ||
|
||
d.SetId(buildTwoPartID(repoName, branchName)) | ||
d.Set("etag", resp.Header.Get("ETag")) | ||
d.Set("repository", repoName) | ||
d.Set("branch", branchName) | ||
d.Set("ref", *ref.Ref) | ||
d.Set("sha", *ref.Object.SHA) | ||
|
||
return nil | ||
} | ||
|
||
func resourceGithubBranchDelete(d *schema.ResourceData, meta interface{}) error { | ||
err := checkOrganization(meta) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
ctx := context.WithValue(context.Background(), ctxId, d.Id()) | ||
|
||
client := meta.(*Organization).v3client | ||
orgName := meta.(*Organization).name | ||
repoName, branchName, err := parseTwoPartID(d.Id(), "repository", "branch") | ||
if err != nil { | ||
return err | ||
} | ||
branchRefName := "refs/heads/" + branchName | ||
|
||
log.Printf("[DEBUG] Deleting GitHub branch reference %s/%s (%s)", | ||
orgName, repoName, branchRefName) | ||
_, err = client.Git.DeleteRef(ctx, orgName, repoName, branchRefName) | ||
if err != nil { | ||
return fmt.Errorf("Error deleting GitHub branch reference %s/%s (%s): %s", | ||
orgName, repoName, branchRefName, err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceGithubBranchImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { | ||
repoName, branchName, err := parseTwoPartID(d.Id(), "repository", "branch") | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
sourceBranch := "master" | ||
if strings.Contains(branchName, ":") { | ||
branchName, sourceBranch, err = parseTwoPartID(branchName, "branch", "source_branch") | ||
if err != nil { | ||
return nil, err | ||
} | ||
d.SetId(buildTwoPartID(repoName, branchName)) | ||
} | ||
|
||
d.Set("source_branch", sourceBranch) | ||
|
||
return []*schema.ResourceData{d}, resourceGithubBranchRead(d, meta) | ||
} |
Oops, something went wrong.