From d48547229a330b9ecdfbc501615f60652d560f74 Mon Sep 17 00:00:00 2001 From: eding Date: Mon, 31 Aug 2026 18:40:56 +0200 Subject: [PATCH] feat: regenerate app delivery source --- internal/bootstrap/bootstrap.go | 57 +++++++++++++++++++++++++++- internal/bootstrap/bootstrap_test.go | 23 +++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/internal/bootstrap/bootstrap.go b/internal/bootstrap/bootstrap.go index f77b374..4ba0cae 100644 --- a/internal/bootstrap/bootstrap.go +++ b/internal/bootstrap/bootstrap.go @@ -437,7 +437,11 @@ func copyAndRenderDeliveryBases(templateDir, repoDir string, cfg config.Config) return err } } - return writePreviewDeliveryConfig(filepath.Join(repoDir, "base", "tekton"), cfg) + dir := filepath.Join(repoDir, "base", "tekton") + if err := writePreviewDeliveryConfig(dir, cfg); err != nil { + return err + } + return writeAppDeliverySource(dir, cfg) } func writePreviewDeliveryConfig(dir string, cfg config.Config) error { @@ -481,6 +485,57 @@ func writePreviewDeliveryConfig(dir string, cfg config.Config) error { return os.WriteFile(path, append(data, []byte(" - maidn-preview-delivery-config.yaml\n")...), 0644) } +func writeAppDeliverySource(dir string, cfg config.Config) error { + if err := config.ValidateDelivery(cfg); err != nil { + return err + } + name := cfg.Delivery.AppName + filename := name + "-source.yaml" + content := fmt.Sprintf(`apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: %s + namespace: flux-system +spec: + interval: 5m + url: %s + ref: + branch: %s + secretRef: + name: forgejo-flux-credentials +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: %s-delivery + namespace: flux-system +spec: + dependsOn: + - name: tekton-catalog + interval: 5m + path: ./.tekton + prune: true + sourceRef: + kind: GitRepository + name: %s +`, name, cfg.Delivery.AppRepoURL, cfg.Delivery.AppRepoRef, name, name) + if err := os.WriteFile(filepath.Join(dir, filename), []byte(content), 0644); err != nil { + return err + } + path := filepath.Join(dir, "kustomization.yaml") + data, err := os.ReadFile(path) + if err != nil { + return err + } + if !strings.Contains("\n"+string(data), "\nresources:") { + return errors.New("Tekton Kustomization must define resources before adding app delivery source") + } + if strings.Contains(string(data), filename) { + return nil + } + return os.WriteFile(path, append(data, []byte(" - "+filename+"\n")...), 0644) +} + func canonicalForgejoOrigin(value string) (string, error) { parsed, err := url.Parse(value) if err != nil || parsed.Scheme != "https" || parsed.Host == "" || parsed.User != nil || parsed.RawPath != "" || parsed.RawQuery != "" || parsed.Fragment != "" || strings.Trim(parsed.Path, "/") != "" { diff --git a/internal/bootstrap/bootstrap_test.go b/internal/bootstrap/bootstrap_test.go index 7aa60eb..b0e315d 100644 --- a/internal/bootstrap/bootstrap_test.go +++ b/internal/bootstrap/bootstrap_test.go @@ -69,6 +69,29 @@ func TestRenderDeliveryConfig(t *testing.T) { } } +func TestWriteAppDeliverySource(t *testing.T) { + dir := t.TempDir() + if err := os.WriteFile(filepath.Join(dir, "kustomization.yaml"), []byte("resources:\n"), 0644); err != nil { + t.Fatal(err) + } + cfg := config.Config{ + Git: config.GitConfig{BaseURL: "https://git.example.test", Owner: "apps"}, + Flux: config.FluxConfig{Branch: "main", ManifestsRepo: "manifests"}, + Delivery: config.DeliveryConfig{AppName: "web-ui", AppRepoURL: "https://git.example.test/apps/web-ui.git", AppRepoRef: "main", ProductionBranch: "production", ImageRepository: "registry.example.test/apps/web-ui", BuildOutputDirectory: "dist", BuildConfiguration: "production", WebhookHostname: "tekton.example.test", WebhookPath: "/"}, + } + if err := writeAppDeliverySource(dir, cfg); err != nil { + t.Fatal(err) + } + content, err := os.ReadFile(filepath.Join(dir, "web-ui-source.yaml")) + if err != nil || !strings.Contains(string(content), "name: web-ui-delivery") || strings.Contains(string(content), "token") { + t.Fatalf("app delivery source = %q, %v", content, err) + } + kustomization, err := os.ReadFile(filepath.Join(dir, "kustomization.yaml")) + if err != nil || !strings.Contains(string(kustomization), "web-ui-source.yaml") { + t.Fatalf("Tekton Kustomization = %q, %v", kustomization, err) + } +} + func TestGeneratedDeliveryIsGenericAndUsesSafePreviewCleanupContract(t *testing.T) { cfg := config.Config{ Git: config.GitConfig{BaseURL: "https://git.example.test", Owner: "platform"},