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