Skip to content

Commit 0caa62c

Browse files
Add a data source for refs. (#1084)
Co-authored-by: Keegan Campbell <[email protected]>
1 parent fa02655 commit 0caa62c

File tree

5 files changed

+215
-0
lines changed

5 files changed

+215
-0
lines changed

github/data_source_github_ref.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package github
2+
3+
import (
4+
"context"
5+
"log"
6+
"net/http"
7+
8+
"github.com/google/go-github/v42/github"
9+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
10+
)
11+
12+
func dataSourceGithubRef() *schema.Resource {
13+
return &schema.Resource{
14+
Read: dataSourceGithubRefRead,
15+
16+
Schema: map[string]*schema.Schema{
17+
"repository": {
18+
Type: schema.TypeString,
19+
Required: true,
20+
ForceNew: true,
21+
},
22+
"branch": {
23+
Type: schema.TypeString,
24+
Required: true,
25+
ForceNew: true,
26+
},
27+
"etag": {
28+
Type: schema.TypeString,
29+
Computed: true,
30+
},
31+
"ref": {
32+
Type: schema.TypeString,
33+
Computed: true,
34+
},
35+
"sha": {
36+
Type: schema.TypeString,
37+
Computed: true,
38+
},
39+
},
40+
}
41+
}
42+
43+
func dataSourceGithubRefRead(d *schema.ResourceData, meta interface{}) error {
44+
client := meta.(*Owner).v3client
45+
orgName := meta.(*Owner).name
46+
repoName := d.Get("repository").(string)
47+
ref := d.Get("ref").(string)
48+
49+
refData, resp, err := client.Git.GetRef(context.TODO(), orgName, repoName, ref)
50+
if err != nil {
51+
if err, ok := err.(*github.ErrorResponse); ok {
52+
if err.Response.StatusCode == http.StatusNotFound {
53+
log.Printf("[DEBUG] Missing GitHub ref %s/%s (%s)", orgName, repoName, ref)
54+
d.SetId("")
55+
return nil
56+
}
57+
}
58+
return err
59+
}
60+
61+
d.SetId(buildTwoPartID(repoName, ref))
62+
d.Set("etag", resp.Header.Get("ETag"))
63+
d.Set("ref", *refData.Ref)
64+
d.Set("sha", *refData.Object.SHA)
65+
66+
return nil
67+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package github
2+
3+
import (
4+
"fmt"
5+
"regexp"
6+
"testing"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
9+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
10+
)
11+
12+
func TestAccGithubRefDataSource(t *testing.T) {
13+
14+
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
15+
16+
t.Run("queries an existing ref without error", func(t *testing.T) {
17+
18+
config := fmt.Sprintf(`
19+
resource "github_repository" "test" {
20+
name = "tf-acc-test-%[1]s"
21+
auto_init = true
22+
}
23+
24+
data "github_ref" "test" {
25+
repository = github_repository.test.id
26+
ref = "/heads/main"
27+
}
28+
`, randomID)
29+
30+
check := resource.ComposeTestCheckFunc(
31+
resource.TestMatchResourceAttr(
32+
"data.github_ref.test", "id", regexp.MustCompile(randomID),
33+
),
34+
)
35+
36+
testCase := func(t *testing.T, mode string) {
37+
resource.Test(t, resource.TestCase{
38+
PreCheck: func() { skipUnlessMode(t, mode) },
39+
Providers: testAccProviders,
40+
Steps: []resource.TestStep{
41+
{
42+
Config: config,
43+
Check: check,
44+
},
45+
},
46+
})
47+
}
48+
49+
t.Run("with an anonymous account", func(t *testing.T) {
50+
t.Skip("anonymous account not supported for this operation")
51+
})
52+
53+
t.Run("with an individual account", func(t *testing.T) {
54+
testCase(t, individual)
55+
})
56+
57+
t.Run("with an organization account", func(t *testing.T) {
58+
testCase(t, organization)
59+
})
60+
61+
})
62+
63+
t.Run("queries an invalid ref without error", func(t *testing.T) {
64+
65+
config := fmt.Sprintf(`
66+
resource "github_repository" "test" {
67+
name = "tf-acc-test-%[1]s"
68+
auto_init = true
69+
}
70+
71+
data "github_ref" "test" {
72+
repository = github_repository.test.id
73+
ref = "heads/xxxxxx"
74+
}
75+
`, randomID)
76+
77+
check := resource.ComposeTestCheckFunc(
78+
resource.TestCheckNoResourceAttr(
79+
"data.github_ref.test", "id",
80+
),
81+
)
82+
83+
testCase := func(t *testing.T, mode string) {
84+
resource.Test(t, resource.TestCase{
85+
PreCheck: func() { skipUnlessMode(t, mode) },
86+
Providers: testAccProviders,
87+
Steps: []resource.TestStep{
88+
{
89+
Config: config,
90+
Check: check,
91+
},
92+
},
93+
})
94+
}
95+
96+
t.Run("with an anonymous account", func(t *testing.T) {
97+
t.Skip("anonymous account not supported for this operation")
98+
})
99+
100+
t.Run("with an individual account", func(t *testing.T) {
101+
testCase(t, individual)
102+
})
103+
104+
t.Run("with an organization account", func(t *testing.T) {
105+
testCase(t, organization)
106+
})
107+
108+
})
109+
}

github/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ func Provider() terraform.ResourceProvider {
137137
"github_organization": dataSourceGithubOrganization(),
138138
"github_organization_team_sync_groups": dataSourceGithubOrganizationTeamSyncGroups(),
139139
"github_organization_teams": dataSourceGithubOrganizationTeams(),
140+
"github_ref": dataSourceGithubRef(),
140141
"github_release": dataSourceGithubRelease(),
141142
"github_repositories": dataSourceGithubRepositories(),
142143
"github_repository": dataSourceGithubRepository(),

website/docs/d/ref.html.markdown

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
layout: "github"
3+
page_title: "GitHub: github_ref"
4+
description: |-
5+
Get information about a repository ref.
6+
---
7+
8+
# github\ref
9+
10+
Use this data source to retrieve information about a repository ref.
11+
12+
## Example Usage
13+
14+
```hcl
15+
data "github_ref" "development" {
16+
repository = "example"
17+
ref = "heads/development"
18+
}
19+
```
20+
21+
## Argument Reference
22+
23+
The following arguments are supported:
24+
25+
* `repository` - (Required) The GitHub repository name.
26+
27+
* `ref` - (Required) The repository ref to look up. Must be formatted `heads/<ref>` for branches, and `tags/<ref>` for tags.
28+
29+
## Attribute Reference
30+
31+
The following additional attributes are exported:
32+
33+
* `etag` - An etag representing the ref.
34+
35+
* `sha` - A string storing the reference's `HEAD` commit's SHA1.

website/github.erb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
<li>
3838
<a href="/docs/providers/github/d/organization_teams.html">github_organization_teams</a>
3939
</li>
40+
<li>
41+
<a href="/docs/providers/github/d/ref.html">github_ref</a>
42+
</li>
4043
<li>
4144
<a href="/docs/providers/github/d/release.html">github_release</a>
4245
</li>

0 commit comments

Comments
 (0)