Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add tree data source #1027

Merged
merged 5 commits into from
Mar 18, 2022
Merged

feat: add tree data source #1027

merged 5 commits into from
Mar 18, 2022

Conversation

jasonwalsh
Copy link
Contributor

Not sure if this is a desired data source, but I had a use case where I needed to find specific files in a GitHub repository using this provider and there was no such way. I ended up using the http data source to issue a request to the Get a tree endpoint, but decided to write a data source for it.

This is my first time contributing to a Terraform provider, so if I need to make any changes to the data source code or the acceptance tests, please let me know.

This pull request adds a new data source github_tree which returns a single tree given a SHA1 value. See Get a tree from the GitHub documentation.

An example is as follows:

resource "github_repository" "this" {
  name = "my-repo"
}

data "github_branch" "this" {
  branch     = "main"
  repository = github_repository.this.name
}

data "github_tree" "this" {
  recursive  = true
  repository = github_repository.this.name
  tree_sha   = data.github_branch.this.sha
}

output "entries" {
  value = data.github_tree.this.entries
}

Which would output something like:

entries = tolist([
  {
    "mode" = "100644"
    "path" = ".gitignore"
    "sha" = "7a3e2fd0945d0099d4f7604518b7e863c57069c0"
    "size" = 716
    "type" = "blob"
  },
  {
    "mode" = "100644"
    "path" = "LICENSE"
    "sha" = "4158a3a44c13ca0bcb249210565ae0cd718a2057"
    "size" = 1074
    "type" = "blob"
  },
  {
    "mode" = "100644"
    "path" = "README.md"
    "sha" = "5314ef162955d8e2bff4a6f5a565e14f30a5aa6c"
    "size" = 71
    "type" = "blob"
  },
])

Returns a single tree using the SHA1 value for that tree.
@jcudit jcudit added this to the v4.20.0 milestone Jan 20, 2022
@kfcampbell
Copy link
Member

Interesting! Do you mind explaining a little bit more about the use case for this?

Also, would you mind providing relevant updates to the website docs?

Also also: it looks like the build is red right now due to a go fmt error; let me know if you'd like me to push the fix or you'd rather. Thanks!

@jasonwalsh
Copy link
Contributor Author

Hey @kfcampbell,

My use case may be really specific, so if it doesn't create much value to add this data source, then it's no problem.

Our team uses env0 to manage Terraform operations like apply and plan. env0 uses templates, which are containers for Terraform configurations that are associated with an SCM like GitHub or GItLab.

Regarding my use case; I wrote a Terraform module for creating projects in env0 using their official provider. The module reads a YAML file which contains an array of desired projects to create in env0.

For example, the configuration file could look something like the following:

- repository: hashicorp/hashicat-aws
  terraform_version: 1.1.2
  variables:
    - category: env
      key: AWS_DEFAULT_REGION
      value: us-east-1

Which would create a new project named hashicat-aws and then use the Get a tree endpoint to discover all of the files ending in .tf or .tf.json in that repository.

The Terraform config for discovering these files looks like the following:

locals {
  // Filters the elements in the tree to only include files ending in `.tf` or `.tf.json`.
  templates = toset([
    for element in jsondecode(data.http.this.body)["tree"] :
    dirname(element.path)
    if element.type == "blob" && length(regexall("\\w+(.tf|.tf.json)$", element.path)) > 0
  ])
}

// Fetches the tree for a specific commit. By default the latest commit of
// the default branch (e.g., `main`).
data "http" "this" {
  request_headers = {
    Accept        = "application/vnd.github.v3+json"
    Authorization = "token ${var.token}"
  }

  url = "https://api.github.com/repos/${local.owner}/${local.repository.name}/git/trees/${data.github_branch.this.sha}?recursive=true"
}

// Creates an env0 template for each directory that contains `.tf` or `.tf.json` files.
// For example, the `hashicorp/hashicat-aws` repository contains `.tf` files in the
// root of the repository, so a single env0 template is created: `env0_template.this["."]`.
resource "env0_template" "this" {
  for_each = local.templates

  description            = "Managed by Terraform"
  github_installation_id = 21147410
  name                   = basename(each.value) == "." ? env0_project.this.name : basename(each.value)
  path                   = each.value
  repository             = local.repository.html_url
  revision               = local.repository.default_branch
  terraform_version      = var.terraform_version
  type                   = "terraform"
}

In order to run Terraform, I need to input the token variable, so the command looks like:

terraform apply -var="token=$GITHUB_TOKEN"

Since this new data source would be part of the GitHub provider, it would remove the need to define a token variable since that can be configured in the provider using the token argument of by reading the value of the GITHUB_TOKEN environment variable.

I hope I was able to explain this well. If something doesn't make sense, please let me know and I'll do my best to explain further.

I'll also run go fmt and update the website docs in separate commits.

Thank you!

@jasonwalsh
Copy link
Contributor Author

When I run go fmt against github/data_source_github_tree.go it does not complain, but the make lint target continues to fail. What am I missing?

@kfcampbell
Copy link
Member

@jasonwalsh I ran make fmt in this commit and the checks passed. Perhaps you could try the same command here?

I can be convinced to include the data source when the docs are updated! Thanks for contributing.

@jasonwalsh
Copy link
Contributor Author

@kfcampbell ran make fmt and updated the docs. Let me know if there is anything else I should do. Thanks for your quick responses!

@kfcampbell kfcampbell modified the milestones: v4.20.0, v4.21.0 Mar 3, 2022
Copy link
Member

@kfcampbell kfcampbell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry, I missed one more thing earlier! Do you mind linking to the new docs page you added on this doc? That way the sweet new docs page you added will be discoverable. Thank you!

@kfcampbell kfcampbell modified the milestones: v4.21.0, v4.22.0 Mar 11, 2022
@jasonwalsh
Copy link
Contributor Author

@kfcampbell done

@kfcampbell kfcampbell merged commit 00481c0 into integrations:main Mar 18, 2022
kfcampbell pushed a commit to kfcampbell/terraform-provider-github that referenced this pull request Jul 26, 2022
* feat: add `tree` data source

Returns a single tree using the SHA1 value for that tree.

* test: add acceptance test for `github_tree`

* syle: run `make fmt` command

* docs: add documentation for new data source

* docs: add link to website
kazaker pushed a commit to auto1-oss/terraform-provider-github that referenced this pull request Dec 28, 2022
* feat: add `tree` data source

Returns a single tree using the SHA1 value for that tree.

* test: add acceptance test for `github_tree`

* syle: run `make fmt` command

* docs: add documentation for new data source

* docs: add link to website
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants