Skip to content

Commit de6596b

Browse files
authored
Add provider-defined version function (#592)
This PR adds a new provider-defined function `provider::apko::version()` that returns version information for both the terraform-provider-apko and the underlying apko package. ## Changes - **New Function**: Added `provider::apko::version()` function that returns an object with: - `provider_version`: The version of the terraform-provider-apko - `apko_version`: The version of the underlying apko package - **Implementation**: - Created `version_function.go` with the function implementation - Updated provider to register the function in the `Functions()` method - Function uses runtime debug info to detect apko package version - **Testing**: - Added acceptance test with `TF_ACC=1` support - Test verifies both provider and apko versions are returned correctly - **Documentation**: - Created example usage in `examples/functions/apko_version/` ## Usage Example ```terraform locals { version_info = provider::apko::version() } output "provider_version" { value = local.version_info.provider_version } output "apko_version" { value = local.version_info.apko_version } ``` This provides a cleaner UX compared to data sources for simple version queries. --------- Signed-off-by: Jason Hall <[email protected]>
1 parent b6fbce8 commit de6596b

File tree

5 files changed

+174
-0
lines changed

5 files changed

+174
-0
lines changed

docs/functions/version.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "version function - terraform-provider-apko"
4+
subcategory: ""
5+
description: |-
6+
Get version information
7+
---
8+
9+
# function: version
10+
11+
Returns version information for the terraform-provider-apko and the underlying apko package.
12+
13+
14+
15+
## Signature
16+
17+
<!-- signature generated by tfplugindocs -->
18+
```text
19+
version() object
20+
```
21+
22+
## Arguments
23+
24+
<!-- arguments generated by tfplugindocs -->
25+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
terraform {
2+
required_providers {
3+
apko = {
4+
source = "chainguard-dev/apko"
5+
}
6+
}
7+
}
8+
9+
locals {
10+
version_info = provider::apko::version()
11+
}
12+
13+
output "provider_version" {
14+
description = "The version of the terraform-provider-apko"
15+
value = local.version_info.provider_version
16+
}
17+
18+
output "apko_version" {
19+
description = "The version of the underlying apko package"
20+
value = local.version_info.apko_version
21+
}
22+
23+
output "all_version_info" {
24+
description = "Complete version information object"
25+
value = local.version_info
26+
}

internal/provider/provider.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
1212
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
1313
"github.com/hashicorp/terraform-plugin-framework/datasource"
14+
"github.com/hashicorp/terraform-plugin-framework/function"
1415
"github.com/hashicorp/terraform-plugin-framework/provider"
1516
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
1617
"github.com/hashicorp/terraform-plugin-framework/resource"
@@ -196,6 +197,14 @@ func (p *Provider) DataSources(ctx context.Context) []func() datasource.DataSour
196197
}
197198
}
198199

200+
func (p *Provider) Functions(ctx context.Context) []func() function.Function {
201+
return []func() function.Function{
202+
func() function.Function {
203+
return NewVersionFunction(p.version)
204+
},
205+
}
206+
}
207+
199208
func New(version string) func() provider.Provider {
200209
return func() provider.Provider {
201210
return &Provider{
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"runtime/debug"
6+
7+
"github.com/hashicorp/terraform-plugin-framework/attr"
8+
"github.com/hashicorp/terraform-plugin-framework/function"
9+
"github.com/hashicorp/terraform-plugin-framework/types"
10+
)
11+
12+
// Ensure provider defined types fully satisfy framework interfaces.
13+
var _ function.Function = &VersionFunction{}
14+
15+
func NewVersionFunction(providerVersion string) function.Function {
16+
return &VersionFunction{
17+
providerVersion: providerVersion,
18+
}
19+
}
20+
21+
// VersionFunction defines the function implementation.
22+
type VersionFunction struct {
23+
providerVersion string
24+
}
25+
26+
func (f *VersionFunction) Metadata(ctx context.Context, req function.MetadataRequest, resp *function.MetadataResponse) {
27+
resp.Name = "version"
28+
}
29+
30+
func (f *VersionFunction) Definition(ctx context.Context, req function.DefinitionRequest, resp *function.DefinitionResponse) {
31+
resp.Definition = function.Definition{
32+
Summary: "Get version information",
33+
MarkdownDescription: "Returns version information for the terraform-provider-apko and the underlying apko package.",
34+
Return: function.ObjectReturn{
35+
AttributeTypes: map[string]attr.Type{
36+
"provider_version": types.StringType,
37+
"apko_version": types.StringType,
38+
},
39+
},
40+
}
41+
}
42+
43+
func (f *VersionFunction) Run(ctx context.Context, req function.RunRequest, resp *function.RunResponse) {
44+
// Use the provider version stored in the function
45+
providerVersion := f.providerVersion
46+
if providerVersion == "" {
47+
providerVersion = "unknown"
48+
}
49+
50+
// Get the apko version from build info
51+
apkoVersion := "unknown"
52+
if info, ok := debug.ReadBuildInfo(); ok {
53+
for _, dep := range info.Deps {
54+
if dep.Path == "chainguard.dev/apko" {
55+
apkoVersion = dep.Version
56+
break
57+
}
58+
}
59+
}
60+
61+
// Create the return object
62+
objectValue, diags := types.ObjectValue(
63+
map[string]attr.Type{
64+
"provider_version": types.StringType,
65+
"apko_version": types.StringType,
66+
},
67+
map[string]attr.Value{
68+
"provider_version": types.StringValue(providerVersion),
69+
"apko_version": types.StringValue(apkoVersion),
70+
},
71+
)
72+
73+
if diags.HasError() {
74+
resp.Error = function.FuncErrorFromDiags(ctx, diags)
75+
return
76+
}
77+
78+
resp.Error = function.ConcatFuncErrors(resp.Error, resp.Result.Set(ctx, objectValue))
79+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package provider
2+
3+
import (
4+
"regexp"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
8+
)
9+
10+
func TestAccVersionFunction(t *testing.T) {
11+
resource.UnitTest(t, resource.TestCase{
12+
PreCheck: func() { testAccPreCheck(t) },
13+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
14+
Steps: []resource.TestStep{{
15+
Config: `
16+
locals {
17+
version_info = provider::apko::version()
18+
}
19+
20+
output "provider_version" {
21+
value = local.version_info.provider_version
22+
}
23+
24+
output "apko_version" {
25+
value = local.version_info.apko_version
26+
}`,
27+
Check: resource.ComposeTestCheckFunc(
28+
// Check that the provider version is "test" (as set in testAccProtoV6ProviderFactories)
29+
resource.TestCheckOutput("provider_version", "test"),
30+
// Check that apko version is not empty and looks like a version
31+
resource.TestMatchOutput("apko_version", regexp.MustCompile(`^v\d+\.\d+\.\d+.*|unknown$`)),
32+
),
33+
}},
34+
})
35+
}

0 commit comments

Comments
 (0)