Skip to content

Commit

Permalink
feat: add github_release_asset data source
Browse files Browse the repository at this point in the history
This addresses issue integrations#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 <mikedball@gmail.com>
  • Loading branch information
mdb committed Dec 17, 2024
1 parent 1c11053 commit 696957f
Show file tree
Hide file tree
Showing 5 changed files with 320 additions and 1 deletion.
5 changes: 4 additions & 1 deletion github/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,10 @@ func (injector *previewHeaderInjectorTransport) RoundTrip(req *http.Request) (*h
header := req.Header.Get(name)
if header == "" {
header = value
} else {
// NOTE: Some API endpoints expect a single Accept: application/octet-stream header.
// If one has been set, it's necessary to preserve it as-is, without
// appending previewHeaders value.
} else if !(strings.ToLower(name) == "accept" && header == "application/octet-stream") {
header = strings.Join([]string{header, value}, ",")
}
req.Header.Set(name, header)
Expand Down
147 changes: 147 additions & 0 deletions github/data_source_github_release_asset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package github

import (
"context"
"io"
"strconv"
"strings"

"github.com/google/go-github/v66/github"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourceGithubReleaseAsset() *schema.Resource {
return &schema.Resource{
Read: dataSourceGithubReleaseAssetRead,

Schema: map[string]*schema.Schema{
"asset_id": {
Type: schema.TypeInt,
Required: true,
},
"owner": {
Type: schema.TypeString,
Required: true,
},
"repository": {
Type: schema.TypeString,
Required: true,
},
"body": {
Type: schema.TypeString,
Computed: true,
},
"url": {
Type: schema.TypeString,
Computed: true,
},
"node_id": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"label": {
Type: schema.TypeString,
Computed: true,
},
"content_type": {
Type: schema.TypeString,
Computed: true,
},
"size": {
Type: schema.TypeInt,
Computed: true,
},
"created_at": {
Type: schema.TypeString,
Computed: true,
},
"updated_at": {
Type: schema.TypeString,
Computed: true,
},
"browser_download_url": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func dataSourceGithubReleaseAssetRead(d *schema.ResourceData, meta interface{}) error {
repository := d.Get("repository").(string)
owner := d.Get("owner").(string)

client := meta.(*Owner).v3client
ctx := context.Background()

var err error
var asset *github.ReleaseAsset

assetID := int64(d.Get("asset_id").(int))
asset, _, err = client.Repositories.GetReleaseAsset(ctx, owner, repository, assetID)
if err != nil {
return err
}

var respBody io.ReadCloser
clientCopy := client.Client()
respBody, _, err = client.Repositories.DownloadReleaseAsset(ctx, owner, repository, assetID, clientCopy)
if err != nil {
return err
}
defer respBody.Close()

buf := new(strings.Builder)
_, err = io.Copy(buf, respBody)
if err != nil {
return err
}

d.SetId(strconv.FormatInt(asset.GetID(), 10))
err = d.Set("body", buf.String())
if err != nil {
return err
}
err = d.Set("url", asset.URL)
if err != nil {
return err
}
err = d.Set("node_id", asset.NodeID)
if err != nil {
return err
}
err = d.Set("name", asset.Name)
if err != nil {
return err
}
err = d.Set("label", asset.Label)
if err != nil {
return err
}
err = d.Set("content_type", asset.ContentType)
if err != nil {
return err
}
err = d.Set("size", asset.Size)
if err != nil {
return err
}
err = d.Set("created_at", asset.CreatedAt.String())
if err != nil {
return err
}
err = d.Set("created_at", asset.UpdatedAt.String())
if err != nil {
return err
}
err = d.Set("browser_download_url", asset.BrowserDownloadURL)
if err != nil {
return err
}

return nil
}
84 changes: 84 additions & 0 deletions github/data_source_github_release_asset_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package github

import (
"fmt"
"os"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccGithubReleaseAssetDataSource(t *testing.T) {

testReleaseRepository := "go-github-issue-demo-1"
if os.Getenv("GITHUB_TEMPLATE_REPOSITORY") != "" {
testReleaseRepository = os.Getenv("GITHUB_TEMPLATE_REPOSITORY")
}

testReleaseAssetID := "151970555"
if os.Getenv("GITHUB_TEMPLATE_REPOSITORY_RELEASE_ASSET_ID") != "" {
testReleaseAssetID = os.Getenv("GITHUB_TEMPLATE_REPOSITORY_RELEASE_ASSET_ID")
}

testReleaseAssetName := "foo.txt"
if os.Getenv("GITHUB_TEMPLATE_REPOSITORY_RELEASE_ASSET_NAME") != "" {
testReleaseAssetName = os.Getenv("GITHUB_TEMPLATE_REPOSITORY_RELEASE_ASSET_NAME")
}

testReleaseAssetContent := "Hello, world!\n"
if os.Getenv("GITHUB_TEMPLATE_REPOSITORY_RELEASE_ASSET_CONTENT") != "" {
testReleaseAssetContent = os.Getenv("GITHUB_TEMPLATE_REPOSITORY_RELEASE_ASSET_CONTENT")
}

testReleaseOwner := testOrganizationFunc()

t.Run("queries specified asset ID", func(t *testing.T) {

config := fmt.Sprintf(`
data "github_release_asset" "test" {
repository = "%s"
owner = "%s"
asset_id = "%s"
}
`, testReleaseRepository, testReleaseOwner, testReleaseAssetID)

check := resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"data.github_release_asset.test", "asset_id", testReleaseAssetID,
),
resource.TestCheckResourceAttr(
"data.github_release_asset.test", "name", testReleaseAssetName,
),
resource.TestCheckResourceAttr(
"data.github_release_asset.test", "body", testReleaseAssetContent,
),
)

testCase := func(t *testing.T, mode string) {
resource.Test(t, resource.TestCase{
PreCheck: func() { skipUnlessMode(t, mode) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: config,
Check: check,
},
},
})
}

t.Run("with an anonymous account", func(t *testing.T) {
testCase(t, anonymous)
})

t.Run("with an individual account", func(t *testing.T) {
testCase(t, individual)
})

t.Run("with an organization account", func(t *testing.T) {
testCase(t, organization)
})

})

}
1 change: 1 addition & 0 deletions github/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ func Provider() *schema.Provider {
"github_organization_webhooks": dataSourceGithubOrganizationWebhooks(),
"github_ref": dataSourceGithubRef(),
"github_release": dataSourceGithubRelease(),
"github_release_asset": dataSourceGithubReleaseAsset(),
"github_repositories": dataSourceGithubRepositories(),
"github_repository": dataSourceGithubRepository(),
"github_repository_autolink_references": dataSourceGithubRepositoryAutolinkReferences(),
Expand Down
84 changes: 84 additions & 0 deletions website/docs/d/release_asset.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
layout: "github"
page_title: "GitHub: github_release_asset"
description: |-
Get information on a GitHub release asset.
---

# github\_release\_asset

Use this data source to retrieve information about a GitHub release asset associated with a specific GitHub release.

## Example Usage
To retrieve the latest release that is present in a repository:

```hcl
data "github_release" "example" {
repository = "example-repository"
owner = "example-owner"
retrieve_by = "latest"
}
```

To retrieve a specific release asset from a repository based on its ID:

```hcl
data "github_release_asset" "example" {
repository = "example-repository"
owner = "example-owner"
asset_id = 12345
}
```

To retrieve the first release asset associated with the the latest release in a repository:

```hcl
data "github_release" "example" {
repository = "example-repository"
owner = "example-owner"
retrieve_by = "latest"
}
data "github_release_asset" "example" {
repository = "example-repository"
owner = "example-owner"
asset_id = data.github_release.example.assets[0].id
}
```

To retrieve all release assets associated with the the latest release in a repository:

```hcl
data "github_release" "example" {
repository = "example-repository"
owner = "example-owner"
retrieve_by = "latest"
}
data "github_release_asset" "example" {
count = length(data.github_release.example.assets)
repository = "example-repository"
owner = "example-owner"
asset_id = data.github_release.example.assets[count.index].id
}
```

## Argument Reference

* `repository` - (Required) Name of the repository to retrieve the release from.
* `owner` - (Required) Owner of the repository.
* `asset_id` - (Required) ID of the release asset to retrieve.

## Attributes Reference

* `id` - ID of the asset
* `url` - URL of the asset
* `node_id` - Node ID of the asset
* `name` - The file name of the asset
* `label` - Label for the asset
* `content_type` - MIME type of the asset
* `size` - Size in byte
* `created_at` - Date the asset was created
* `updated_at` - Date the asset was last updated
* `browser_download_url` - Browser download URL
* `body` - The release asset body

0 comments on commit 696957f

Please sign in to comment.