-
Notifications
You must be signed in to change notification settings - Fork 903
🏳️ Custom properties resource & data #2107
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
Conversation
d5be511 to
3432109
Compare
3432109 to
3011363
Compare
|
If I'm ready this correctly, this is only adding support to create/read custom properties definitions, would it also be possible to add support for defining custom properties values (by repo)? |
| if err := resourceGithubCustomPropertiesCreate(d, meta); err != nil { | ||
| return err | ||
| } | ||
| return resourceGithubTeamRead(d, meta) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you probably want to return the resourceGithubCustomPropertiesRead(d, meta) value, I guess this is a typo
I've looked a bit into it, and it should be possible once PR #2188 is merged to update go-github, since there was bug relating to that api that was fixed. I'm likely to try to build a working version of that feature on my side, i'll follow up there once it's done. |
| "default_value": { | ||
| Type: schema.TypeString, | ||
| Description: "The default value of the custom property", | ||
| Optional: true, | ||
| Computed: true, | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm working in the repository level equivalents of these resources (i.e., github_repository_custom_properties as opposed to github_organization_custom_properties) in #2316. The value of a custom property, and by extension the default_value of it as well, can either be a string or a list of strings depending on the type of custom property (multi_select --> list of strings). See Response schema in the API docs.
I've opted to represent list values as a comma separated string for simplicity (eg "option1,option2"), and would suggest doing so here as well. It wouldn't change the schema at all, only the logic when creating a custom property of type multi_select
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't use comma-separated strings for this! We have a use-case for explicitly using comma-separated strings as the values within our multi-select custom properties :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Back to the drawing board then 😅
I guess it's possible to use something other than a comma as a separator, but that has the same problem if someone actually has a usecase for it.
Another alternative is having two different attributes depending on the property type. valueList for multi_select and valueString for the rest. And have some logic for not allowing both to be set at the same time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about an explicitly dynamic type with validation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh cool, I wasn't aware that existed! I've restricted myself to the Terraform SDKv2 docs so far, as that is what this project is using (it upgraded from SDKv1 in Januari #1780). Dynamic values are only available if you use the Terraform Plugin Framework. Looking at the Terraform Framework, it looks like it has some major advantages compared to SDKv2.
With that said, going down that path requires buy in from the maintainers of the provider itself, since it's no longer a simple feature request. There seems to be support for using both the Framework and SDKv2 at the same time, but I don't think it's worth adding the framework just for using Dynamic Types for one resource. In that case it should be for the other benefits it brings. I think @kfcampbell is the right person to ask for opinions here
In either case, I think we should be able to figure out an interface for this that doesn't require structural changes to the provider itself,. I can see the following options:
- String with some separator. Bad for the reasons mentioned previously in the thread
valueAsStringandvalueAsStringList- Treat all values as a list of strings. I.e., the
valuefor a non-multi_selectcustom property is a list of strings of length 1, andmutli_selectproperties are a list of length x- Note - Add support for maps with non-primitive types (rich / object map support) hashicorp/terraform-plugin-sdk#62. This limitation makes it so we cannot create an authoritative
github_repository_custom_propertiesresource, i.e., a resource that handles ALL custom_properties for a repo in one go, since that would require a Map of Strings to Lists of Strings. Agithub_repository_custom_propertyresource that can handle 1 single attribute is fine though, since we don't have to use a Map for the custom property names.
- Note - Add support for maps with non-primitive types (rich / object map support) hashicorp/terraform-plugin-sdk#62. This limitation makes it so we cannot create an authoritative
My vote is probably on the latter. It would loke something like:
resource "github_repository_custom_properties" "test" {
repository = "test-custom-properties"
properties = {
true_false = ["true"]
text = ["asd123"]
single_select = ["option1"]
multi_select = ["option2", "option3"]
}
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bother, indeed. I've only been working with the newer framework recently.
Bear in mind that whilst they're likely not yet exposed through go-github, upstream custom properties already support additional types, including boolean and multi-select, so argument per-type likely doesn't scale well into the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mhm, looks like my idea of treating everything as lists of string isn't supported by SDKv2 either... hashicorp/terraform-plugin-sdk#62.
The issue above essentially says that the values of a Terraform map can only be primitive values, which includes TypeBool, TypeInt, TypeFloat, and TypeString. This means that multi_select custom property values, which are lists, has to be represented as a TypeString as long as SDKv2 is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, actually the above is only true as long as the schema is using a Map structure, which is how I've currently implemented the github_repository_custom_properties datasource since it reads all custom properties of the repo. Nothing stops the default_value in this PR to be either a TypeList/TypeString
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with the internals of Terraform providers, but would it make sense to use a property block instead?
resource "github_repository_custom_properties" "test" {
repository = "test-custom-properties"
property {
name = "true_false"
value = ["true"]
}
property {
name = "text"
value = ["asd123"]
}
property {
name = "single_select"
value = ["option1"]
}
property {
name = "multi_select"
value = ["option2", "option3"]
}
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Internally, blocks are implemented more-or-less the same as object lists. Sense idiomatic to me.
Whether implemented with blocks or not, what about encoding the values as JSON to support the different property types. This is pretty common pattern, and HCL lends itself to easy marshal/unmarshal.
I would also personally vote for this being introduced as a block on the existing github_repository resource rather than introducing another (with associated per-resource billing models from most commercial state backends)
resource "github_repository" {
...
custom_property {
name = "owner"
value = jsonencode("bob")
}
custom_property {
name = "PoC"
value = jsonencode(true)
}
custom_property {
name = "promotion_flow"
value = jsonencode(["main","staging","production"])
}
}Edit: oops, this example really belongs on the other PR, but the point about JSON encoding the options holds :-)
|
➕ 1️⃣ on getting this merged. Would love to migrate our bash scripts to TF, but need this functionality. |
|
CI is failing because it's looking for an older version of go-github @ v57 whereas the version in branch is v66. |
|
Additionally, we will need to merge in docs for this change after this PR get's merged. |
nickfloyd
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving, with the need for a fast follow up on getting linting working as well as docs merged in.
Resolves #1956
Before the change?
After the change?
Pull request checklist
Does this introduce a breaking change?
Please see our docs on breaking changes to help!