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: support repository level custom_property resource and custom_properties datasource #2316

Merged
merged 40 commits into from
Jan 17, 2025
Merged
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
a7e562c
add octokit sdk client
Jul 12, 2024
af0245a
stash half working solution
Jul 12, 2024
cdd112a
add repository custom properties data source
Jul 13, 2024
f9633fb
break out custom props parsing logic to its own function
Jul 13, 2024
5e0894d
use background ctx
Jul 14, 2024
2accb56
format provider.go
Jul 14, 2024
b3f44ca
fix error msg to include repoName instead of its pointer
Jul 15, 2024
98947a3
use type switch instead of if else
Jul 15, 2024
2125cab
fix linting errors
Jul 15, 2024
ec2755e
restructure datasource to take a property name and call it github_rep…
Jul 16, 2024
1e88e7a
formatting
Jul 16, 2024
31f9a2b
rename file to match datasource name
Jul 16, 2024
5ed47ba
Merge branch 'main' into repository-custom-properties
felixlut Jul 31, 2024
697c43c
remove go-sdk in favor of go-github
Oct 5, 2024
9933170
implement data_source_github_repository_custom_property with go-github
Oct 5, 2024
a7aefae
implement resource_github_repository_custom_property
Oct 5, 2024
ce87c42
update descriptions
Oct 5, 2024
6b76479
remove custom_property resource in favour of custom_propertIES one
Oct 9, 2024
d9ad9a9
add custom_property resource to provider.go
Oct 9, 2024
7982a1a
formatting
Oct 9, 2024
7366a88
add tests for repository_custom_property
Oct 9, 2024
fe5add1
update description of test
Oct 9, 2024
0dbd149
add tests for each custom_property type
Oct 9, 2024
d9f13fd
rollback repo changes
Oct 9, 2024
7615100
add tests for custom_property datasource
Oct 9, 2024
c72ce22
formatting
Oct 9, 2024
bc93a88
Merge branch 'main' into repository-custom-properties
felixlut Oct 9, 2024
d298e07
breakout parsing custom_property_value as a string slice to its own f…
Oct 9, 2024
8eff6f4
Merge branch 'main' into repository-custom-properties
felixlut Nov 21, 2024
3deb3ed
bump go-github to v66 for new files
felixlut Nov 21, 2024
31ac7db
add property_type as a required attribute
felixlut Nov 22, 2024
10bb6f0
flip datasource to use typeList instead of typeSet
felixlut Nov 22, 2024
1e3ba1d
refactor tests for data source to use property_type
felixlut Nov 22, 2024
5be94bd
Update data_source_github_repository_custom_properties.go
felixlut Nov 22, 2024
d9974e6
cleanup incorrect comments
felixlut Nov 22, 2024
add24a8
remove old comment
felixlut Nov 23, 2024
46c1846
add docs
felixlut Nov 24, 2024
15b61e7
fix typo
felixlut Nov 24, 2024
2b169f1
Merge branch 'main' into repository-custom-properties
felixlut Nov 26, 2024
1b6bfaa
Merge branch 'main' into repository-custom-properties
kfcampbell Jan 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
remove custom_property resource in favour of custom_propertIES one
  • Loading branch information
felixlut committed Oct 9, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 6b76479aad20efa1d552ada596bf1159012eece8
94 changes: 94 additions & 0 deletions github/data_source_github_repository_custom_properties.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package github

import (
"context"
"fmt"

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

func dataSourceGithubRepositoryCustomProperties() *schema.Resource {
return &schema.Resource{
Read: dataSourceGithubOrgaRepositoryCustomProperties,

Schema: map[string]*schema.Schema{
"repository": {
Type: schema.TypeString,
Required: true,
Description: "Name of the repository which the custom properties should be on.",
},
"property": {
Type: schema.TypeSet,
Copy link
Contributor Author

@felixlut felixlut Nov 24, 2024

Choose a reason for hiding this comment

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

The way I see most people using this resource is to:

  1. Read the custom properties of a repo
  2. For each specific property do something based on it's value. Eg, do X to the repo if the owner property equals Y, do Z to the repo if the environment property equals ...

This means that it should be as easy as possible to get the value of a specific property. IMO that would be best achieved by using a TypeMap. Unfortunately that is not supported by v2 of the terraform-plugin-sdk (see thread).

The choice is then between TypeList or TypeSet. Reading the docs the latter sounds more correct to me, as the order of the custom properties does not matter. We've seen issues regarding this in this provider in the past, eg in #1950, that should be avoided by using TypeSet.

It's worth noting that there are some other implications of using TypeSet though, namely that they are non-indexable. This common pattern will for example not work, and throw the error below:

data "github_repository_custom_properties" "test" {
  repository    = "test-custom-properties"
}
locals {
  # Assuming the repo have a property called "string" set already
  test = data.github_repository_custom_properties.test.property[index(data.github_repository_custom_properties.test.property.*.property_name, "string")]
}

image

That does not mean that it's impossible to fetch the value of a custom property though. Either of the two snippets below does work, and are IMO more readable, but I think I'd be amiss if I didn't mention this.

data "github_repository_custom_properties" "test" {
  repository    = "test-custom-properties"
}
locals {
  # Get single custom property
  string_property = one([ for prop in data.github_repository_custom_properties.test.property: prop if prop.property_name == "string" ])
  # Convert the output of the data_source to a map that can then be referenced by `local.property_map[<property_name>]`
  property_map = { for prop in data.github_repository_custom_properties.test.property: prop.property_name => prop.property_value }
}

I personally lean towards using a TypeSet to avoid possible weird diffs, but I don't feel strongly about it. If anyone have any opinions here I'm all ears 😄

Copy link
Contributor

Choose a reason for hiding this comment

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

@felixlut have you considered also adding a github_repository_custom_property data source to access a singular property? It would allow for more direct access to properties at the cost of increased API usage.

Copy link
Contributor Author

@felixlut felixlut Nov 26, 2024

Choose a reason for hiding this comment

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

I have, and nothing stops future PR:s for doing just that. It probably should exist, but you can't do everything in 1 PR 😅

The actual implementation would be to simply filter it after this call

Computed: true,
Description: "List of custom properties",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"property_name": {
Type: schema.TypeString,
Computed: true,
Description: "Name of the custom property.",
},
"property_value": {
Type: schema.TypeSet,
Computed: true,
Description: "Value of the custom property.",
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
},
},
}
}

func dataSourceGithubOrgaRepositoryCustomProperties(d *schema.ResourceData, meta interface{}) error {

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

owner := meta.(*Owner).name

repoName := d.Get("repository").(string)

allCustomProperties, _, err := client.Repositories.GetAllCustomPropertyValues(ctx, owner, repoName)
if err != nil {
return err
}

results, err := flattenRepositoryCustomProperties(allCustomProperties)
if err != nil {
return err
}

d.SetId(buildTwoPartID(owner, repoName))
d.Set("repository", repoName)
d.Set("property", results)

return nil
}

func flattenRepositoryCustomProperties(customProperties []*github.CustomPropertyValue) ([]interface{}, error) {

results := make([]interface{}, 0)
for _, prop := range customProperties {
result := make(map[string]interface{})

result["property_name"] = prop.PropertyName

switch value := prop.Value.(type) {
case string:
result["property_value"] = []string{value}
case []string:
result["property_value"] = value
default:
return nil, fmt.Errorf("custom property value couldn't be parsed as a string or a list of strings: %s", value)
}

results = append(results, result)
}

return results, nil
}
56 changes: 0 additions & 56 deletions github/data_source_github_repository_custom_property.go

This file was deleted.

3 changes: 1 addition & 2 deletions github/provider.go
Original file line number Diff line number Diff line change
@@ -172,7 +172,6 @@ func Provider() *schema.Provider {
"github_repository_dependabot_security_updates": resourceGithubRepositoryDependabotSecurityUpdates(),
"github_repository_collaborator": resourceGithubRepositoryCollaborator(),
"github_repository_collaborators": resourceGithubRepositoryCollaborators(),
"github_repository_custom_property": resourceGithubRepositoryCustomProperty(),
"github_repository_deploy_key": resourceGithubRepositoryDeployKey(),
"github_repository_deployment_branch_policy": resourceGithubRepositoryDeploymentBranchPolicy(),
"github_repository_environment": resourceGithubRepositoryEnvironment(),
@@ -243,7 +242,7 @@ func Provider() *schema.Provider {
"github_repository": dataSourceGithubRepository(),
"github_repository_autolink_references": dataSourceGithubRepositoryAutolinkReferences(),
"github_repository_branches": dataSourceGithubRepositoryBranches(),
"github_repository_custom_property": dataSourceGithubRepositoryCustomProperty(),
"github_repository_custom_properties": dataSourceGithubRepositoryCustomProperties(),
"github_repository_environments": dataSourceGithubRepositoryEnvironments(),
"github_repository_deploy_keys": dataSourceGithubRepositoryDeployKeys(),
"github_repository_deployment_branch_policies": dataSourceGithubRepositoryDeploymentBranchPolicies(),
Loading