diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..e6de40ddb --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,44 @@ +name: Build and Upload on AppStoreConnect + +on: + push: + tags: + - '*' + workflow_dispatch: + +jobs: + build: + name: Build and Upload on AppStoreConnect + runs-on: [ self-hosted, iOS ] + + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.12.1 + with: + access_token: ${{ github.token }} + - uses: jdx/mise-action@v2 + with: + cache: false + - name: Checkout + uses: actions/checkout@v4 + - name: Setup AppStoreConnect API key + env: + API_KEY_ID: ${{ secrets.APPSTORECONNECT_API_KEY_ID }} + API_KEY: ${{ secrets.APPSTORECONNECT_API_KEY }} + run: | + mkdir -p private_keys + touch "private_keys/AuthKey_$API_KEY_ID.p8" + echo -e "$API_KEY" > "private_keys/AuthKey_$API_KEY_ID.p8" + - name: Build and upload + env: + WORKSPACE: "Mail.xcworkspace" + SCHEME: "Infomaniak Mail" + SENTRY_PROJECT: "mail-ios" + API_ISSUER_ID: ${{ secrets.APPSTORECONNECT_API_ISSUER_ID }} + API_KEY_ID: ${{ secrets.APPSTORECONNECT_API_KEY_ID }} + SENTRY_URL: ${{ secrets.SENTRY_URL }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_ORG: ${{ secrets.SENTRY_ORG }} + run: ./scripts/build_and_upload.sh $GITHUB_REF_NAME + - name: Cleanup + run: rm -rf ./private_keys diff --git a/.github/workflows/swiftlint.yml b/.github/workflows/swiftlint.yml index 181799ac3..29161d122 100644 --- a/.github/workflows/swiftlint.yml +++ b/.github/workflows/swiftlint.yml @@ -1,12 +1,14 @@ name: SwiftLint on: - pull_request: - branches: [ master ] + push: + tags: + - '*' + workflow_dispatch: jobs: build: - name: SwiftLint + name: Build and Upload on AppStoreConnect runs-on: [ self-hosted, iOS ] steps: @@ -19,7 +21,25 @@ jobs: cache: false - name: Checkout uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: SwiftLint - run: swiftlint --config .swiftlint.yml --config .swiftlint-ci.yml --reporter github-actions-logging . + - name: Setup AppStoreConnect API key + env: + API_KEY_ID: ${{ secrets.APPSTORECONNECT_API_KEY_ID }} + API_KEY: ${{ secrets.APPSTORECONNECT_API_KEY }} + run: | + mkdir -p private_keys + touch "private_keys/AuthKey_$API_KEY_ID.p8" + echo -e "$API_KEY" > "private_keys/AuthKey_$API_KEY_ID.p8" + - name: Build and upload + env: + WORKSPACE: "Mail.xcworkspace" + SCHEME: "Infomaniak Mail" + SENTRY_PROJECT: "mail-ios" + API_ISSUER_ID: ${{ secrets.APPSTORECONNECT_API_ISSUER_ID }} + API_KEY_ID: ${{ secrets.APPSTORECONNECT_API_KEY_ID }} + SENTRY_URL: ${{ secrets.SENTRY_URL }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_ORG: ${{ secrets.SENTRY_ORG }} + GITHUB_REF_NAME: "Beta-1.2.8-b1" + run: ./scripts/build_and_upload.sh $GITHUB_REF_NAME + - name: Cleanup + run: rm -rf ./private_keys diff --git a/scripts/ExportOptions.plist b/scripts/ExportOptions.plist new file mode 100644 index 000000000..031164091 --- /dev/null +++ b/scripts/ExportOptions.plist @@ -0,0 +1,16 @@ + + + + + teamID + 864VDCS2QY + uploadBitcode + + uploadSymbols + + method + app-store + manageAppVersionAndBuildNumber + + + diff --git a/scripts/build_and_upload.sh b/scripts/build_and_upload.sh new file mode 100755 index 000000000..a899abd09 --- /dev/null +++ b/scripts/build_and_upload.sh @@ -0,0 +1,110 @@ +#!/bin/bash + +# Exit immediately if a command exits with a non-zero status +set -e + +# --- Check Environment Variables --- +REQUIRED_VARS=( + "WORKSPACE" + "SCHEME" + "API_ISSUER_ID" + "API_KEY_ID" + "SENTRY_URL" + "SENTRY_ORG" + "SENTRY_PROJECT" + "SENTRY_AUTH_TOKEN" +) + +for VAR in "${REQUIRED_VARS[@]}"; do + if [[ -z "${!VAR}" ]]; then + echo "Error: Environment variable $VAR is not set." + exit 1 + fi +done + +# --- Configuration --- +EXPORT_OPTIONS_PLIST="./scripts/ExportOptions.plist" +ARCHIVE_PATH="./build/$SCHEME.xcarchive" +IPA_PATH="./build/export" +CONSTANTS_FILE="./Tuist/ProjectDescriptionHelpers/Constants.swift" + +# --- Arguments --- +if [[ $# -ne 1 ]]; then + echo "Usage: $0 Beta--b" + echo "Example: $0 Beta-1.2.7-b10" + exit 1 +fi + +INPUT_STRING=$1 + +# Extract Version and Build Number +if [[ $INPUT_STRING =~ Beta-([0-9]+\.[0-9]+\.[0-9]+)-b([0-9]+) ]]; then + VERSION="${BASH_REMATCH[1]}" + BUILD_NUMBER="${BASH_REMATCH[2]}" +else + echo "Error: Input string must follow the format Beta--b (e.g., Beta-1.2.7-b10)" + exit 1 +fi + +# --- Clean and Build --- +echo "Cleaning previous build artifacts..." +rm -rf ./build +mkdir -p ./build + +echo "Cleaning Derived data..." +xcodebuild -workspace "$WORKSPACE" \ + -scheme "$SCHEME" + +# --- Update Constants.swift --- +echo "Updating version and build number in $CONSTANTS_FILE..." +sed -i '' -e "s/\.marketingVersion(\"[^\"]*\")/.marketingVersion(\"$VERSION\")/" \ + -e "s/\.currentProjectVersion(\"[^\"]*\")/.currentProjectVersion(\"$BUILD_NUMBER\")/" "$CONSTANTS_FILE" + +tuist install && tuist generate -n + +# --- Create and export archive --- +echo "Archiving the app..." +xcodebuild -workspace "$WORKSPACE" \ + -scheme "$SCHEME" \ + -sdk iphoneos \ + -configuration Release \ + -archivePath "$ARCHIVE_PATH" \ + archive + +echo "Exporting IPA..." +xcodebuild -exportArchive \ + -archivePath "$ARCHIVE_PATH" \ + -exportPath "$IPA_PATH" \ + -exportOptionsPlist "$EXPORT_OPTIONS_PLIST" + +# --- Upload IPA --- +echo "Uploading IPA to App Store Connect..." +xcrun altool --upload-app \ + --type ios \ + --file "$IPA_PATH/$SCHEME.ipa" \ + --apiKey "$API_KEY_ID" \ + --apiIssuer "$API_ISSUER_ID" + +if [ $? -eq 0 ]; then + echo "Upload successful!" +else + echo "Upload failed. Check the logs above for details." + exit 1 +fi + +# --- Upload symbols to Sentry --- +echo "Checking if sentry-cli is installed..." +if ! command -v sentry-cli &> /dev/null; then + echo "sentry-cli not found. Installing with brew..." + brew install sentry-cli +else + echo "sentry-cli is already installed." +fi + + echo "Uploading symbols to Sentry" +sentry-cli upload-dif --url $SENTRY_URL \ + --org $SENTRY_ORG \ + --project $SENTRY_PROJECT \ + --auth-token $SENTRY_AUTH_TOKEN \ + --derived-data \ + --include-sources ~/Library/Developer/Xcode/DerivedData