release: Add publish testflight

This commit is contained in:
世界 2024-12-15 21:56:23 +08:00
parent 2f24a64def
commit bb422ea4c6
No known key found for this signature in database
GPG Key ID: CD109927C34A63C4
2 changed files with 88 additions and 54 deletions

View File

@ -491,6 +491,10 @@ jobs:
-authenticationKeyPath $ASC_KEY_PATH \ -authenticationKeyPath $ASC_KEY_PATH \
-authenticationKeyID $ASC_KEY_ID \ -authenticationKeyID $ASC_KEY_ID \
-authenticationKeyIssuerID $ASC_KEY_ISSUER_ID -authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
- name: Publish to TestFlight
if: matrix.if && matrix.name != 'macOS-standalone' && github.event_name == 'workflow_dispatch'
run: |-
go run -v ./cmd/internal/app_store_connect publish_testflight ${{ matrix.platform }}
- name: Build image - name: Build image
if: matrix.if && matrix.name == 'macOS-standalone' && github.event_name == 'workflow_dispatch' if: matrix.if && matrix.name == 'macOS-standalone' && github.event_name == 'workflow_dispatch'
run: |- run: |-

View File

@ -54,12 +54,12 @@ const (
groupID = "5c5f3b78-b7a0-40c0-bcad-e6ef87bbefda" groupID = "5c5f3b78-b7a0-40c0-bcad-e6ef87bbefda"
) )
func createClient() *Client { func createClient(expireDuration time.Duration) *Client {
privateKey, err := os.ReadFile(os.Getenv("ASC_KEY_PATH")) privateKey, err := os.ReadFile(os.Getenv("ASC_KEY_PATH"))
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
tokenConfig, err := asc.NewTokenConfig(os.Getenv("ASC_KEY_ID"), os.Getenv("ASC_KEY_ISSUER_ID"), time.Minute, privateKey) tokenConfig, err := asc.NewTokenConfig(os.Getenv("ASC_KEY_ID"), os.Getenv("ASC_KEY_ISSUER_ID"), expireDuration, privateKey)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -67,7 +67,7 @@ func createClient() *Client {
} }
func fetchMacOSVersion(ctx context.Context) error { func fetchMacOSVersion(ctx context.Context) error {
client := createClient() client := createClient(time.Minute)
versions, _, err := client.Apps.ListAppStoreVersionsForApp(ctx, appID, &asc.ListAppStoreVersionsQuery{ versions, _, err := client.Apps.ListAppStoreVersionsForApp(ctx, appID, &asc.ListAppStoreVersionsQuery{
FilterPlatform: []string{"MAC_OS"}, FilterPlatform: []string{"MAC_OS"},
}) })
@ -105,71 +105,101 @@ func publishTestflight(ctx context.Context) error {
return err return err
} }
tag := tagVersion.VersionString() tag := tagVersion.VersionString()
client := createClient() client := createClient(10 * time.Minute)
log.Info(tag, " list build IDs")
buildIDsResponse, _, err := client.TestFlight.ListBuildIDsForBetaGroup(ctx, groupID, nil) buildIDsResponse, _, err := client.TestFlight.ListBuildIDsForBetaGroup(ctx, groupID, nil)
if err != nil { if err != nil {
return err return err
} }
buildIDS := common.Map(buildIDsResponse.Data, func(it asc.RelationshipData) string { buildIDs := common.Map(buildIDsResponse.Data, func(it asc.RelationshipData) string {
return it.ID return it.ID
}) })
for _, platform := range []asc.Platform{ var platforms []asc.Platform
asc.PlatformIOS, if len(os.Args) == 3 {
asc.PlatformMACOS, switch os.Args[2] {
asc.PlatformTVOS, 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,
}
}
for _, platform := range platforms {
log.Info(string(platform), " list builds") log.Info(string(platform), " list builds")
builds, _, err := client.Builds.ListBuilds(ctx, &asc.ListBuildsQuery{ for {
FilterApp: []string{appID}, builds, _, err := client.Builds.ListBuilds(ctx, &asc.ListBuildsQuery{
FilterPreReleaseVersionPlatform: []string{string(platform)}, FilterApp: []string{appID},
}) FilterPreReleaseVersionPlatform: []string{string(platform)},
if err != nil { })
return err
}
log.Info(string(platform), " ", tag, " list localizations")
localizations, _, err := client.TestFlight.ListBetaBuildLocalizationsForBuild(ctx, builds.Data[0].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 ", tag),
))
if err != nil { if err != nil {
return err return err
} }
} build := builds.Data[0]
if !common.Contains(buildIDS, builds.Data[0].ID) { if common.Contains(buildIDs, build.ID) || time.Since(build.Attributes.UploadedDate.Time) > 5*time.Minute {
log.Info(string(platform), " ", tag, " waiting for process")
time.Sleep(15 * time.Second)
continue
}
if *build.Attributes.ProcessingState != "VALID" {
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 ", tag),
))
if err != nil {
return err
}
}
log.Info(string(platform), " ", tag, " publish") log.Info(string(platform), " ", tag, " publish")
_, err = client.TestFlight.AddBuildsToBetaGroup(ctx, groupID, []string{builds.Data[0].ID}) response, err := client.TestFlight.AddBuildsToBetaGroup(ctx, groupID, []string{build.ID})
if response != nil && response.StatusCode == http.StatusUnprocessableEntity {
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 { if err != nil {
return err return err
} }
} if len(betaSubmissions.Data) == 0 {
log.Info(string(platform), " ", tag, " list submissions") log.Info(string(platform), " ", tag, " create submission")
betaSubmissions, _, err := client.TestFlight.ListBetaAppReviewSubmissions(ctx, &asc.ListBetaAppReviewSubmissionsQuery{ _, _, err = client.TestFlight.CreateBetaAppReviewSubmission(ctx, build.ID)
FilterBuild: []string{builds.Data[0].ID}, if err != nil {
}) return err
if err != nil { }
return err
}
if len(betaSubmissions.Data) == 0 {
log.Info(string(platform), " ", tag, " create submission")
_, _, err = client.TestFlight.CreateBetaAppReviewSubmission(ctx, builds.Data[0].ID)
if err != nil {
return err
} }
continue break
} }
} }
return nil return nil
} }
@ -187,7 +217,7 @@ func cancelAppStore(ctx context.Context, platform string) error {
if err != nil { if err != nil {
return err return err
} }
client := createClient() client := createClient(time.Minute)
log.Info(platform, " list versions") log.Info(platform, " list versions")
versions, _, err := client.Apps.ListAppStoreVersionsForApp(ctx, appID, &asc.ListAppStoreVersionsQuery{ versions, _, err := client.Apps.ListAppStoreVersionsForApp(ctx, appID, &asc.ListAppStoreVersionsQuery{
FilterPlatform: []string{string(platform)}, FilterPlatform: []string{string(platform)},
@ -222,7 +252,7 @@ func prepareAppStore(ctx context.Context) error {
if err != nil { if err != nil {
return err return err
} }
client := createClient() client := createClient(time.Minute)
for _, platform := range []asc.Platform{ for _, platform := range []asc.Platform{
asc.PlatformIOS, asc.PlatformIOS,
asc.PlatformMACOS, asc.PlatformMACOS,
@ -364,7 +394,7 @@ func publishAppStore(ctx context.Context) error {
if err != nil { if err != nil {
return err return err
} }
client := createClient() client := createClient(time.Minute)
for _, platform := range []asc.Platform{ for _, platform := range []asc.Platform{
asc.PlatformIOS, asc.PlatformIOS,
asc.PlatformMACOS, asc.PlatformMACOS,