diff --git a/Makefile b/Makefile index d5be4af9b..22c2e77d3 100644 --- a/Makefile +++ b/Makefile @@ -211,7 +211,7 @@ release_apple: lib_ios update_apple_version release_ios release_macos release_tv release_apple_beta: update_apple_version release_ios release_macos release_tvos publish_testflight: - go run -v ./cmd/internal/app_store_connect publish_testflight + go run -v ./cmd/internal/app_store_connect publish_testflight $(filter-out $@,$(MAKECMDGOALS)) prepare_app_store: go run -v ./cmd/internal/app_store_connect prepare_app_store @@ -269,3 +269,6 @@ update: git fetch git reset FETCH_HEAD --hard git clean -fdx + +%: + @: diff --git a/cmd/internal/app_store_connect/main.go b/cmd/internal/app_store_connect/main.go index 1e7109b63..97919521f 100644 --- a/cmd/internal/app_store_connect/main.go +++ b/cmd/internal/app_store_connect/main.go @@ -100,11 +100,32 @@ findVersion: } func publishTestflight(ctx context.Context) error { + if len(os.Args) < 3 { + return E.New("platform required: ios, macos, or tvos") + } + var platform asc.Platform + switch os.Args[2] { + case "ios": + platform = asc.PlatformIOS + case "macos": + platform = asc.PlatformMACOS + case "tvos": + platform = asc.PlatformTVOS + default: + return E.New("unknown platform: ", os.Args[2]) + } + tagVersion, err := build_shared.ReadTagVersion() if err != nil { return err } tag := tagVersion.VersionString() + + releaseNotes := F.ToString("sing-box ", tagVersion.String()) + if len(os.Args) >= 4 { + releaseNotes = strings.Join(os.Args[3:], " ") + } + client := createClient(20 * time.Minute) log.Info(tag, " list build IDs") @@ -115,97 +136,75 @@ func publishTestflight(ctx context.Context) error { buildIDs := common.Map(buildIDsResponse.Data, func(it asc.RelationshipData) string { return it.ID }) - var platforms []asc.Platform - if len(os.Args) == 3 { - switch os.Args[2] { - case "ios": - platforms = []asc.Platform{asc.PlatformIOS} - case "macos": - platforms = []asc.Platform{asc.PlatformMACOS} - case "tvos": - platforms = []asc.Platform{asc.PlatformTVOS} - default: - return E.New("unknown platform: ", os.Args[2]) - } - } else { - platforms = []asc.Platform{ - asc.PlatformIOS, - asc.PlatformMACOS, - asc.PlatformTVOS, - } - } + waitingForProcess := false - for _, platform := range platforms { - log.Info(string(platform), " list builds") - for { - builds, _, err := client.Builds.ListBuilds(ctx, &asc.ListBuildsQuery{ - FilterApp: []string{appID}, - FilterPreReleaseVersionPlatform: []string{string(platform)}, - }) - if err != nil { - return err - } - build := builds.Data[0] - if !waitingForProcess && (common.Contains(buildIDs, build.ID) || time.Since(build.Attributes.UploadedDate.Time) > 30*time.Minute) { - log.Info(string(platform), " ", tag, " waiting for process") - time.Sleep(15 * time.Second) - continue - } - if *build.Attributes.ProcessingState != "VALID" { - waitingForProcess = true - log.Info(string(platform), " ", tag, " waiting for process: ", *build.Attributes.ProcessingState) - time.Sleep(15 * time.Second) - continue - } - log.Info(string(platform), " ", tag, " list localizations") - localizations, _, err := client.TestFlight.ListBetaBuildLocalizationsForBuild(ctx, build.ID, nil) - if err != nil { - return err - } - localization := common.Find(localizations.Data, func(it asc.BetaBuildLocalization) bool { - return *it.Attributes.Locale == "en-US" - }) - if localization.ID == "" { - log.Fatal(string(platform), " ", tag, " no en-US localization found") - } - if localization.Attributes == nil || localization.Attributes.WhatsNew == nil || *localization.Attributes.WhatsNew == "" { - log.Info(string(platform), " ", tag, " update localization") - _, _, err = client.TestFlight.UpdateBetaBuildLocalization(ctx, localization.ID, common.Ptr( - F.ToString("sing-box ", tagVersion.String()), - )) - if err != nil { - return err - } - } - log.Info(string(platform), " ", tag, " publish") - response, err := client.TestFlight.AddBuildsToBetaGroup(ctx, groupID, []string{build.ID}) - if response != nil && (response.StatusCode == http.StatusUnprocessableEntity || response.StatusCode == http.StatusNotFound) { - log.Info("waiting for process") - time.Sleep(15 * time.Second) - continue - } else if err != nil { - return err - } - log.Info(string(platform), " ", tag, " list submissions") - betaSubmissions, _, err := client.TestFlight.ListBetaAppReviewSubmissions(ctx, &asc.ListBetaAppReviewSubmissionsQuery{ - FilterBuild: []string{build.ID}, - }) - if err != nil { - return err - } - if len(betaSubmissions.Data) == 0 { - log.Info(string(platform), " ", tag, " create submission") - _, _, err = client.TestFlight.CreateBetaAppReviewSubmission(ctx, build.ID) - if err != nil { - if strings.Contains(err.Error(), "ANOTHER_BUILD_IN_REVIEW") { - log.Error(err) - break - } - return err - } - } - break + log.Info(string(platform), " list builds") + for { + builds, _, err := client.Builds.ListBuilds(ctx, &asc.ListBuildsQuery{ + FilterApp: []string{appID}, + FilterPreReleaseVersionPlatform: []string{string(platform)}, + }) + if err != nil { + return err } + build := builds.Data[0] + if !waitingForProcess && (common.Contains(buildIDs, build.ID) || time.Since(build.Attributes.UploadedDate.Time) > 30*time.Minute) { + log.Info(string(platform), " ", tag, " waiting for process") + time.Sleep(15 * time.Second) + continue + } + if *build.Attributes.ProcessingState != "VALID" { + waitingForProcess = true + log.Info(string(platform), " ", tag, " waiting for process: ", *build.Attributes.ProcessingState) + time.Sleep(15 * time.Second) + continue + } + log.Info(string(platform), " ", tag, " list localizations") + localizations, _, err := client.TestFlight.ListBetaBuildLocalizationsForBuild(ctx, build.ID, nil) + if err != nil { + return err + } + localization := common.Find(localizations.Data, func(it asc.BetaBuildLocalization) bool { + return *it.Attributes.Locale == "en-US" + }) + if localization.ID == "" { + log.Fatal(string(platform), " ", tag, " no en-US localization found") + } + if localization.Attributes == nil || localization.Attributes.WhatsNew == nil || *localization.Attributes.WhatsNew == "" { + log.Info(string(platform), " ", tag, " update localization") + _, _, err = client.TestFlight.UpdateBetaBuildLocalization(ctx, localization.ID, common.Ptr(releaseNotes)) + if err != nil { + return err + } + } + log.Info(string(platform), " ", tag, " publish") + response, err := client.TestFlight.AddBuildsToBetaGroup(ctx, groupID, []string{build.ID}) + if response != nil && (response.StatusCode == http.StatusUnprocessableEntity || response.StatusCode == http.StatusNotFound) { + log.Info("waiting for process") + time.Sleep(15 * time.Second) + continue + } else if err != nil { + return err + } + log.Info(string(platform), " ", tag, " list submissions") + betaSubmissions, _, err := client.TestFlight.ListBetaAppReviewSubmissions(ctx, &asc.ListBetaAppReviewSubmissionsQuery{ + FilterBuild: []string{build.ID}, + }) + if err != nil { + return err + } + if len(betaSubmissions.Data) == 0 { + log.Info(string(platform), " ", tag, " create submission") + _, _, err = client.TestFlight.CreateBetaAppReviewSubmission(ctx, build.ID) + if err != nil { + if strings.Contains(err.Error(), "ANOTHER_BUILD_IN_REVIEW") { + log.Error(err) + break + } + return err + } + } + break } return nil }