Skip to content

Commit 5439872

Browse files
committed
feat(data_source_github_release_asset): make download configurable
Per code review feedback from @stevehipwell (#2514 (review)), this makes the release asset download optional, controlled by a `download_body` attribute, and off by default. Signed-off-by: Mike Ball <mikedball@gmail.com>
1 parent ff9d3ec commit 5439872

3 files changed

Lines changed: 84 additions & 39 deletions

File tree

github/data_source_github_release_asset.go

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,16 @@ func dataSourceGithubReleaseAsset() *schema.Resource {
3232
Required: true,
3333
Description: "Name of the repository to retrieve the release asset from",
3434
},
35+
"download_body": {
36+
Type: schema.TypeBool,
37+
Optional: true,
38+
Default: false,
39+
Description: "Whether to download the asset content into the body attribute",
40+
},
3541
"body": {
3642
Type: schema.TypeString,
3743
Computed: true,
38-
Description: "The release asset body",
44+
Description: "The release asset body (requires download_body to be 'true'",
3945
},
4046
"url": {
4147
Type: schema.TypeString,
@@ -98,35 +104,8 @@ func dataSourceGithubReleaseAssetRead(ctx context.Context, d *schema.ResourceDat
98104
return diag.FromErr(err)
99105
}
100106

101-
// Use a client copy to avoid possible mutation of shared GitHub client state
102-
// by client.Repositories.DownloadReleaseAsset.
103-
clientCopy := client.Client()
104-
req, err := http.NewRequestWithContext(ctx, "GET", asset.GetBrowserDownloadURL(), nil)
105-
if err != nil {
106-
return diag.FromErr(err)
107-
}
108-
109-
req.Header.Set("Accept", "application/octet-stream")
110-
resp, err := clientCopy.Do(req)
111-
if err != nil {
112-
return diag.FromErr(err)
113-
}
114-
defer resp.Body.Close()
115-
116-
if resp.StatusCode != http.StatusOK {
117-
return diag.Errorf("failed to get release asset (%s/%s %d): %s", owner, repository, assetID, resp.Status)
118-
}
119-
120-
buf := new(strings.Builder)
121-
if _, err := io.Copy(buf, resp.Body); err != nil {
122-
return diag.FromErr(err)
123-
}
124-
125107
d.SetId(buildThreePartID(owner, repository, strconv.FormatInt(assetID, 10)))
126108

127-
if err := d.Set("body", buf.String()); err != nil {
128-
return diag.FromErr(err)
129-
}
130109
if err := d.Set("url", asset.URL); err != nil {
131110
return diag.FromErr(err)
132111
}
@@ -155,5 +134,37 @@ func dataSourceGithubReleaseAssetRead(ctx context.Context, d *schema.ResourceDat
155134
return diag.FromErr(err)
156135
}
157136

137+
if !d.Get("download_body").(bool) {
138+
return nil
139+
}
140+
141+
// Use a client copy to avoid possible mutation of shared GitHub client state
142+
// by client.Repositories.DownloadReleaseAsset.
143+
clientCopy := client.Client()
144+
req, err := http.NewRequestWithContext(ctx, "GET", asset.GetBrowserDownloadURL(), nil)
145+
if err != nil {
146+
return diag.FromErr(err)
147+
}
148+
149+
req.Header.Set("Accept", "application/octet-stream")
150+
resp, err := clientCopy.Do(req)
151+
if err != nil {
152+
return diag.FromErr(err)
153+
}
154+
defer resp.Body.Close()
155+
156+
if resp.StatusCode != http.StatusOK {
157+
return diag.Errorf("failed to get release asset (%s/%s %d): %s", owner, repository, assetID, resp.Status)
158+
}
159+
160+
buf := new(strings.Builder)
161+
if _, err := io.Copy(buf, resp.Body); err != nil {
162+
return diag.FromErr(err)
163+
}
164+
165+
if err := d.Set("body", buf.String()); err != nil {
166+
return diag.FromErr(err)
167+
}
168+
158169
return nil
159170
}

github/data_source_github_release_asset_test.go

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ func TestAccGithubReleaseAssetDataSource(t *testing.T) {
1515
testReleaseAssetName := testAccConf.testPublicRelaseAssetName
1616
testReleaseAssetContent := testAccConf.testPublicReleaseAssetContent
1717

18-
t.Run("queries specified asset ID", func(t *testing.T) {
19-
18+
t.Run("queries and downloads specified asset ID", func(t *testing.T) {
2019
config := fmt.Sprintf(`
2120
data "github_release_asset" "test" {
2221
repository = "%s"
2322
owner = "%s"
2423
asset_id = "%s"
24+
download_body = true
2525
}
2626
`, testReleaseRepository, testRepositoryOwner, testReleaseAssetID)
2727

@@ -45,4 +45,34 @@ func TestAccGithubReleaseAssetDataSource(t *testing.T) {
4545
},
4646
})
4747
})
48+
49+
t.Run("queries without downloading the specified asset ID", func(t *testing.T) {
50+
config := fmt.Sprintf(`
51+
data "github_release_asset" "test" {
52+
repository = "%s"
53+
owner = "%s"
54+
asset_id = "%s"
55+
}
56+
`, testReleaseRepository, testRepositoryOwner, testReleaseAssetID)
57+
58+
resource.Test(t, resource.TestCase{
59+
ProviderFactories: providerFactories,
60+
Steps: []resource.TestStep{
61+
{
62+
Config: config,
63+
Check: resource.ComposeTestCheckFunc(
64+
resource.TestCheckResourceAttr(
65+
"data.github_release_asset.test", "asset_id", testReleaseAssetID,
66+
),
67+
resource.TestCheckResourceAttr(
68+
"data.github_release_asset.test", "name", testReleaseAssetName,
69+
),
70+
resource.TestCheckNoResourceAttr(
71+
"data.github_release_asset.test", "body",
72+
),
73+
),
74+
},
75+
},
76+
})
77+
})
4878
}

website/docs/d/release_asset.html.markdown

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,30 @@ description: |-
1010
Use this data source to retrieve information about a GitHub release asset.
1111

1212
## Example Usage
13-
To retrieve the latest release that is present in a repository:
13+
To retrieve a specific release asset from a repository based on its ID:
1414

1515
```hcl
16-
data "github_release" "example" {
16+
data "github_release_asset" "example" {
1717
repository = "example-repository"
1818
owner = "example-owner"
19-
retrieve_by = "latest"
19+
asset_id = 12345
2020
}
2121
```
2222

23-
To retrieve a specific release asset from a repository based on its ID:
23+
To retrieve a specific release asset from a repository, and download its body
24+
into a `body` attribute on the data source:
2425

2526
```hcl
2627
data "github_release_asset" "example" {
27-
repository = "example-repository"
28-
owner = "example-owner"
29-
asset_id = 12345
28+
repository = "example-repository"
29+
owner = "example-owner"
30+
asset_id = 12345
31+
download_body = true
3032
}
3133
```
3234

33-
To retrieve the first release asset associated with the the latest release in a repository:
35+
36+
To retrieve the first release asset associated with the latest release in a repository:
3437

3538
```hcl
3639
data "github_release" "example" {
@@ -68,6 +71,7 @@ data "github_release_asset" "example" {
6871
* `repository` - (Required) Name of the repository to retrieve the release from
6972
* `owner` - (Required) Owner of the repository
7073
* `asset_id` - (Required) ID of the release asset to retrieve
74+
* `download_body` - (Optional) If `true`, download the release asset to the `body` attribute. Defaults to `false`.
7175

7276
## Attributes Reference
7377

@@ -81,4 +85,4 @@ data "github_release_asset" "example" {
8185
* `created_at` - Date the asset was created
8286
* `updated_at` - Date the asset was last updated
8387
* `browser_download_url` - Browser URL from which the release asset can be downloaded
84-
* `body` - The release asset body
88+
* `body` - The release asset body (requires `download_body` to be `true`)

0 commit comments

Comments
 (0)