Skip to content

Commit 696957f

Browse files
committed
feat: add github_release_asset data source
This addresses issue #2513 and adds support for a `github_release_asset` data source. Example of passing acceptance tests: ``` GITHUB_ORGANIZATION=mterwill \ GITHUB_OWNER=mterwill \ TF_ACC=1 \ go test -v ./... -run ^TestAccGithubReleaseAssetDataSource ? github.com/integrations/terraform-provider-github/v6 [no test files] === RUN TestAccGithubReleaseAssetDataSource === RUN TestAccGithubReleaseAssetDataSource/queries_specified_asset_ID === RUN TestAccGithubReleaseAssetDataSource/queries_specified_asset_ID/with_an_anonymous_account provider_utils.go:51: GITHUB_TOKEN environment variable should be empty provider_utils.go:74: Skipping TestAccGithubReleaseAssetDataSource/queries_specified_asset_ID/with_an_anonymous_account which requires anonymous mode === RUN TestAccGithubReleaseAssetDataSource/queries_specified_asset_ID/with_an_individual_account === RUN TestAccGithubReleaseAssetDataSource/queries_specified_asset_ID/with_an_organization_account --- PASS: TestAccGithubReleaseAssetDataSource (11.65s) --- PASS: TestAccGithubReleaseAssetDataSource/queries_specified_asset_ID (11.65s) --- SKIP: TestAccGithubReleaseAssetDataSource/queries_specified_asset_ID/with_an_anonymous_account (0.00s) --- PASS: TestAccGithubReleaseAssetDataSource/queries_specified_asset_ID/with_an_individual_account (8.90s) --- PASS: TestAccGithubReleaseAssetDataSource/queries_specified_asset_ID/with_an_organization_account (2.75s) PASS ok github.com/integrations/terraform-provider-github/v6/github 12.434s ``` Signed-off-by: Mike Ball <[email protected]>
1 parent 1c11053 commit 696957f

5 files changed

+320
-1
lines changed

github/config.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,10 @@ func (injector *previewHeaderInjectorTransport) RoundTrip(req *http.Request) (*h
186186
header := req.Header.Get(name)
187187
if header == "" {
188188
header = value
189-
} else {
189+
// NOTE: Some API endpoints expect a single Accept: application/octet-stream header.
190+
// If one has been set, it's necessary to preserve it as-is, without
191+
// appending previewHeaders value.
192+
} else if !(strings.ToLower(name) == "accept" && header == "application/octet-stream") {
190193
header = strings.Join([]string{header, value}, ",")
191194
}
192195
req.Header.Set(name, header)
+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package github
2+
3+
import (
4+
"context"
5+
"io"
6+
"strconv"
7+
"strings"
8+
9+
"github.com/google/go-github/v66/github"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
11+
)
12+
13+
func dataSourceGithubReleaseAsset() *schema.Resource {
14+
return &schema.Resource{
15+
Read: dataSourceGithubReleaseAssetRead,
16+
17+
Schema: map[string]*schema.Schema{
18+
"asset_id": {
19+
Type: schema.TypeInt,
20+
Required: true,
21+
},
22+
"owner": {
23+
Type: schema.TypeString,
24+
Required: true,
25+
},
26+
"repository": {
27+
Type: schema.TypeString,
28+
Required: true,
29+
},
30+
"body": {
31+
Type: schema.TypeString,
32+
Computed: true,
33+
},
34+
"url": {
35+
Type: schema.TypeString,
36+
Computed: true,
37+
},
38+
"node_id": {
39+
Type: schema.TypeString,
40+
Computed: true,
41+
},
42+
"name": {
43+
Type: schema.TypeString,
44+
Computed: true,
45+
},
46+
"label": {
47+
Type: schema.TypeString,
48+
Computed: true,
49+
},
50+
"content_type": {
51+
Type: schema.TypeString,
52+
Computed: true,
53+
},
54+
"size": {
55+
Type: schema.TypeInt,
56+
Computed: true,
57+
},
58+
"created_at": {
59+
Type: schema.TypeString,
60+
Computed: true,
61+
},
62+
"updated_at": {
63+
Type: schema.TypeString,
64+
Computed: true,
65+
},
66+
"browser_download_url": {
67+
Type: schema.TypeString,
68+
Computed: true,
69+
},
70+
},
71+
}
72+
}
73+
74+
func dataSourceGithubReleaseAssetRead(d *schema.ResourceData, meta interface{}) error {
75+
repository := d.Get("repository").(string)
76+
owner := d.Get("owner").(string)
77+
78+
client := meta.(*Owner).v3client
79+
ctx := context.Background()
80+
81+
var err error
82+
var asset *github.ReleaseAsset
83+
84+
assetID := int64(d.Get("asset_id").(int))
85+
asset, _, err = client.Repositories.GetReleaseAsset(ctx, owner, repository, assetID)
86+
if err != nil {
87+
return err
88+
}
89+
90+
var respBody io.ReadCloser
91+
clientCopy := client.Client()
92+
respBody, _, err = client.Repositories.DownloadReleaseAsset(ctx, owner, repository, assetID, clientCopy)
93+
if err != nil {
94+
return err
95+
}
96+
defer respBody.Close()
97+
98+
buf := new(strings.Builder)
99+
_, err = io.Copy(buf, respBody)
100+
if err != nil {
101+
return err
102+
}
103+
104+
d.SetId(strconv.FormatInt(asset.GetID(), 10))
105+
err = d.Set("body", buf.String())
106+
if err != nil {
107+
return err
108+
}
109+
err = d.Set("url", asset.URL)
110+
if err != nil {
111+
return err
112+
}
113+
err = d.Set("node_id", asset.NodeID)
114+
if err != nil {
115+
return err
116+
}
117+
err = d.Set("name", asset.Name)
118+
if err != nil {
119+
return err
120+
}
121+
err = d.Set("label", asset.Label)
122+
if err != nil {
123+
return err
124+
}
125+
err = d.Set("content_type", asset.ContentType)
126+
if err != nil {
127+
return err
128+
}
129+
err = d.Set("size", asset.Size)
130+
if err != nil {
131+
return err
132+
}
133+
err = d.Set("created_at", asset.CreatedAt.String())
134+
if err != nil {
135+
return err
136+
}
137+
err = d.Set("created_at", asset.UpdatedAt.String())
138+
if err != nil {
139+
return err
140+
}
141+
err = d.Set("browser_download_url", asset.BrowserDownloadURL)
142+
if err != nil {
143+
return err
144+
}
145+
146+
return nil
147+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package github
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"testing"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
9+
)
10+
11+
func TestAccGithubReleaseAssetDataSource(t *testing.T) {
12+
13+
testReleaseRepository := "go-github-issue-demo-1"
14+
if os.Getenv("GITHUB_TEMPLATE_REPOSITORY") != "" {
15+
testReleaseRepository = os.Getenv("GITHUB_TEMPLATE_REPOSITORY")
16+
}
17+
18+
testReleaseAssetID := "151970555"
19+
if os.Getenv("GITHUB_TEMPLATE_REPOSITORY_RELEASE_ASSET_ID") != "" {
20+
testReleaseAssetID = os.Getenv("GITHUB_TEMPLATE_REPOSITORY_RELEASE_ASSET_ID")
21+
}
22+
23+
testReleaseAssetName := "foo.txt"
24+
if os.Getenv("GITHUB_TEMPLATE_REPOSITORY_RELEASE_ASSET_NAME") != "" {
25+
testReleaseAssetName = os.Getenv("GITHUB_TEMPLATE_REPOSITORY_RELEASE_ASSET_NAME")
26+
}
27+
28+
testReleaseAssetContent := "Hello, world!\n"
29+
if os.Getenv("GITHUB_TEMPLATE_REPOSITORY_RELEASE_ASSET_CONTENT") != "" {
30+
testReleaseAssetContent = os.Getenv("GITHUB_TEMPLATE_REPOSITORY_RELEASE_ASSET_CONTENT")
31+
}
32+
33+
testReleaseOwner := testOrganizationFunc()
34+
35+
t.Run("queries specified asset ID", func(t *testing.T) {
36+
37+
config := fmt.Sprintf(`
38+
data "github_release_asset" "test" {
39+
repository = "%s"
40+
owner = "%s"
41+
asset_id = "%s"
42+
}
43+
`, testReleaseRepository, testReleaseOwner, testReleaseAssetID)
44+
45+
check := resource.ComposeTestCheckFunc(
46+
resource.TestCheckResourceAttr(
47+
"data.github_release_asset.test", "asset_id", testReleaseAssetID,
48+
),
49+
resource.TestCheckResourceAttr(
50+
"data.github_release_asset.test", "name", testReleaseAssetName,
51+
),
52+
resource.TestCheckResourceAttr(
53+
"data.github_release_asset.test", "body", testReleaseAssetContent,
54+
),
55+
)
56+
57+
testCase := func(t *testing.T, mode string) {
58+
resource.Test(t, resource.TestCase{
59+
PreCheck: func() { skipUnlessMode(t, mode) },
60+
Providers: testAccProviders,
61+
Steps: []resource.TestStep{
62+
{
63+
Config: config,
64+
Check: check,
65+
},
66+
},
67+
})
68+
}
69+
70+
t.Run("with an anonymous account", func(t *testing.T) {
71+
testCase(t, anonymous)
72+
})
73+
74+
t.Run("with an individual account", func(t *testing.T) {
75+
testCase(t, individual)
76+
})
77+
78+
t.Run("with an organization account", func(t *testing.T) {
79+
testCase(t, organization)
80+
})
81+
82+
})
83+
84+
}

github/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ func Provider() *schema.Provider {
237237
"github_organization_webhooks": dataSourceGithubOrganizationWebhooks(),
238238
"github_ref": dataSourceGithubRef(),
239239
"github_release": dataSourceGithubRelease(),
240+
"github_release_asset": dataSourceGithubReleaseAsset(),
240241
"github_repositories": dataSourceGithubRepositories(),
241242
"github_repository": dataSourceGithubRepository(),
242243
"github_repository_autolink_references": dataSourceGithubRepositoryAutolinkReferences(),
+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
---
2+
layout: "github"
3+
page_title: "GitHub: github_release_asset"
4+
description: |-
5+
Get information on a GitHub release asset.
6+
---
7+
8+
# github\_release\_asset
9+
10+
Use this data source to retrieve information about a GitHub release asset associated with a specific GitHub release.
11+
12+
## Example Usage
13+
To retrieve the latest release that is present in a repository:
14+
15+
```hcl
16+
data "github_release" "example" {
17+
repository = "example-repository"
18+
owner = "example-owner"
19+
retrieve_by = "latest"
20+
}
21+
```
22+
23+
To retrieve a specific release asset from a repository based on its ID:
24+
25+
```hcl
26+
data "github_release_asset" "example" {
27+
repository = "example-repository"
28+
owner = "example-owner"
29+
asset_id = 12345
30+
}
31+
```
32+
33+
To retrieve the first release asset associated with the the latest release in a repository:
34+
35+
```hcl
36+
data "github_release" "example" {
37+
repository = "example-repository"
38+
owner = "example-owner"
39+
retrieve_by = "latest"
40+
}
41+
42+
data "github_release_asset" "example" {
43+
repository = "example-repository"
44+
owner = "example-owner"
45+
asset_id = data.github_release.example.assets[0].id
46+
}
47+
```
48+
49+
To retrieve all release assets associated with the the latest release in a repository:
50+
51+
```hcl
52+
data "github_release" "example" {
53+
repository = "example-repository"
54+
owner = "example-owner"
55+
retrieve_by = "latest"
56+
}
57+
58+
data "github_release_asset" "example" {
59+
count = length(data.github_release.example.assets)
60+
repository = "example-repository"
61+
owner = "example-owner"
62+
asset_id = data.github_release.example.assets[count.index].id
63+
}
64+
```
65+
66+
## Argument Reference
67+
68+
* `repository` - (Required) Name of the repository to retrieve the release from.
69+
* `owner` - (Required) Owner of the repository.
70+
* `asset_id` - (Required) ID of the release asset to retrieve.
71+
72+
## Attributes Reference
73+
74+
* `id` - ID of the asset
75+
* `url` - URL of the asset
76+
* `node_id` - Node ID of the asset
77+
* `name` - The file name of the asset
78+
* `label` - Label for the asset
79+
* `content_type` - MIME type of the asset
80+
* `size` - Size in byte
81+
* `created_at` - Date the asset was created
82+
* `updated_at` - Date the asset was last updated
83+
* `browser_download_url` - Browser download URL
84+
* `body` - The release asset body

0 commit comments

Comments
 (0)