Skip to content

Commit

Permalink
Use App Store Connect API to set version in Xcode Cloud CI post clone
Browse files Browse the repository at this point in the history
  • Loading branch information
mvasilak committed Aug 28, 2023
1 parent a712ec5 commit 2428260
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
26 changes: 25 additions & 1 deletion ci_scripts/ci_post_clone.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
#!/bin/sh
#!/bin/bash

# ci_post_clone.sh
# Zotero
#
# Created by Miltiadis Vasilakis on 3/8/23.
# Copyright © 2023 Corporation for Digital Scholarship. All rights reserved.

set -euo pipefail

which swiftgen || HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew install swiftgen
which swiftlint || HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew install swiftlint
which openssl || HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew install openssl
which python3 || HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew install python3
which jq || HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew install jq
pip3 install joserfc

# Generate JWT token
jwt_token=$(./generate_jtw_token.py)

# App Store Connect API request
response=$(curl -s --header "Authorization: Bearer $jwt_token" "https://api.appstoreconnect.apple.com/v1/apps/$zotero_app_id/appStoreVersions?filter%5BappStoreState%5D=READY_FOR_SALE&fields%5BappStoreVersions%5D=versionString")
versionString=$(echo "$response" | jq -r '.data[0].attributes.versionString')
if [[ "$versionString" == "null" ]]; then
echo "Error: versionString is null"
exit 1
fi

# Increment version string
newVersionString=$(awk -F. -v OFS=. '{$NF = $NF + 1; print}' <<< "$versionString")

# Update Info.plist files
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $newVersionString" ../Zotero/Info.plist
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $newVersionString" ../ZShare/Info.plist
29 changes: 29 additions & 0 deletions ci_scripts/generate_jtw_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env python3

import os, sys, time
from joserfc import jwt
from joserfc.jwk import ECKey

def generate_jwt_token(key_id, issuer_id, secret):
header = {"alg": "ES256", "kid": key_id, "typ": "JWT"}
issued_at_time = int(time.time())
expiration_time = issued_at_time + 2*600
payload = {"iss": issuer_id, "iat": issued_at_time, "exp": expiration_time, "aud": "appstoreconnect-v1"}
secret = secret[:27] + secret[27:-25].replace(" ", "\n") + secret[-25:]
key = ECKey.import_key(secret)
token = jwt.encode(header, payload, key)
return f"{token}"

if __name__ == "__main__":
key_id = os.environ.get("app_store_connect_key_id")
issuer_id = os.environ.get("app_store_connect_issuer_id")
secret = os.environ.get("app_store_connect_api_key")
if key_id is None or issuer_id is None or secret is None:
print("Error: One or more arguments are missing", file=sys.stderr)
sys.exit(1)
elif secret[:27] != "-----BEGIN PRIVATE KEY-----" or secret[-25:] != "-----END PRIVATE KEY-----":
print("Error: secret not in PEM format", file=sys.stderr)
sys.exit(2)

result = generate_jwt_token(key_id, issuer_id, secret)
print(result)

0 comments on commit 2428260

Please sign in to comment.