Skip to main content

AWS CodeBuild Configuration & Optimization for MASST CLI Integration

Step 1: Create an S3 Bucket

Create an Amazon S3 bucket to store the build artifacts generated by CodeBuild.

Step 2: Create a CodeBuild Project

  1. Open the AWS Console.
  2. Navigate to CodeBuild.
  3. Select Create build project.
  4. Enter a project name.

Step 3: Configure the Source

Select GitHub as the source provider.

Connect your GitHub account using AWS CodeConnections and select the required repository.

Ensure the repository contains all required project files.

Step 4: Configure the Environment

Configure the CodeBuild environment using the appropriate settings for your project. The following configuration was used for our setup:

  • Environment Type: Managed Image
  • Operating System: Ubuntu
  • Runtime: Standard
  • Image Version: Ubuntu Standard 8.0 (or later)
Note

The operating system, runtime, and image version can be modified based on your project's requirements and build environment.

Step 5: Configure Artifacts

Select Amazon S3 as the artifact destination.

Choose the S3 bucket created earlier.

The generated output files will be uploaded to this bucket after a successful build.

Step 6: Add the Build Specification

Place the buildspec.yml file in the root directory of the GitHub repository.

The build specification is responsible for:

  • Downloading MASSTCLI
  • Preparing the build environment
  • Running the MASSTCLI integration
  • Uploading the generated artifacts

Environment Variables

The following environment variables should be configured in the buildspec.yml file before running the CodeBuild project.

VariableDescriptionRequired Input
IS_DEBUGSpecifies whether the application is a debug or release build. Set to true for debug builds and false for release builds.true or false
INPUT_FILEName of the application package to be integrated by MASSTCLI. The file must be present in the GitHub repository.Example: app-release.aab or app-release.apk
CONFIG_FILEName of the MASST configuration file used during integration. The file must be present in the repository.Example: config.bm
MACOS_DOWNLOAD_URLDownload URL for the macOS version of MASSTCLI. This is used only when the build is executed on macOS.Keep the default URL unless a newer MASSTCLI version is provided.
LINUX_DOWNLOAD_URLDownload URL for the Linux version of MASSTCLI. This is used when the build runs on AWS CodeBuild (Ubuntu).Keep the default URL unless a newer MASSTCLI version is provided.
ANDROID_HOMELocation where the Android SDK is installed in the build environment. MASSTCLI uses this path to locate Android SDK components.Example: /opt/android-sdk
ANDROID_SDK_ROOTRoot directory of the Android SDK. This should match the value of ANDROID_HOME.Example: /opt/android-sdk
KEYSTORE_FILEAndroid signing keystore file. The file must be available in the repository or downloaded during the build.Example: keystore.jks
KEYSTORE_PASSWORDPassword used to access the Android keystore.Enter the password for the keystore.
KEY_ALIASAlias of the signing key stored inside the keystore.Example: key0
KEY_PASSWORDPassword for the signing key alias. In many cases, this is the same as the keystore password.Enter the alias password.
IDENTITYApple signing identity used only for iOS application integration. This value is ignored for Android builds.Example: Apple Certificate
MASST_DIRDirectory where the downloaded MASSTCLI package is extracted during the build.Default value can be retained.
ARTIFACTS_DIRDirectory where generated build artifacts and reports are stored before being uploaded to Amazon S3.Default value can be retained or changed if required.
MASST_ZIPName assigned to the downloaded MASSTCLI archive before extraction.Default value can be retained.

Required Files

Ensure the following files are available in the GitHub repository before starting the build:

  • Application package (.apk or .aab)
  • MASST configuration file (.bm)
  • Android keystore (.jks) (required for release builds)
  • Buildspec.yml
version: 0.2

env:
variables:
# Default parameters (Can be overridden when starting the CodeBuild execution)
IS_DEBUG: "false"
INPUT_FILE: "your-app-release.aab"
CONFIG_FILE: "your-config.bm"
MACOS_DOWNLOAD_URL: "https://storage.googleapis.com/masst-assets/Defender-Binary-Integrator/1.0.0/MacOS/MASSTCLI-v1.1.0-darwin-arm64.zip"
LINUX_DOWNLOAD_URL: "https://storage.googleapis.com/masst-assets/Defender-Binary-Integrator/1.0.0/Linux/MASSTCLI-v1.1.0-linux-amd64.zip"

# Set up a clean, standard location for the Android SDK
ANDROID_HOME: "/opt/android-sdk"
ANDROID_SDK_ROOT: "/opt/android-sdk"

KEYSTORE_FILE: "Keystorefile.jks"
KEYSTORE_PASSWORD: "keystorepassword"
KEY_ALIAS: "keys"
KEY_PASSWORD: "password"
IDENTITY: "Certificate"
MASST_DIR: "MASSTCLI_EXTRACTED"
ARTIFACTS_DIR: "output"
MASST_ZIP: "MASSTCLI"

phases:
install:
commands:
- echo "Installing Java 17 and system dependencies..."
- apt-get update && apt-get install -y openjdk-17-jdk unzip wget curl lib32stdc++6 lib32z1

- echo "Checking if Android SDK is already restored from cache..."
- |
if [ ! -d "/opt/android-sdk/platform-tools" ]; then
echo "Cache miss! Downloading and configuring Android SDK Command Line Tools..."
mkdir -p /opt/android-sdk/cmdline-tools
cd /opt/android-sdk/cmdline-tools

curl -L -o cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
unzip -q cmdline-tools.zip

# Fixes the "Could not determine SDK root" error by setting up the expected structure
mv cmdline-tools latest
rm -f cmdline-tools.zip

echo "Installing Android SDK Platform Tools, Build Tools, and API 36..."
export PATH=/opt/android-sdk/cmdline-tools/latest/bin:/opt/android-sdk/platform-tools:$PATH
yes | sdkmanager --licenses || true
sdkmanager "platform-tools" "platforms;android-35" "platforms;android-36" "build-tools;35.0.0"
else
echo "Cache HIT! Android SDK already exists. Skipping download steps."
fi
# Always return to the CodeBuild workspace root directory
- cd $CODEBUILD_SRC_DIR

- echo "Detecting platform and downloading MASST CLI..."
- |
if [ "$(uname)" = "Darwin" ]; then
echo "MacOS" > platform.txt
DOWNLOAD_URL=$MACOS_DOWNLOAD_URL
else
echo "Linux" > platform.txt
DOWNLOAD_URL=$LINUX_DOWNLOAD_URL
fi
echo "Platform detected: $(cat platform.txt)"

if [ ! -f "${MASST_ZIP}.zip" ]; then
curl -L -o "${MASST_ZIP}.zip" "${DOWNLOAD_URL}" || wget -O "${MASST_ZIP}.zip" "${DOWNLOAD_URL}"
fi

- echo "Extracting toolsets..."
- |
rm -rf "${MASST_DIR}"
mkdir -p "${MASST_DIR}"
unzip -q "${MASST_ZIP}.zip" -d "${MASST_DIR}"
chmod +x $(find "${MASST_DIR}" -type f -name "MASSTCLI*" || true)
echo "Setup completed"

pre_build:
commands:
- echo "Validating input files..."
- '[ -f "${INPUT_FILE}" ] || { echo "ERROR: ${INPUT_FILE} not found"; exit 1; }'
- '[ -f "${CONFIG_FILE}" ] || { echo "ERROR: ${CONFIG_FILE} not found"; exit 1; }'

build:
commands:
- echo "Re-exporting Android paths for the Build shell environment..."
- export ANDROID_HOME=/opt/android-sdk
- export ANDROID_SDK_ROOT=/opt/android-sdk

# Added $ANDROID_HOME/build-tools/35.0.0 to the PATH string so 'd8' can be executed globally
- export PATH=/bin:/usr/bin:/usr/local/bin:$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools/35.0.0

- echo "Creating local standard Android SDK symlink structure expected by MASST..."
- mkdir -p $HOME/Android
- ln -sfn /opt/android-sdk $HOME/Android/Sdk

- |
MASST_EXE=$(find "${MASST_DIR}" -type f -name "MASSTCLI*" | head -n 1)
if [ -z "$MASST_EXE" ]; then
echo "ERROR: MASST CLI not found"
exit 1
fi
echo "Using MASST CLI: $MASST_EXE"

EXT=$(echo "${INPUT_FILE}" | awk -F. '{print tolower($NF)}')
case "$EXT" in
xcarchive|ipa)
"$MASST_EXE" -input="${INPUT_FILE}" -config="${CONFIG_FILE}" -identity="${IDENTITY}"
;;
aab|apk)
if [ "${IS_DEBUG}" = "true" ]; then
"$MASST_EXE" -input="${INPUT_FILE}" -config="${CONFIG_FILE}"
else
"$MASST_EXE" -input="${INPUT_FILE}" -config="${CONFIG_FILE}" \
-keystore="${KEYSTORE_FILE}" \
-storePassword=${KEYSTORE_PASSWORD} \
-alias=${KEY_ALIAS} \
-keyPassword=${KEY_PASSWORD} \
-v=true -apk
fi
;;
*)
echo "ERROR: Unsupported file type"
exit 1
;;
esac
echo "Execution completed"

post_build:
commands:
- mkdir -p "${ARTIFACTS_DIR}"
- DETECTED_PLATFORM=$(cat platform.txt || echo "Unknown")
- echo "Build - ${DETECTED_PLATFORM} | IS_DEBUG=${IS_DEBUG} | $(date)" > "${ARTIFACTS_DIR}/report.txt"
- rm -f "${MASST_ZIP}.zip"
- |
if [ "$CODEBUILD_BUILD_SUCCEEDING" = "1" ]; then
echo "${DETECTED_PLATFORM} IS_DEBUG=${IS_DEBUG} - SUCCESS"
else
echo "Failed"
fi

artifacts:
files:
- 'output/**/*'
cache:
paths:
- '/opt/android-sdk/**/*'
- '$HOME/.android/**/*'

Step 7: Start the Build

After creating the project, select Start Build.

CodeBuild will:

  • Clone the GitHub repository.
  • Execute the commands defined in buildspec.yml.
  • Run MASSTCLI.
  • Upload the generated artifacts to the configured S3 bucket.

Android SDK Requirement

MASSTCLI requires the Android SDK during execution.

AWS CodeBuild starts with a fresh environment for every build. Therefore, the Android SDK must either:

  • be installed during the build process, or
  • be included in a custom Docker image used by CodeBuild.

Installing the SDK within the build is suitable for initial setup and testing, while using a custom image is recommended for production environments to reduce build time.

Build Output

After a successful build:

  • MASSTCLI completes the integration process.
  • Generated artifacts are uploaded to the configured S3 bucket.
  • Build logs are available in the AWS CodeBuild console for troubleshooting.