Merge pull request 'fix: merge all bootstrap migrations' (#38) from fix/bootstrap-migration-repositories into main

Reviewed-on: #38
This commit is contained in:
eding 2026-09-09 21:23:49 +02:00
commit 0cf8fa7557
4 changed files with 40 additions and 24 deletions

View file

@ -121,9 +121,17 @@ func runBootstrap(cmd *cobra.Command, args []string) error {
return err return err
} }
manager := forgejo.NewRepoManager(cfg.Git.BaseURL, cfg.Git.Token, cfg.Git.Owner, cfg.Git.Username, "", "", cfg.Flux.Branch, "") manager := forgejo.NewRepoManager(cfg.Git.BaseURL, cfg.Git.Token, cfg.Git.Owner, cfg.Git.Username, "", "", cfg.Flux.Branch, "")
if err := manager.MergePullRequest(cfg.Flux.RepoName, "maidn/bootstrap-"+cfg.ClusterID); err != nil { for _, repository := range []string{cfg.Flux.ManifestsRepo, cfg.Flux.RepoName} {
open, err := manager.HasOpenPullRequest(repository, "maidn/bootstrap-"+cfg.ClusterID)
if err != nil {
return err return err
} }
if open {
if err := manager.MergePullRequest(repository, "maidn/bootstrap-"+cfg.ClusterID); err != nil {
return err
}
}
}
} }
if bootstrapConfigPath != "" { if bootstrapConfigPath != "" {
if bootstrapPromptDemocraticCSI || bootstrapPromptOperationalSecrets || bootstrapInitializeOpenBaoRecovery || bootstrapManageNetworkBridges { if bootstrapPromptDemocraticCSI || bootstrapPromptOperationalSecrets || bootstrapInitializeOpenBaoRecovery || bootstrapManageNetworkBridges {

View file

@ -343,14 +343,16 @@ func (r Runner) Run() error {
} }
func (r Runner) reconcileBootstrapMigration(manager *forgejo.RepoManager) error { func (r Runner) reconcileBootstrapMigration(manager *forgejo.RepoManager) error {
if !manager.MigrationPending { if len(manager.MigrationRepositories) == 0 {
return nil return nil
} }
if !r.AutoMergeBootstrapMigration { if !r.AutoMergeBootstrapMigration {
return errors.New("existing repository migration PR created; merge and rerun bootstrap before infrastructure changes") return fmt.Errorf("repository migration PRs created for %s; merge and rerun bootstrap before infrastructure changes", strings.Join(manager.MigrationRepositories, ", "))
}
for _, repository := range manager.MigrationRepositories {
if err := manager.MergePullRequest(repository, manager.MigrationBranch); err != nil {
return fmt.Errorf("merge bootstrap migration PR for %s: %w", repository, err)
} }
if err := manager.MergePullRequest(r.Config.Flux.RepoName, manager.MigrationBranch); err != nil {
return fmt.Errorf("merge bootstrap migration PR: %w", err)
} }
return nil return nil
} }

View file

@ -908,15 +908,16 @@ func TestRunnerEnableDeliveryAppliesDefaults(t *testing.T) {
func TestRunnerAutoMergesBootstrapMigration(t *testing.T) { func TestRunnerAutoMergesBootstrapMigration(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) {
switch request.Method + " " + request.URL.Path { if request.Method == http.MethodGet && (request.URL.Path == "/api/v1/repos/test-org/manifests/pulls" || request.URL.Path == "/api/v1/repos/test-org/cluster/pulls") {
case http.MethodGet + " /api/v1/repos/test-org/cluster/pulls":
if request.URL.Query().Get("state") != "open" || request.URL.Query().Get("head") != "maidn/bootstrap-test-cluster" { if request.URL.Query().Get("state") != "open" || request.URL.Query().Get("head") != "maidn/bootstrap-test-cluster" {
t.Fatalf("unexpected migration lookup query: %q", request.URL.RawQuery) t.Fatalf("unexpected migration lookup query: %q", request.URL.RawQuery)
} }
_ = json.NewEncoder(writer).Encode([]struct { _ = json.NewEncoder(writer).Encode([]struct {
Number int `json:"number"` Number int `json:"number"`
}{{Number: 4}}) }{{Number: 4}})
case http.MethodPost + " /api/v1/repos/test-org/cluster/pulls/4/merge": return
}
if request.Method == http.MethodPost && (request.URL.Path == "/api/v1/repos/test-org/manifests/pulls/4/merge" || request.URL.Path == "/api/v1/repos/test-org/cluster/pulls/4/merge") {
var body struct { var body struct {
Do string `json:"Do"` Do string `json:"Do"`
} }
@ -924,15 +925,15 @@ func TestRunnerAutoMergesBootstrapMigration(t *testing.T) {
t.Fatalf("unexpected migration merge request: %#v, %v", body, err) t.Fatalf("unexpected migration merge request: %#v, %v", body, err)
} }
writer.WriteHeader(http.StatusOK) writer.WriteHeader(http.StatusOK)
default: return
t.Fatalf("unexpected Forgejo request %s %s", request.Method, request.URL.Path)
} }
t.Fatalf("unexpected Forgejo request %s %s", request.Method, request.URL.Path)
})) }))
defer server.Close() defer server.Close()
manager := forgejo.NewRepoManager(server.URL, "test-token", "test-org", "bot", "manifests", "cluster", "main", "maidn/bootstrap-test-cluster") manager := forgejo.NewRepoManager(server.URL, "test-token", "test-org", "bot", "manifests", "cluster", "main", "maidn/bootstrap-test-cluster")
manager.HTTPClient = server.Client() manager.HTTPClient = server.Client()
manager.MigrationPending = true manager.MigrationRepositories = []string{"manifests", "cluster"}
if err := (Runner{Config: config.Config{Flux: config.FluxConfig{RepoName: "cluster"}}, AutoMergeBootstrapMigration: true}).reconcileBootstrapMigration(manager); err != nil { if err := (Runner{Config: config.Config{Flux: config.FluxConfig{RepoName: "cluster"}}, AutoMergeBootstrapMigration: true}).reconcileBootstrapMigration(manager); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -946,7 +947,7 @@ func TestRunnerRetainsMigrationApprovalGate(t *testing.T) {
manager := forgejo.NewRepoManager(server.URL, "test-token", "test-org", "bot", "manifests", "cluster", "main", "maidn/bootstrap-test-cluster") manager := forgejo.NewRepoManager(server.URL, "test-token", "test-org", "bot", "manifests", "cluster", "main", "maidn/bootstrap-test-cluster")
manager.HTTPClient = server.Client() manager.HTTPClient = server.Client()
manager.MigrationPending = true manager.MigrationRepositories = []string{"manifests"}
if err := (Runner{Config: config.Config{Flux: config.FluxConfig{RepoName: "cluster"}}}).reconcileBootstrapMigration(manager); err == nil || !strings.Contains(err.Error(), "merge and rerun bootstrap") { if err := (Runner{Config: config.Config{Flux: config.FluxConfig{RepoName: "cluster"}}}).reconcileBootstrapMigration(manager); err == nil || !strings.Contains(err.Error(), "merge and rerun bootstrap") {
t.Fatalf("normal bootstrap migration gate = %v", err) t.Fatalf("normal bootstrap migration gate = %v", err)
} }

View file

@ -24,7 +24,7 @@ type RepoManager struct {
FluxRepoName string FluxRepoName string
Branch string Branch string
MigrationBranch string MigrationBranch string
MigrationPending bool MigrationRepositories []string
HTTPClient *http.Client HTTPClient *http.Client
} }
@ -379,7 +379,12 @@ func (rm *RepoManager) setupRepository(repoURL, repoName string, existing bool,
if err != nil || !changed || !existing { if err != nil || !changed || !existing {
return err return err
} }
rm.MigrationPending = true for _, repository := range rm.MigrationRepositories {
if repository == repoName {
return rm.createMigrationPullRequest(repoName, targetBranch)
}
}
rm.MigrationRepositories = append(rm.MigrationRepositories, repoName)
return rm.createMigrationPullRequest(repoName, targetBranch) return rm.createMigrationPullRequest(repoName, targetBranch)
} }