Skip to content

Commit 55ab657

Browse files
Add manifest-bundle boundary conformance guard (#5)
Enforce the transport-neutral boundary that issue #5 requires on the plugin side: runtime source and plugin-owned deployment manifests must carry no Git/GitHub/Argo/Flux/reconciler/repository-binding ownership. The upstream contract rename (core#110) is not yet published, so this locks in the invariant the plugin already satisfies and guards against regression when the migration lands. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 843ff34 commit 55ab657

1 file changed

Lines changed: 98 additions & 0 deletions

File tree

‎conformance_test.go‎

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package main
2+
3+
import (
4+
"io/fs"
5+
"os"
6+
"regexp"
7+
"strconv"
8+
"strings"
9+
"testing"
10+
)
11+
12+
// transportOwnershipPatterns are the delivery/reconciliation ownership
13+
// concepts a manifest-producing plugin must never carry. A Codefly plugin
14+
// renders deterministic Kubernetes output from normalized inputs; how that
15+
// output is transported, reviewed, or reconciled belongs to a separate
16+
// promotion driver, not here. Each entry is matched case-insensitively.
17+
var transportOwnershipPatterns = []*regexp.Regexp{
18+
regexp.MustCompile(`(?i)gitops`),
19+
regexp.MustCompile(`(?i)repourl`),
20+
regexp.MustCompile(`(?i)targetrevision`),
21+
regexp.MustCompile(`(?i)appproject`),
22+
regexp.MustCompile(`(?i)argocd`),
23+
regexp.MustCompile(`(?i)argoproj`),
24+
regexp.MustCompile(`(?i)\bflux\b`),
25+
regexp.MustCompile(`(?i)kubeconfig`),
26+
regexp.MustCompile(`(?i)reconcil`),
27+
regexp.MustCompile(`(?i)\bgit\s+(clone|push|commit|checkout|fetch|remote|tag|init|pull)\b`),
28+
regexp.MustCompile(`(?i)\bpull\s+request\b`),
29+
regexp.MustCompile(`(?i)kind:\s*Application\b`),
30+
regexp.MustCompile(`(?i)kind:\s*AppProject\b`),
31+
}
32+
33+
// scan reports every line in content that matches a forbidden pattern,
34+
// formatted as "<name>:<line>: <trimmed source>".
35+
func scanTransportOwnership(name, content string) []string {
36+
var hits []string
37+
for i, line := range strings.Split(content, "\n") {
38+
for _, re := range transportOwnershipPatterns {
39+
if re.MatchString(line) {
40+
hits = append(hits, name+":"+strconv.Itoa(i+1)+": "+strings.TrimSpace(line))
41+
break
42+
}
43+
}
44+
}
45+
return hits
46+
}
47+
48+
// TestRuntimeSourceIsTransportNeutral enforces the manifest-bundle boundary
49+
// on this plugin's runtime source: it must not integrate with Git
50+
// repositories, GitHub/pull requests, Argo CD/Flux reconcilers, kubeconfig,
51+
// or own reconciliation objects (repoURL, targetRevision, Application,
52+
// AppProject). Test files are excluded — this guard itself names the
53+
// forbidden concepts.
54+
func TestRuntimeSourceIsTransportNeutral(t *testing.T) {
55+
entries, err := os.ReadDir(".")
56+
if err != nil {
57+
t.Fatalf("read package dir: %v", err)
58+
}
59+
for _, e := range entries {
60+
name := e.Name()
61+
if e.IsDir() || !strings.HasSuffix(name, ".go") || strings.HasSuffix(name, "_test.go") {
62+
continue
63+
}
64+
src, err := os.ReadFile(name)
65+
if err != nil {
66+
t.Fatalf("read %s: %v", name, err)
67+
}
68+
if hits := scanTransportOwnership(name, string(src)); hits != nil {
69+
t.Errorf("runtime source names a transport/reconciler concept:\n %s", strings.Join(hits, "\n "))
70+
}
71+
}
72+
}
73+
74+
// TestOwnedManifestsAreTransportNeutral enforces the same boundary on the
75+
// plugin-owned deployment templates: they carry only workload/resources,
76+
// never reconciliation control-plane objects (Argo Application/AppProject)
77+
// or repository source bindings (repoURL, targetRevision).
78+
func TestOwnedManifestsAreTransportNeutral(t *testing.T) {
79+
err := fs.WalkDir(deploymentFS, ".", func(path string, d fs.DirEntry, err error) error {
80+
if err != nil {
81+
return err
82+
}
83+
if d.IsDir() {
84+
return nil
85+
}
86+
content, err := fs.ReadFile(deploymentFS, path)
87+
if err != nil {
88+
return err
89+
}
90+
if hits := scanTransportOwnership(path, string(content)); hits != nil {
91+
t.Errorf("owned manifest names a transport/reconciler concept:\n %s", strings.Join(hits, "\n "))
92+
}
93+
return nil
94+
})
95+
if err != nil {
96+
t.Fatalf("walk deployment templates: %v", err)
97+
}
98+
}

0 commit comments

Comments
 (0)