Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,4 @@ ui/StatusQ/src/StatusQ/Core/TestConfig.qml
mobile/bin/
mobile/lib/
mobile/build/
scripts/node_modules/
2 changes: 1 addition & 1 deletion ci/Jenkinsfile.android
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library '[email protected].29'
library '[email protected].30'

/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
Expand Down
2 changes: 1 addition & 1 deletion ci/Jenkinsfile.combined
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env groovy

library '[email protected].29'
library '[email protected].30'

/* Object to store public URLs for description. */
urls = [:]
Expand Down
44 changes: 36 additions & 8 deletions ci/Jenkinsfile.ios
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#!/usr/bin/env groovy
library '[email protected].29'
library '[email protected].30'

/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
def isNightlyBuild = utils.isNightlyBuild()

pipeline {

Expand All @@ -20,6 +19,16 @@ pipeline {
description: 'Level of verbosity based on nimbus-build-system setup.',
choices: ['0','1','2','3']
)
string(
name: 'TESTFLIGHT_POLL_TIMEOUT',
description: 'TestFlight build polling timeout in minutes.',
defaultValue: '30'
)
string(
name: 'TESTFLIGHT_POLL_INTERVAL',
description: 'TestFlight build polling interval in seconds.',
defaultValue: '30'
)
}

options {
Expand Down Expand Up @@ -65,8 +74,11 @@ pipeline {
IPHONE_SDK = "iphoneos"
ARCH = "x86_64"
/* iOS app paths */
STATUS_IOS_APP_ARTIFACT = "pkg/${utils.pkgFilename(ext: 'app.zip', arch: getArch(), version: env.VERSION, type: env.APP_TYPE)}"
STATUS_IOS_APP_ARTIFACT = "pkg/${utils.pkgFilename(ext: 'ipa', arch: getArch(), version: env.VERSION, type: env.APP_TYPE)}"
STATUS_IOS_APP = "${WORKSPACE}/mobile/bin/ios/qt6/Status.app"
STATUS_IOS_IPA = "${WORKSPACE}/mobile/bin/ios/qt6/Status.ipa"
TESTFLIGHT_POLL_TIMEOUT = "${params.TESTFLIGHT_POLL_TIMEOUT}"
TESTFLIGHT_POLL_INTERVAL = "${params.TESTFLIGHT_POLL_INTERVAL}"
}

stages {
Expand All @@ -91,25 +103,41 @@ pipeline {

stage('Build iOS App') {
steps {
sh 'make mobile-build'
script {
app.buildSignedIOS(target='mobile-build', verbose=params.VERBOSE)
}
}
}

stage('Package iOS App') {
steps {
sh 'mkdir -p pkg'
sh "cd mobile/bin/ios/qt6 && zip -r ${env.WORKSPACE}/${env.STATUS_IOS_APP_ARTIFACT} Status.app"
sh "ls -la ${env.STATUS_IOS_APP_ARTIFACT}"
sh "cp ${env.STATUS_IOS_IPA} ${env.STATUS_IOS_APP_ARTIFACT}"
sh "ls -lh ${env.STATUS_IOS_APP_ARTIFACT}"
}
}

stage('Parallel Upload') {
parallel {
stage('Upload') {
stage('Upload to TestFlight') {
steps {
script {
def changelog = sh(script: './scripts/generate-changelog.sh', returnStdout: true).trim()

app.uploadToTestFlight(
ipaPath=env.STATUS_IOS_APP_ARTIFACT,
changelog=changelog,
pollTimeout=env.TESTFLIGHT_POLL_TIMEOUT,
pollInterval=env.TESTFLIGHT_POLL_INTERVAL
)
}
}
}
stage('Upload to S3') {
steps {
script {
env.PKG_URL = s5cmd.upload(env.STATUS_IOS_APP_ARTIFACT)
jenkins.setBuildDesc(APP: env.PKG_URL)
jenkins.setBuildDesc(IPA: env.PKG_URL)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion ci/Jenkinsfile.linux
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library '[email protected].29'
library '[email protected].30'

/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
Expand Down
2 changes: 1 addition & 1 deletion ci/Jenkinsfile.linux-nix
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env groovy

library '[email protected].29'
library '[email protected].30'

/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
Expand Down
2 changes: 1 addition & 1 deletion ci/Jenkinsfile.macos
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library '[email protected].29'
library '[email protected].30'

/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
Expand Down
2 changes: 1 addition & 1 deletion ci/Jenkinsfile.qt-build
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library '[email protected].29'
library '[email protected].30'

pipeline {
agent {
Expand Down
2 changes: 1 addition & 1 deletion ci/Jenkinsfile.tests-e2e
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library '[email protected].29'
library '[email protected].30'

pipeline {
agent {
Expand Down
2 changes: 1 addition & 1 deletion ci/Jenkinsfile.tests-e2e.windows
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library '[email protected].29'
library '[email protected].30'

pipeline {

Expand Down
2 changes: 1 addition & 1 deletion ci/Jenkinsfile.tests-nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library '[email protected].29'
library '[email protected].30'

/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
Expand Down
2 changes: 1 addition & 1 deletion ci/Jenkinsfile.tests-ui
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library '[email protected].29'
library '[email protected].30'

/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
Expand Down
2 changes: 1 addition & 1 deletion ci/Jenkinsfile.windows
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library '[email protected].29'
library '[email protected].30'

/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
Expand Down
2 changes: 2 additions & 0 deletions mobile/ios/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,7 @@
<string>Status uses Media Library to save and send Images. The Media Library module internally requires permissions to Apple Music</string>
<key>NSFaceIDUsageDescription</key>
<string>Log in securely to your account.</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
</dict>
</plist>
55 changes: 55 additions & 0 deletions mobile/scripts/android/sign.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
set -euo pipefail

if [[ $# -lt 1 ]]; then
echo "Usage: $0 <aab-file-path>"
exit 1
fi

AAB_FILE="$1"

function required_var() {
if [[ -z "${!1}" ]]; then
echo -e "ERROR: No required env variable: ${1}" 1>&2
exit 1
fi
}

required_var KEYSTORE_PATH
required_var KEYSTORE_PASSWORD
required_var KEY_ALIAS
required_var KEY_PASSWORD

if [[ ! -f "$AAB_FILE" ]]; then
echo "ERROR: AAB file not found at $AAB_FILE"
exit 1
fi

if [[ ! -f "$KEYSTORE_PATH" ]]; then
echo "ERROR: Keystore file not found at $KEYSTORE_PATH"
exit 1
fi

echo "Signing AAB with jarsigner..."
jarsigner -sigalg SHA256withRSA -digestalg SHA-256 \
-keystore "$KEYSTORE_PATH" \
-storepass "$KEYSTORE_PASSWORD" \
-keypass "$KEY_PASSWORD" \
"$AAB_FILE" "$KEY_ALIAS"

if [[ $? -ne 0 ]]; then
echo "Error: AAB signing failed"
exit 1
fi

echo "Verifying AAB signature..."
VERIFY_OUTPUT=$(jarsigner -verify "$AAB_FILE" 2>&1)
if echo "$VERIFY_OUTPUT" | grep -q "jar verified"; then
echo "AAB signature verification: PASSED"
else
echo "Error: AAB signature verification failed"
echo "Verify output: $VERIFY_OUTPUT"
exit 1
fi

echo "AAB signed successfully: $AAB_FILE"
49 changes: 23 additions & 26 deletions mobile/scripts/buildApp.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
set -ef pipefail
set -eo pipefail

CWD=$(realpath "$(dirname "$0")")

Expand All @@ -10,6 +10,7 @@ BIN_DIR=${BIN_DIR:-"$CWD/../bin/ios"}
BUILD_DIR=${BUILD_DIR:-"$CWD/../build"}
ANDROID_ABI=${ANDROID_ABI:-"arm64-v8a"}
BUILD_TYPE=${BUILD_TYPE:-"apk"}
SIGN_IOS=${SIGN_IOS:-"false"}

echo "Building wrapperApp for ${OS}, ${ANDROID_ABI}"

Expand Down Expand Up @@ -60,27 +61,8 @@ if [[ "${OS}" == "android" ]]; then
exit 1
fi

# Note: androiddeployqt --sign does not work for AAB files, so we sign with jarsigner
echo "Signing AAB with jarsigner..."
jarsigner -sigalg SHA256withRSA -digestalg SHA-256 \
-keystore "$KEYSTORE_PATH" \
-storepass "$KEYSTORE_PASSWORD" \
-keypass "$KEY_PASSWORD" \
"$OUTPUT_FILE" "$KEY_ALIAS"

if [[ $? -ne 0 ]]; then
echo "Error: AAB signing failed"
exit 1
fi

VERIFY_OUTPUT=$(jarsigner -verify "$OUTPUT_FILE" 2>&1)
if echo "$VERIFY_OUTPUT" | grep -q "jar verified"; then
echo "AAB signature verification: PASSED"
else
echo "Error: AAB signature verification failed"
echo "Verify output: $VERIFY_OUTPUT"
exit 1
fi
# Sign the AAB file (androiddeployqt --sign does not work for AAB files)
"$CWD/android/sign.sh" "$OUTPUT_FILE"

ANDROID_OUTPUT_DIR="bin/android/qt6"
BIN_DIR_ANDROID=${BIN_DIR:-"$CWD/$ANDROID_OUTPUT_DIR"}
Expand Down Expand Up @@ -128,17 +110,32 @@ if [[ "${OS}" == "android" ]]; then
fi
fi
else
BUILD_VERSION=$(($(date +%s) * 1000 / 60000))

if [[ -n "${CHANGE_ID:-}" ]]; then
VERSION_STRING="${CHANGE_ID}.${BUILD_VERSION}"
else
VERSION_STRING="${BUILD_VERSION}"
fi

echo "Using version: $VERSION_STRING"

QMAKE_BIN="${QMAKE:-qmake}"
"$QMAKE_BIN" "$CWD/../wrapperApp/Status.pro" -spec macx-ios-clang CONFIG+=release CONFIG+="$SDK" CONFIG+=device -after
"$QMAKE_BIN" "$CWD/../wrapperApp/Status.pro" -spec macx-ios-clang CONFIG+=release CONFIG+="$SDK" CONFIG+=device VERSION="$VERSION_STRING" -after

# Compile resources
xcodebuild -configuration Release -target "Qt Preprocess" -sdk "$SDK" -arch "$ARCH" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO | xcbeautify
# Compile the app
xcodebuild -configuration Release -target Status install -sdk "$SDK" -arch "$ARCH" DSTROOT="$BIN_DIR" INSTALL_PATH="/" TARGET_BUILD_DIR="$BIN_DIR" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO | xcbeautify

if [[ -e "$BIN_DIR/Status.app/Info.plist" ]]; then
echo "Build succeeded"
else
if [[ ! -e "$BIN_DIR/Status.app/Info.plist" ]]; then
echo "Build failed"
exit 1
fi

if [[ "$SIGN_IOS" == "true" ]]; then
"$CWD/ios/sign.sh"
fi

echo "Build succeeded"
fi
Loading