Compare commits
No commits in common. "8684ed942725d48de9062cbdc565fcfc3bd3412d" and "7df7d03dbe55cb0d8f16dc253f2f821b5a18ce71" have entirely different histories.
8684ed9427
...
7df7d03dbe
|
|
@ -13,23 +13,7 @@ import (
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type onboardingRepoManager interface {
|
// OnboardApp imports one clean checkout into the configured Forgejo owner,
|
||||||
EnsureRepository(string, string) (bool, error)
|
|
||||||
RemoteBranchRevision(string, string) (string, error)
|
|
||||||
PushRef(string, string, string, string) error
|
|
||||||
EnsureProtectedBranch(string, string) error
|
|
||||||
PublishDeliveryBranch(string, string, string, string, func(string) error) (bool, error)
|
|
||||||
EnsurePullRequest(string, string, string, string) error
|
|
||||||
PublishRepositoryPullRequest(string, string, string, string, func(string) error) (bool, error)
|
|
||||||
EnsureWebhook(string, string, string) error
|
|
||||||
TriggerWebhookTest(string, string, string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
var newOnboardingRepoManager = func(baseURL, token, owner, username, manifestsRepo, fluxRepo, branch, migrationBranch string) onboardingRepoManager {
|
|
||||||
return forgejo.NewRepoManager(baseURL, token, owner, username, manifestsRepo, fluxRepo, branch, migrationBranch)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OnboardApp imports one clean checkout into its source Forgejo owner,
|
|
||||||
// publishes its delivery branch, registers it with Flux, then adds its webhook.
|
// publishes its delivery branch, registers it with Flux, then adds its webhook.
|
||||||
func OnboardApp(cfg config.Config, sourceDir string) error {
|
func OnboardApp(cfg config.Config, sourceDir string) error {
|
||||||
resolved, err := config.ResolveAppOnboarding(cfg)
|
resolved, err := config.ResolveAppOnboarding(cfg)
|
||||||
|
|
@ -50,21 +34,24 @@ func OnboardApp(cfg config.Config, sourceDir string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if owner != resolved.Git.Owner {
|
||||||
|
return errors.New("delivery appRepoUrl owner must match git owner for app onboarding")
|
||||||
|
}
|
||||||
deliveryBranch, err := forgejo.DeliveryBranch(resolved.Delivery.AppName, resolved.Delivery.AppRepoRef)
|
deliveryBranch, err := forgejo.DeliveryBranch(resolved.Delivery.AppName, resolved.Delivery.AppRepoRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sourceManager := newOnboardingRepoManager(resolved.Git.BaseURL, resolved.Git.Token, owner, resolved.Git.Username, "", "", resolved.Delivery.AppRepoRef, "")
|
manager := forgejo.NewRepoManager(resolved.Git.BaseURL, resolved.Git.Token, resolved.Git.Owner, resolved.Git.Username, "", "", resolved.Delivery.AppRepoRef, "")
|
||||||
if _, err := sourceManager.EnsureRepository(repository, "Application source for Maidn CI/CD delivery"); err != nil {
|
if _, err := manager.EnsureRepository(repository, "Application source for Maidn CI/CD delivery"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := publishInitialAppBranches(sourceManager, sourceDir, resolved.Delivery.AppRepoURL, sourceBranch, resolved.Delivery.AppRepoRef, resolved.Delivery.ProductionBranch); err != nil {
|
if err := publishInitialAppBranches(manager, sourceDir, resolved.Delivery.AppRepoURL, sourceBranch, resolved.Delivery.AppRepoRef, resolved.Delivery.ProductionBranch); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := sourceManager.EnsureProtectedBranch(repository, resolved.Delivery.ProductionBranch); err != nil {
|
if err := manager.EnsureProtectedBranch(repository, resolved.Delivery.ProductionBranch); err != nil {
|
||||||
return fmt.Errorf("protect Forgejo production branch: %w", err)
|
return fmt.Errorf("protect Forgejo production branch: %w", err)
|
||||||
}
|
}
|
||||||
changed, err := sourceManager.PublishDeliveryBranch(sourceDir, sourceBranch, resolved.Delivery.AppRepoURL, deliveryBranch, func(dir string) error {
|
changed, err := manager.PublishDeliveryBranch(sourceDir, sourceBranch, resolved.Delivery.AppRepoURL, deliveryBranch, func(dir string) error {
|
||||||
if err := GenerateAppDelivery(dir, resolved); err != nil {
|
if err := GenerateAppDelivery(dir, resolved); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -74,19 +61,25 @@ func OnboardApp(cfg config.Config, sourceDir string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if changed {
|
if changed {
|
||||||
if err := sourceManager.EnsurePullRequest(repository, "feat: migrate delivery to Tekton", deliveryBranch, resolved.Delivery.AppRepoRef); err != nil {
|
if err := manager.EnsurePullRequest(repository, "feat: migrate delivery to Tekton", deliveryBranch, resolved.Delivery.AppRepoRef); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if open, err := manager.HasOpenPullRequest(repository, deliveryBranch); err != nil {
|
||||||
|
return err
|
||||||
|
} else if open {
|
||||||
|
if err := manager.MergePullRequest(repository, deliveryBranch); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registrationBranch := "maidn/register-" + resolved.Delivery.AppName
|
registrationBranch := "maidn/register-" + resolved.Delivery.AppName
|
||||||
clusterManager := newOnboardingRepoManager(resolved.Git.BaseURL, resolved.Git.Token, resolved.Git.Owner, resolved.Git.Username, "", "", resolved.Flux.Branch, "")
|
if _, err := manager.PublishRepositoryPullRequest(resolved.Flux.RepoName, "feat: register "+resolved.Delivery.AppName+" delivery", registrationBranch, resolved.Flux.Branch, func(dir string) error {
|
||||||
if _, err := clusterManager.PublishRepositoryPullRequest(resolved.Flux.RepoName, "feat: register "+resolved.Delivery.AppName+" delivery", registrationBranch, resolved.Flux.Branch, func(dir string) error {
|
|
||||||
return RegisterAppInCluster(dir, resolved)
|
return RegisterAppInCluster(dir, resolved)
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return fmt.Errorf("register app in cluster repository: %w", err)
|
return fmt.Errorf("register app in cluster repository: %w", err)
|
||||||
}
|
}
|
||||||
secrets, err := readOperationalSecrets(resolved.SOPS.OperationalSecretsPath, resolved.SOPS.AgeKeyPath)
|
secrets, err := ReadOperationalSecrets(resolved.SOPS.OperationalSecretsPath, resolved.SOPS.AgeKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("read encrypted webhook authorization: %w", err)
|
return fmt.Errorf("read encrypted webhook authorization: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -99,17 +92,17 @@ func OnboardApp(cfg config.Config, sourceDir string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
webhookURL := "https://tekton." + resolved.Flux.ClusterDomain + "/"
|
webhookURL := "https://tekton." + resolved.Flux.ClusterDomain + "/"
|
||||||
if err := sourceManager.EnsureWebhook(repository, webhookURL, authorization); err != nil {
|
if err := manager.EnsureWebhook(repository, webhookURL, authorization); err != nil {
|
||||||
return fmt.Errorf("register Forgejo webhook: %w", err)
|
return fmt.Errorf("register Forgejo webhook: %w", err)
|
||||||
}
|
}
|
||||||
if err := sourceManager.TriggerWebhookTest(repository, webhookURL, resolved.Delivery.AppRepoRef); err != nil {
|
if err := manager.TriggerWebhookTest(repository, webhookURL, resolved.Delivery.AppRepoRef); err != nil {
|
||||||
return fmt.Errorf("trigger Forgejo webhook test: %w", err)
|
return fmt.Errorf("trigger Forgejo webhook test: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// publishInitialAppBranches establishes the immutable source baseline before delivery setup.
|
// publishInitialAppBranches establishes the immutable source baseline before delivery setup.
|
||||||
func publishInitialAppBranches(manager onboardingRepoManager, sourceDir, targetURL, sourceBranch, targetBranch, productionBranch string) error {
|
func publishInitialAppBranches(manager *forgejo.RepoManager, sourceDir, targetURL, sourceBranch, targetBranch, productionBranch string) error {
|
||||||
sourceRevision, err := forgejo.BranchRevision(sourceDir, sourceBranch)
|
sourceRevision, err := forgejo.BranchRevision(sourceDir, sourceBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -338,21 +331,7 @@ spec:
|
||||||
if err := os.MkdirAll(maidnDir, 0755); err != nil {
|
if err := os.MkdirAll(maidnDir, 0755); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
kustomization := filepath.Join(maidnDir, "kustomization.yaml")
|
if err := os.WriteFile(filepath.Join(maidnDir, "kustomization.yaml"), []byte("apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nresources:\n - secret-access.yaml\n"), 0644); err != nil {
|
||||||
content := []byte("apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nresources:\n - secret-access.yaml\n")
|
|
||||||
if _, err := os.Lstat(kustomization); err == nil {
|
|
||||||
content, err = readRegularFile(kustomization)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
content, err = addKustomizationResource(content, "secret-access.yaml")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else if !os.IsNotExist(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := os.WriteFile(kustomization, content, 0644); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return os.WriteFile(filepath.Join(maidnDir, "secret-access.yaml"), []byte(manifests), 0644)
|
return os.WriteFile(filepath.Join(maidnDir, "secret-access.yaml"), []byte(manifests), 0644)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package bootstrap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
@ -116,12 +115,6 @@ func TestGenerateAppSecretAccessRendersOnlyDeclaredRuntimeSecrets(t *testing.T)
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
cfg := onboardingConfig()
|
cfg := onboardingConfig()
|
||||||
cfg.SecretGrants = []config.SecretGrant{{Application: "web-ui", Consumer: "runtime", Environment: "staging", Secrets: []string{"api-key"}, Shared: []string{"payments"}}}
|
cfg.SecretGrants = []config.SecretGrant{{Application: "web-ui", Consumer: "runtime", Environment: "staging", Secrets: []string{"api-key"}, Shared: []string{"payments"}}}
|
||||||
if err := os.Mkdir(filepath.Join(dir, ".maidn"), 0755); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := os.WriteFile(filepath.Join(dir, ".maidn", "kustomization.yaml"), []byte("apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nresources:\n - database.yaml\n"), 0644); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := GenerateAppSecretAccess(dir, cfg); err != nil {
|
if err := GenerateAppSecretAccess(dir, cfg); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -129,10 +122,6 @@ func TestGenerateAppSecretAccessRendersOnlyDeclaredRuntimeSecrets(t *testing.T)
|
||||||
if err != nil || !strings.Contains(string(access), "namespace: staging") || !strings.Contains(string(access), "key: apps/web-ui/api-key") || strings.Contains(string(access), "shared/payments") {
|
if err != nil || !strings.Contains(string(access), "namespace: staging") || !strings.Contains(string(access), "key: apps/web-ui/api-key") || strings.Contains(string(access), "shared/payments") {
|
||||||
t.Fatalf("secret access = %q, %v", access, err)
|
t.Fatalf("secret access = %q, %v", access, err)
|
||||||
}
|
}
|
||||||
kustomization, err := os.ReadFile(filepath.Join(dir, ".maidn", "kustomization.yaml"))
|
|
||||||
if err != nil || !strings.Contains(string(kustomization), "database.yaml") || !strings.Contains(string(kustomization), "secret-access.yaml") {
|
|
||||||
t.Fatalf("secret Kustomization = %q, %v", kustomization, err)
|
|
||||||
}
|
|
||||||
registration, err := renderAppRegistration(cfg)
|
registration, err := renderAppRegistration(cfg)
|
||||||
if err != nil || !strings.Contains(string(registration), "name: web-ui-secrets") || !strings.Contains(string(registration), "path: ./.maidn") {
|
if err != nil || !strings.Contains(string(registration), "name: web-ui-secrets") || !strings.Contains(string(registration), "path: ./.maidn") {
|
||||||
t.Fatalf("secret registration = %q, %v", registration, err)
|
t.Fatalf("secret registration = %q, %v", registration, err)
|
||||||
|
|
@ -201,125 +190,3 @@ func TestPublishInitialAppBranchesCreatesAndPreservesProduction(t *testing.T) {
|
||||||
t.Fatalf("main = %s, want existing %s", got, sourceRevision)
|
t.Fatalf("main = %s, want existing %s", got, sourceRevision)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type onboardingManagerFake struct {
|
|
||||||
owner string
|
|
||||||
calls []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *onboardingManagerFake) EnsureRepository(repo, _ string) (bool, error) {
|
|
||||||
m.calls = append(m.calls, "ensure "+m.owner+"/"+repo)
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *onboardingManagerFake) RemoteBranchRevision(targetURL, branch string) (string, error) {
|
|
||||||
m.calls = append(m.calls, "remote "+targetURL+":"+branch)
|
|
||||||
return "existing", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *onboardingManagerFake) PushRef(_, targetURL, _, targetBranch string) error {
|
|
||||||
m.calls = append(m.calls, "push "+targetURL+":"+targetBranch)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *onboardingManagerFake) EnsureProtectedBranch(repo, branch string) error {
|
|
||||||
m.calls = append(m.calls, "protect "+m.owner+"/"+repo+":"+branch)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *onboardingManagerFake) PublishDeliveryBranch(_, _, targetURL, branch string, _ func(string) error) (bool, error) {
|
|
||||||
m.calls = append(m.calls, "delivery "+targetURL+":"+branch)
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *onboardingManagerFake) EnsurePullRequest(repo, _, branch, _ string) error {
|
|
||||||
m.calls = append(m.calls, "ensure-pr "+m.owner+"/"+repo+":"+branch)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *onboardingManagerFake) HasOpenPullRequest(repo, branch string) (bool, error) {
|
|
||||||
m.calls = append(m.calls, "open-pr "+m.owner+"/"+repo+":"+branch)
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *onboardingManagerFake) MergePullRequest(repo, branch string) error {
|
|
||||||
m.calls = append(m.calls, "merge-pr "+m.owner+"/"+repo+":"+branch)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *onboardingManagerFake) PublishRepositoryPullRequest(repo, _, branch, _ string, _ func(string) error) (bool, error) {
|
|
||||||
m.calls = append(m.calls, "register "+m.owner+"/"+repo+":"+branch)
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *onboardingManagerFake) EnsureWebhook(repo, _, _ string) error {
|
|
||||||
m.calls = append(m.calls, "webhook "+m.owner+"/"+repo)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *onboardingManagerFake) TriggerWebhookTest(repo, _, branch string) error {
|
|
||||||
m.calls = append(m.calls, "webhook-test "+m.owner+"/"+repo+":"+branch)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOnboardAppUsesCanonicalSourceAndExecutionClusterManagers(t *testing.T) {
|
|
||||||
source := filepath.Join(t.TempDir(), "source")
|
|
||||||
if err := os.Mkdir(source, 0755); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
onboardingGit(t, source, "init", "-b", "main")
|
|
||||||
onboardingGit(t, source, "config", "user.name", "Test")
|
|
||||||
onboardingGit(t, source, "config", "user.email", "test@example.test")
|
|
||||||
if err := os.WriteFile(filepath.Join(source, "README.md"), []byte("source\n"), 0644); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
onboardingGit(t, source, "add", "README.md")
|
|
||||||
onboardingGit(t, source, "commit", "-m", "source")
|
|
||||||
|
|
||||||
cfg := onboardingConfig()
|
|
||||||
cfg.Git.Username, cfg.Git.Token = "bot", "test-token"
|
|
||||||
cfg.Delivery.AppRepoURL = "https://git.example.test/Maidn/maidn-e2e-web.git"
|
|
||||||
sourceManager := &onboardingManagerFake{owner: "Maidn"}
|
|
||||||
clusterManager := &onboardingManagerFake{owner: cfg.Git.Owner}
|
|
||||||
originalManager, originalSecrets := newOnboardingRepoManager, readOperationalSecrets
|
|
||||||
t.Cleanup(func() {
|
|
||||||
newOnboardingRepoManager, readOperationalSecrets = originalManager, originalSecrets
|
|
||||||
})
|
|
||||||
newOnboardingRepoManager = func(_, _, owner, _, _, _, _, _ string) onboardingRepoManager {
|
|
||||||
switch owner {
|
|
||||||
case "Maidn":
|
|
||||||
return sourceManager
|
|
||||||
case cfg.Git.Owner:
|
|
||||||
return clusterManager
|
|
||||||
default:
|
|
||||||
t.Fatalf("unexpected onboarding manager owner %q", owner)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
readOperationalSecrets = func(string, string) (map[string]map[string]string, error) {
|
|
||||||
return nil, errors.New("stop after registration")
|
|
||||||
}
|
|
||||||
|
|
||||||
err := OnboardApp(cfg, source)
|
|
||||||
if err == nil || !strings.Contains(err.Error(), "read encrypted webhook authorization") {
|
|
||||||
t.Fatalf("OnboardApp() = %v", err)
|
|
||||||
}
|
|
||||||
sourceCalls := strings.Join(sourceManager.calls, "\n")
|
|
||||||
for _, want := range []string{
|
|
||||||
"ensure Maidn/maidn-e2e-web",
|
|
||||||
"remote https://git.example.test/Maidn/maidn-e2e-web.git:main",
|
|
||||||
"remote https://git.example.test/Maidn/maidn-e2e-web.git:production",
|
|
||||||
"protect Maidn/maidn-e2e-web:production",
|
|
||||||
"delivery https://git.example.test/Maidn/maidn-e2e-web.git:maidn/delivery-web-ui",
|
|
||||||
} {
|
|
||||||
if !strings.Contains(sourceCalls, want) {
|
|
||||||
t.Fatalf("source manager calls = %q, missing %q", sourceCalls, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if strings.Contains(sourceCalls, "merge-pr") {
|
|
||||||
t.Fatalf("source delivery PR was merged without review: %q", sourceCalls)
|
|
||||||
}
|
|
||||||
if got := strings.Join(clusterManager.calls, "\n"); got != "register test-org-2/cluster:maidn/register-web-ui" {
|
|
||||||
t.Fatalf("cluster manager calls = %q", got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -164,12 +164,12 @@ func ResolveAppOnboarding(cfg Config) (Config, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cfg, err
|
return cfg, err
|
||||||
}
|
}
|
||||||
owner, repository, err := deliveryRepositoryOwner(resolved.Delivery.AppRepoURL)
|
owner, _, err := deliveryRepositoryOwner(resolved.Delivery.AppRepoURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cfg, err
|
return cfg, err
|
||||||
}
|
}
|
||||||
if owner != resolved.Git.Owner && (owner != "Maidn" || !strings.HasPrefix(repository, "maidn-e2e-")) {
|
if owner != resolved.Git.Owner {
|
||||||
return cfg, errors.New("delivery appRepoUrl owner must match git owner or identify a canonical Maidn E2E fixture")
|
return cfg, errors.New("delivery appRepoUrl owner must match git owner for app onboarding")
|
||||||
}
|
}
|
||||||
if resolved.Delivery.ProductionBranch != "production" {
|
if resolved.Delivery.ProductionBranch != "production" {
|
||||||
return cfg, errors.New("delivery productionBranch must be literal production for app onboarding")
|
return cfg, errors.New("delivery productionBranch must be literal production for app onboarding")
|
||||||
|
|
|
||||||
|
|
@ -99,26 +99,16 @@ func TestValidateDeliveryRejectsUnsafeTektonDashboardURL(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestResolveAppOnboardingAllowsOnlyCanonicalCrossOwnerSource(t *testing.T) {
|
func TestResolveAppOnboardingRequiresTargetOwner(t *testing.T) {
|
||||||
cfg := validConfig(t)
|
cfg := validConfig(t)
|
||||||
cfg.Git.Owner = "test-org-2"
|
cfg.Git.Owner = "test-org-2"
|
||||||
cfg.Delivery.AppRepoURL = "https://git.example.test/Maidn/maidn-e2e-web.git"
|
if _, err := ResolveAppOnboarding(cfg); err == nil || !strings.Contains(err.Error(), "owner must match") {
|
||||||
if _, err := ResolveAppOnboarding(cfg); err != nil {
|
t.Fatalf("ResolveAppOnboarding() accepted a source-owner target: %v", err)
|
||||||
t.Fatalf("ResolveAppOnboarding() rejected canonical source: %v", err)
|
|
||||||
}
|
}
|
||||||
cfg.Delivery.AppRepoURL = "https://git.example.test/test-org-2/web-ui.git"
|
cfg.Delivery.AppRepoURL = "https://git.example.test/test-org-2/web-ui.git"
|
||||||
if resolved, err := ResolveAppOnboarding(cfg); err != nil || resolved.Delivery.WebhookURL() != "https://tekton.example.test/" {
|
if resolved, err := ResolveAppOnboarding(cfg); err != nil || resolved.Delivery.WebhookURL() != "https://tekton.example.test/" {
|
||||||
t.Fatalf("ResolveAppOnboarding() = %#v, %v", resolved.Delivery, err)
|
t.Fatalf("ResolveAppOnboarding() = %#v, %v", resolved.Delivery, err)
|
||||||
}
|
}
|
||||||
for _, appRepoURL := range []string{
|
|
||||||
"https://git.example.test/Maidn/web-ui.git",
|
|
||||||
"https://git.example.test/other-org/maidn-e2e-web.git",
|
|
||||||
} {
|
|
||||||
cfg.Delivery.AppRepoURL = appRepoURL
|
|
||||||
if _, err := ResolveAppOnboarding(cfg); err == nil || !strings.Contains(err.Error(), "canonical Maidn E2E fixture") {
|
|
||||||
t.Fatalf("ResolveAppOnboarding() accepted noncanonical cross-owner source %q: %v", appRepoURL, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestResolveAppOnboardingRequiresProductionBranch(t *testing.T) {
|
func TestResolveAppOnboardingRequiresProductionBranch(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -317,28 +317,6 @@ func TestEnsureProtectedBranchCreatesDirectPushProtection(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEnsureProtectedBranchUsesCanonicalSourceOwnerPath(t *testing.T) {
|
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
|
||||||
if request.URL.Path != "/api/v1/repos/Maidn/maidn-e2e-web/branch_protections" {
|
|
||||||
t.Fatalf("canonical source mutation targeted %q", request.URL.Path)
|
|
||||||
}
|
|
||||||
switch request.Method {
|
|
||||||
case http.MethodGet:
|
|
||||||
_ = json.NewEncoder(writer).Encode([]branchProtection{})
|
|
||||||
case http.MethodPost:
|
|
||||||
writer.WriteHeader(http.StatusCreated)
|
|
||||||
default:
|
|
||||||
t.Fatalf("unexpected method %q", request.Method)
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
defer server.Close()
|
|
||||||
manager := NewRepoManager(server.URL, "token", "Maidn", "user", "", "", "main", "")
|
|
||||||
manager.HTTPClient = server.Client()
|
|
||||||
if err := manager.EnsureProtectedBranch("maidn-e2e-web", "production"); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEnsureProtectedBranchRejectsExistingDirectPushRule(t *testing.T) {
|
func TestEnsureProtectedBranchRejectsExistingDirectPushRule(t *testing.T) {
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
||||||
if request.Method != http.MethodGet {
|
if request.Method != http.MethodGet {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue