Forráskód Böngészése

release: Update macOS project version atomically

世界 10 hónapja
szülő
commit
dd9de694f8
6 módosított fájl, 167 hozzáadás és 62 törlés
  1. 23 52
      .github/workflows/build.yml
  2. 10 4
      Makefile
  3. 108 0
      cmd/internal/app_store_connect/main.go
  4. 12 6
      cmd/internal/build_libbox/main.go
  5. 4 0
      go.mod
  6. 10 0
      go.sum

+ 23 - 52
.github/workflows/build.yml

@@ -28,10 +28,6 @@ on:
           - tvOS
           - macOS-standalone
           - publish-android
-      macos_project_version:
-        description: "macOS project version"
-        required: false
-        type: string
   push:
     branches:
       - main-next
@@ -354,67 +350,38 @@ jobs:
           ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
           LOCAL_PROPERTIES: ${{ secrets.LOCAL_PROPERTIES }}
           SERVICE_ACCOUNT_CREDENTIALS: ${{ secrets.SERVICE_ACCOUNT_CREDENTIALS }}
-  build_apple_library:
-    name: Build Apple library
-    if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store' || inputs.build == 'iOS' || inputs.build == 'macOS' || inputs.build == 'tvOS' || inputs.build == 'macOS-standalone'
-    runs-on: macos-15
-    needs:
-      - calculate_version
-    steps:
-      - name: Checkout
-        uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4
-        with:
-          fetch-depth: 0
-          submodules: 'recursive'
-      - name: Setup Go
-        uses: actions/setup-go@v5
-        with:
-          go-version: ^1.23
-      - name: Setup Xcode
-        run: |-
-          sudo xcode-select -s /Applications/Xcode_16.2_beta_3.app
-      - name: Set tag
-        run: |-
-          git tag v${{ needs.calculate_version.outputs.version }}
-      - name: Build library
-        run: |-
-          make lib_install
-          export PATH="$PATH:$(go env GOPATH)/bin"
-          make lib_ios
-      - name: Upload library
-        uses: actions/upload-artifact@v4
-        with:
-          name: library-apple
-          path: 'Libbox.xcframework'
   build_apple:
     name: Build Apple clients
     runs-on: macos-15
     needs:
       - calculate_version
-      - build_apple_library
     strategy:
       matrix:
         include:
           - name: iOS
             if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'iOS' }}
+            platform: ios
             scheme: SFI
             destination: 'generic/platform=iOS'
             archive: build/SFI.xcarchive
             upload: SFI/Upload.plist
           - name: macOS
             if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'macOS' }}
+            platform: macos
             scheme: SFM
             destination: 'generic/platform=macOS'
             archive: build/SFM.xcarchive
             upload: SFI/Upload.plist
           - name: tvOS
             if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'tvOS' }}
+            platform: tvos
             scheme: SFT
             destination: 'generic/platform=tvOS'
             archive: build/SFT.xcarchive
             upload: SFI/Upload.plist
           - name: macOS-standalone
             if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone' }}
+            platform: macos
             scheme: SFM.System
             destination: 'generic/platform=macOS'
             archive: build/SFM.System.xcarchive
@@ -435,7 +402,7 @@ jobs:
       - name: Setup Xcode
         if: matrix.if
         run: |-
-          sudo xcode-select -s /Applications/Xcode_16.2_beta_3.app
+          sudo xcode-select -s /Applications/Xcode_16.2.app
       - name: Set tag
         if: matrix.if
         run: |-
@@ -478,6 +445,10 @@ jobs:
             --key $ASC_KEY_PATH \
             --key-id $ASC_KEY_ID \
             --issuer $ASC_KEY_ISSUER_ID
+          
+          echo "ASC_KEY_PATH=$ASC_KEY_PATH" >> "$GITHUB_ENV"
+          echo "ASC_KEY_ID=$ASC_KEY_ID" >> "$GITHUB_ENV"
+          echo "ASC_KEY_ISSUER_ID=$ASC_KEY_ISSUER_ID" >> "$GITHUB_ENV"
         env:
           CERTIFICATES_P12: ${{ secrets.CERTIFICATES_P12 }}
           P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
@@ -486,12 +457,19 @@ jobs:
           ASC_KEY: ${{ secrets.ASC_KEY }}
           ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
           ASC_KEY_ISSUER_ID: ${{ secrets.ASC_KEY_ISSUER_ID }}
-      - name: Download library
+      - name: Build library
         if: matrix.if
-        uses: actions/download-artifact@v4
-        with:
-          name: library-apple
-          path: clients/apple/Libbox.xcframework
+        run: |-
+          make lib_install
+          export PATH="$PATH:$(go env GOPATH)/bin"
+          go run ./cmd/internal/build_libbox -target apple -platform ${{ matrix.platform }}
+          mv Libbox.xcframework clients/apple
+      - name: Update macOS version
+        if: matrix.if && matrix.name == 'macOS' && github.event_name == 'workflow_dispatch'
+        run: |-
+          MACOS_PROJECT_VERSION=$(go run -v ./cmd/internal/app_store_connect next_macos_project_version)
+          echo "MACOS_PROJECT_VERSION=$MACOS_PROJECT_VERSION"
+          echo "MACOS_PROJECT_VERSION=$MACOS_PROJECT_VERSION" >> "$GITHUB_ENV"
       - name: Build
         if: matrix.if
         run: |-
@@ -503,13 +481,9 @@ jobs:
             -destination "${{ matrix.destination }}" \
             -archivePath "${{ matrix.archive }}" \
             -allowProvisioningUpdates \
-            -authenticationKeyPath $RUNNER_TEMP/Key.p12 \
+            -authenticationKeyPath $ASC_KEY_PATH \
             -authenticationKeyID $ASC_KEY_ID \
             -authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
-        env:
-          MACOS_PROJECT_VERSION: ${{ inputs.macos_project_version }}
-          ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
-          ASC_KEY_ISSUER_ID: ${{ secrets.ASC_KEY_ISSUER_ID }}
       - name: Upload to App Store Connect
         if: matrix.if && matrix.name != 'macOS-standalone' && github.event_name == 'workflow_dispatch'
         run: |-
@@ -518,12 +492,9 @@ jobs:
             -archivePath "${{ matrix.archive }}" \
             -exportOptionsPlist ${{ matrix.upload }} \
             -allowProvisioningUpdates \
-            -authenticationKeyPath $RUNNER_TEMP/Key.p12 \
+            -authenticationKeyPath $ASC_KEY_PATH \
             -authenticationKeyID $ASC_KEY_ID \
             -authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
-        env:
-          ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
-          ASC_KEY_ISSUER_ID: ${{ secrets.ASC_KEY_ISSUER_ID }}
       - name: Build image
         if: matrix.if && matrix.name == 'macOS-standalone' && github.event_name == 'workflow_dispatch'
         run: |-

+ 10 - 4
Makefile

@@ -182,10 +182,16 @@ release_tvos: build_tvos upload_tvos_app_store
 update_apple_version:
 	go run ./cmd/internal/update_apple_version
 
+update_macos_version:
+	MACOS_PROJECT_VERSION=$(shell go run -v ./cmd/internal/app_store_connect next_macos_project_version) go run ./cmd/internal/update_apple_version
+
 release_apple: lib_ios update_apple_version release_ios release_macos release_tvos release_macos_standalone
 
 release_apple_beta: update_apple_version release_ios release_macos release_tvos
 
+publish_testflight:
+	go run -v ./cmd/internal/app_store_connect publish_testflight
+
 test:
 	@go test -v ./... && \
 	cd test && \
@@ -204,11 +210,11 @@ lib_android:
 lib_android_debug:
 	go run ./cmd/internal/build_libbox -target android -debug
 
-lib_ios:
-	go run ./cmd/internal/build_libbox -target ios
+lib_apple:
+	go run ./cmd/internal/build_libbox -target apple
 
-lib_ios_debug:
-	go run ./cmd/internal/build_libbox -target ios -debug
+lib_ios:
+	go run ./cmd/internal/build_libbox -target apple -platform ios -debug
 
 lib:
 	go run ./cmd/internal/build_libbox -target android

+ 108 - 0
cmd/internal/app_store_connect/main.go

@@ -0,0 +1,108 @@
+package main
+
+import (
+	"context"
+	"os"
+	"strconv"
+	"time"
+
+	"github.com/sagernet/sing-box/log"
+	"github.com/sagernet/sing/common"
+	E "github.com/sagernet/sing/common/exceptions"
+	F "github.com/sagernet/sing/common/format"
+
+	"github.com/cidertool/asc-go/asc"
+)
+
+func main() {
+	switch os.Args[1] {
+	case "publish_testflight":
+		err := publishTestflight(context.Background())
+		if err != nil {
+			log.Fatal(err)
+		}
+	case "next_macos_project_version":
+		err := fetchMacOSVersion(context.Background())
+		if err != nil {
+			log.Fatal(err)
+		}
+	default:
+		log.Fatal("unknown action: ", os.Args[1])
+	}
+}
+
+const (
+	appID   = "6673731168"
+	groupID = "5c5f3b78-b7a0-40c0-bcad-e6ef87bbefda"
+)
+
+func createClient() *asc.Client {
+	privateKey, err := os.ReadFile(os.Getenv("ASC_KEY_PATH"))
+	if err != nil {
+		log.Fatal(err)
+	}
+	tokenConfig, err := asc.NewTokenConfig(os.Getenv("ASC_KEY_ID"), os.Getenv("ASC_KEY_ISSUER_ID"), time.Minute, privateKey)
+	if err != nil {
+		log.Fatal(err)
+	}
+	return asc.NewClient(tokenConfig.Client())
+}
+
+func publishTestflight(ctx context.Context) error {
+	client := createClient()
+	var buildsToPublish []asc.Build
+	for _, platform := range []string{
+		"IOS",
+		"MAC_OS",
+		"TV_OS",
+	} {
+		builds, _, err := client.Builds.ListBuilds(ctx, &asc.ListBuildsQuery{
+			FilterApp:                       []string{appID},
+			FilterPreReleaseVersionPlatform: []string{platform},
+		})
+		if err != nil {
+			return err
+		}
+		buildsToPublish = append(buildsToPublish, builds.Data[0])
+	}
+	_, err := client.TestFlight.AddBuildsToBetaGroup(ctx, groupID, common.Map(buildsToPublish, func(it asc.Build) string {
+		return it.ID
+	}))
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func fetchMacOSVersion(ctx context.Context) error {
+	client := createClient()
+	versions, _, err := client.Apps.ListAppStoreVersionsForApp(ctx, appID, &asc.ListAppStoreVersionsQuery{
+		FilterPlatform: []string{"MAC_OS"},
+	})
+	if err != nil {
+		return err
+	}
+	var versionID string
+findVersion:
+	for _, version := range versions.Data {
+		switch *version.Attributes.AppStoreState {
+		case asc.AppStoreVersionStateReadyForSale,
+			asc.AppStoreVersionStatePendingDeveloperRelease:
+			versionID = version.ID
+			break findVersion
+		}
+	}
+	if versionID == "" {
+		return E.New("no version found")
+	}
+	latestBuild, _, err := client.Builds.GetBuildForAppStoreVersion(ctx, versionID, &asc.GetBuildForAppStoreVersionQuery{})
+	if err != nil {
+		return err
+	}
+	versionInt, err := strconv.Atoi(*latestBuild.Data.Attributes.Version)
+	if err != nil {
+		return E.Cause(err, "parse version code")
+	}
+	os.Stdout.WriteString(F.ToString(versionInt+1, "\n"))
+	return nil
+}

+ 12 - 6
cmd/internal/build_libbox/main.go

@@ -18,11 +18,13 @@ import (
 var (
 	debugEnabled bool
 	target       string
+	platform     string
 )
 
 func init() {
 	flag.BoolVar(&debugEnabled, "debug", false, "enable debug")
 	flag.StringVar(&target, "target", "android", "target platform")
+	flag.StringVar(&platform, "platform", "", "specify platform")
 }
 
 func main() {
@@ -33,8 +35,8 @@ func main() {
 	switch target {
 	case "android":
 		buildAndroid()
-	case "ios":
-		buildiOS()
+	case "apple":
+		buildApple()
 	}
 }
 
@@ -81,7 +83,9 @@ func buildAndroid() {
 	}
 
 	var bindTarget string
-	if debugEnabled {
+	if platform != "" {
+		bindTarget = platform
+	} else if debugEnabled {
 		bindTarget = "android/arm64"
 	} else {
 		bindTarget = "android"
@@ -129,12 +133,14 @@ func buildAndroid() {
 	}
 }
 
-func buildiOS() {
+func buildApple() {
 	var bindTarget string
-	if debugEnabled {
+	if platform != "" {
+		bindTarget = platform
+	} else if debugEnabled {
 		bindTarget = "ios"
 	} else {
-		bindTarget = "ios,iossimulator,tvos,tvossimulator,macos"
+		bindTarget = "ios,tvos,macos"
 	}
 
 	args := []string{

+ 4 - 0
go.mod

@@ -5,6 +5,7 @@ go 1.20
 require (
 	berty.tech/go-libtor v1.0.385
 	github.com/caddyserver/certmagic v0.20.0
+	github.com/cidertool/asc-go v0.5.1
 	github.com/cloudflare/circl v1.3.7
 	github.com/cretz/bine v0.2.0
 	github.com/go-chi/chi/v5 v5.1.0
@@ -60,7 +61,9 @@ require (
 require (
 	github.com/ajg/form v1.5.1 // indirect
 	github.com/andybalholm/brotli v1.0.6 // indirect
+	github.com/cenkalti/backoff/v4 v4.1.0 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 // indirect
 	github.com/fsnotify/fsnotify v1.7.0 // indirect
 	github.com/go-ole/go-ole v1.3.0 // indirect
 	github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
@@ -68,6 +71,7 @@ require (
 	github.com/gobwas/pool v0.2.1 // indirect
 	github.com/google/btree v1.1.3 // indirect
 	github.com/google/go-cmp v0.6.0 // indirect
+	github.com/google/go-querystring v1.0.0 // indirect
 	github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a // indirect
 	github.com/hashicorp/yamux v0.1.2 // indirect
 	github.com/inconshreveable/mousetrap v1.1.0 // indirect

+ 10 - 0
go.sum

@@ -6,6 +6,10 @@ github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sx
 github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
 github.com/caddyserver/certmagic v0.20.0 h1:bTw7LcEZAh9ucYCRXyCpIrSAGplplI0vGYJ4BpCQ/Fc=
 github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg=
+github.com/cenkalti/backoff/v4 v4.1.0 h1:c8LkOFQTzuO0WBM/ae5HdGQuZPfPxp7lqBRwQRm4fSc=
+github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
+github.com/cidertool/asc-go v0.5.1 h1:KYki2Y8IXJMOkOXy9y1sdr8tz6IdW2ti770K4bk7WY0=
+github.com/cidertool/asc-go v0.5.1/go.mod h1:LyrZWU7DeCh8cWrFwXcpl93ixRUUL2aEZV7/0h07FxA=
 github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
 github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
 github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@@ -15,6 +19,8 @@ github.com/cretz/bine v0.2.0/go.mod h1:WU4o9QR9wWp8AVKtTM1XD5vUHkEqnf2vVSo6dBqbe
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 h1:CaO/zOnF8VvUfEbhRatPcwKVWamvbYd8tQGRWacE9kU=
+github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4=
 github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
 github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
 github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
@@ -37,6 +43,8 @@ github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
 github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
 github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
+github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
 github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a h1:fEBsGL/sjAuJrgah5XqmmYsTLzJp/TO9Lhy39gkverk=
 github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
 github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=
@@ -203,6 +211,8 @@ golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
 golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE=
 golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=