Skip to content

Commit f03ce51

Browse files
authored
Fix plugin scaffold release versioning (#872)
* fix: stabilize plugin scaffold versions Closes #871 * fix: use positional plugin contract validation
1 parent 6cde9aa commit f03ce51

15 files changed

Lines changed: 262 additions & 44 deletions

File tree

cmd/wfctl/plugin.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func runPluginInit(args []string) error {
9191
}
9292
fs := flag.NewFlagSet("plugin init", flag.ExitOnError)
9393
author := fs.String("author", "", "Plugin author (required)")
94-
ver := fs.String("version", "0.1.0", "Plugin version")
94+
ver := fs.String("version", "0.0.0", "Deprecated; release versions are injected from Git tags")
9595
desc := fs.String("description", "", "Plugin description")
9696
license := fs.String("license", "", "Plugin license")
9797
output := fs.String("output", "", "Output directory (defaults to plugin name)")

cmd/wfctl/plugin_init_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ func TestRunPluginInit_PluginJSON(t *testing.T) {
178178
if pj["version"] == nil || pj["version"].(string) == "" {
179179
t.Error("plugin.json: missing or empty version")
180180
}
181+
if pj["version"].(string) != "0.0.0" {
182+
t.Errorf("version: got %q, want stable plugin.json sentinel %q", pj["version"], "0.0.0")
183+
}
181184
if pj["author"] == nil || pj["author"].(string) == "" {
182185
t.Error("plugin.json: missing or empty author")
183186
}

cmd/wfctl/templates/plugin/.github/workflows/release.yml.tmpl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,20 @@ jobs:
1313
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
1414
with:
1515
go-version: '1.26.4'
16+
- name: Setup wfctl
17+
uses: GoCodeAlone/setup-wfctl@bcd880980f5bbe8d192d0c20ff6279d25331f956 # v1
18+
- name: Validate release contract before packaging
19+
run: wfctl plugin validate-contract --for-publish --tag "${{ "{{" }} github.ref_name {{ "}}" }}" .
1620
- name: Build plugin binaries
1721
run: |
1822
mkdir -p dist
1923
for GOOS in linux darwin; do
2024
for GOARCH in amd64 arm64; do
21-
GOOS=$GOOS GOARCH=$GOARCH go build -o dist/{{.Name}}-$GOOS-$GOARCH ./...
25+
GOOS=$GOOS GOARCH=$GOARCH go build -ldflags "-s -w -X main.Version=${GITHUB_REF_NAME}" -o dist/{{.Name}}-$GOOS-$GOARCH ./...
2226
done
2327
done
28+
- name: Validate packaged release contract
29+
run: wfctl plugin validate-contract --for-publish --tag "${{ "{{" }} github.ref_name {{ "}}" }}" .
2430
- name: Create release
2531
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
2632
with:

cmd/wfctl/templates/plugin/main.go.tmpl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@ import (
55
)
66

77
func main() {
8-
sdk.Serve(&{{.NameCamel}}Plugin{})
8+
sdk.Serve(&{{.NameCamel}}Plugin{},
9+
sdk.WithBuildVersion(sdk.ResolveBuildVersion(Version)),
10+
)
911
}

cmd/wfctl/templates/plugin/plugin.go.tmpl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@ import (
66
"github.com/GoCodeAlone/workflow/plugin/external/sdk"
77
)
88

9+
// Version is injected by the release build so runtime manifests report the tag.
10+
var Version = "dev"
11+
912
// {{.NameCamel}}Plugin implements sdk.PluginProvider, sdk.ModuleProvider, and sdk.StepProvider.
1013
type {{.NameCamel}}Plugin struct{}
1114

1215
// Manifest returns the plugin metadata.
1316
func (p *{{.NameCamel}}Plugin) Manifest() sdk.PluginManifest {
1417
return sdk.PluginManifest{
1518
Name: "{{.Name}}",
16-
Version: "0.1.0",
19+
Version: sdk.ResolveBuildVersion(Version),
1720
Author: "{{.Author}}",
1821
Description: "{{.Description}}",
1922
}

cmd/wfctl/templates/ui-plugin/.github/workflows/release.yml.tmpl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,23 @@ jobs:
1616
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
1717
with:
1818
node-version: '24'
19+
- name: Setup wfctl
20+
uses: GoCodeAlone/setup-wfctl@bcd880980f5bbe8d192d0c20ff6279d25331f956 # v1
1921
- name: Build UI
2022
run: |
2123
cd ui && npm ci && npm run build && cd ..
24+
- name: Validate release contract before packaging
25+
run: wfctl plugin validate-contract --for-publish --tag "${{ "{{" }} github.ref_name {{ "}}" }}" .
2226
- name: Build plugin binaries
2327
run: |
2428
mkdir -p dist
2529
for GOOS in linux darwin; do
2630
for GOARCH in amd64 arm64; do
27-
GOOS=$GOOS GOARCH=$GOARCH go build -o dist/{{.Name}}-$GOOS-$GOARCH ./...
31+
GOOS=$GOOS GOARCH=$GOARCH go build -ldflags "-s -w -X main.Version=${GITHUB_REF_NAME}" -o dist/{{.Name}}-$GOOS-$GOARCH ./...
2832
done
2933
done
34+
- name: Validate packaged release contract
35+
run: wfctl plugin validate-contract --for-publish --tag "${{ "{{" }} github.ref_name {{ "}}" }}" .
3036
- name: Create release
3137
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
3238
with:

cmd/wfctl/templates/ui-plugin/main.go.tmpl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@ import (
55
)
66

77
func main() {
8-
sdk.Serve(&{{.NameCamel}}Plugin{})
8+
sdk.Serve(&{{.NameCamel}}Plugin{},
9+
sdk.WithBuildVersion(sdk.ResolveBuildVersion(Version)),
10+
)
911
}

cmd/wfctl/templates/ui-plugin/plugin.go.tmpl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import (
88
"github.com/GoCodeAlone/workflow/plugin/external/sdk"
99
)
1010

11+
// Version is injected by the release build so runtime manifests report the tag.
12+
var Version = "dev"
13+
1114
//go:embed ui/dist
1215
var uiAssets embed.FS
1316

@@ -18,7 +21,7 @@ type {{.NameCamel}}Plugin struct{}
1821
func (p *{{.NameCamel}}Plugin) Manifest() sdk.PluginManifest {
1922
return sdk.PluginManifest{
2023
Name: "{{.Name}}",
21-
Version: "0.1.0",
24+
Version: sdk.ResolveBuildVersion(Version),
2225
Author: "{{.Author}}",
2326
Description: "{{.Description}}",
2427
}

plugin/doc.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Package plugin contains Workflow's plugin manifest, registry, loading, and
2+
// installation primitives.
3+
//
4+
// Host-side code normally starts with PluginManifest values loaded from
5+
// plugin.json files, then uses Manager, Loader, or Registry implementations to
6+
// resolve plugin metadata and executables. Plugin authors usually consume the
7+
// higher-level packages under plugin/external/sdk and plugin/sdk instead.
8+
package plugin

plugin/external/sdk/doc.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Package sdk is the public runtime SDK for out-of-process Workflow plugins.
2+
//
3+
// Plugin binaries implement PluginProvider plus optional provider interfaces
4+
// such as StepProvider, TypedStepProvider, ModuleProvider, ContractProvider, or
5+
// CLIProvider. A typical main function constructs the provider and calls Serve:
6+
//
7+
// func main() {
8+
// sdk.Serve(internal.NewProvider(),
9+
// sdk.WithBuildVersion(sdk.ResolveBuildVersion(internal.Version)),
10+
// )
11+
// }
12+
//
13+
// Plugins that also expose CLI commands or build hooks can use ServePluginFull.
14+
// IaC provider plugins should use ServeIaCPlugin so typed IaC gRPC services are
15+
// registered and advertised consistently.
16+
package sdk

0 commit comments

Comments
 (0)