CI/CD Integration¶
Integrate Totis CLI into your continuous integration and deployment pipelines to automatically upload builds.
Environment Variables¶
Set these environment variables in your CI/CD system:
| Variable | Description |
|---|---|
TOTIS_SERVER_URL |
Totis API URL |
TOTIS_CLIENT_ID |
Service account client ID |
TOTIS_CLIENT_SECRET |
Service account client secret |
GitHub Actions¶
Basic Workflow¶
name: Build and Upload
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Application
run: ./build.sh
- name: Install Totis CLI
run: |
curl -L https://github.com/gameforgelabs/totis/releases/latest/download/totis-linux-amd64 -o totis
chmod +x totis
sudo mv totis /usr/local/bin/
- name: Upload to Totis
env:
TOTIS_SERVER_URL: ${{ secrets.TOTIS_URL }}
run: |
totis auth login \
--client-id "${{ secrets.TOTIS_CLIENT_ID }}" \
--client-secret "${{ secrets.TOTIS_CLIENT_SECRET }}"
totis build create \
--workspace "${{ vars.WORKSPACE_SLUG }}" \
--project "${{ vars.PROJECT_SLUG }}" \
--version "${GITHUB_REF_NAME#v}" \
--name "Release ${GITHUB_REF_NAME}" \
--platform ANDROID \
--type RELEASE \
--commit "${{ github.sha }}" \
--branch "${{ github.ref_name }}" \
--ci-url "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
--tag production \
--tag "${{ github.ref_name }}" \
--file ./app/build/outputs/apk/release/app-release.apk
Android Build with Multiple Artifacts¶
name: Android Release
on:
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Build Release APK
run: ./gradlew assembleRelease
- name: Upload to Totis
env:
TOTIS_SERVER_URL: ${{ secrets.TOTIS_URL }}
run: |
# Install CLI
curl -sL https://github.com/gameforgelabs/totis/releases/latest/download/totis-linux-amd64 -o totis
chmod +x totis && sudo mv totis /usr/local/bin/
# Authenticate
totis auth login \
--client-id "${{ secrets.TOTIS_CLIENT_ID }}" \
--client-secret "${{ secrets.TOTIS_CLIENT_SECRET }}"
# Upload build with all APK variants
totis build create \
--workspace my-company \
--project my-android-app \
--version "${{ github.event.release.tag_name }}" \
--name "${{ github.event.release.name }}" \
--platform ANDROID \
--type RELEASE \
--commit "${{ github.sha }}" \
--notes "${{ github.event.release.body }}" \
--tag release \
--tag "${{ github.event.release.tag_name }}" \
--file ./app/build/outputs/apk/release/app-arm64-v8a-release.apk \
--file ./app/build/outputs/apk/release/app-armeabi-v7a-release.apk \
--file ./app/build/outputs/apk/release/app-x86_64-release.apk \
--file ./app/build/outputs/mapping/release/mapping.txt
GitLab CI¶
stages:
- build
- upload
build:
stage: build
script:
- ./build.sh
artifacts:
paths:
- build/output/
upload:
stage: upload
image: golang:1.21
variables:
TOTIS_SERVER_URL: ${TOTIS_URL}
script:
- go install github.com/gameforgelabs/totis@latest
- |
totis auth login \
--client-id "${TOTIS_CLIENT_ID}" \
--client-secret "${TOTIS_CLIENT_SECRET}"
- |
totis build create \
--workspace "${WORKSPACE_SLUG}" \
--project "${PROJECT_SLUG}" \
--version "${CI_COMMIT_TAG}" \
--name "Build ${CI_PIPELINE_ID}" \
--platform ANDROID \
--type CI \
--commit "${CI_COMMIT_SHA}" \
--branch "${CI_COMMIT_REF_NAME}" \
--ci-url "${CI_PIPELINE_URL}" \
--tag ci \
--tag "${CI_COMMIT_REF_NAME}" \
--file ./build/output/app-release.apk
only:
- tags
Jenkins¶
Pipeline Script¶
pipeline {
agent any
environment {
TOTIS_SERVER_URL = credentials('totis-url')
TOTIS_CLIENT_ID = credentials('totis-client-id')
TOTIS_CLIENT_SECRET = credentials('totis-client-secret')
}
stages {
stage('Build') {
steps {
sh './gradlew assembleRelease'
}
}
stage('Upload to Totis') {
steps {
sh '''
# Install Totis CLI
curl -sL https://github.com/gameforgelabs/totis/releases/latest/download/totis-linux-amd64 -o totis
chmod +x totis
# Authenticate
./totis auth login \
--client-id "${TOTIS_CLIENT_ID}" \
--client-secret "${TOTIS_CLIENT_SECRET}"
# Create build and upload
./totis build create \
--workspace my-company \
--project my-app \
--version "${BUILD_NUMBER}" \
--name "Build #${BUILD_NUMBER}" \
--platform ANDROID \
--type CI \
--commit "${GIT_COMMIT}" \
--branch "${GIT_BRANCH}" \
--ci-url "${BUILD_URL}" \
--tag jenkins \
--tag "${GIT_BRANCH}" \
--file ./app/build/outputs/apk/release/app-release.apk
'''
}
}
}
}
CircleCI¶
version: 2.1
jobs:
build-and-upload:
docker:
- image: cimg/android:2024.01
steps:
- checkout
- run:
name: Build APK
command: ./gradlew assembleRelease
- run:
name: Install Totis CLI
command: |
curl -sL https://github.com/gameforgelabs/totis/releases/latest/download/totis-linux-amd64 -o totis
chmod +x totis
sudo mv totis /usr/local/bin/
- run:
name: Upload to Totis
command: |
totis auth login \
--client-id "${TOTIS_CLIENT_ID}" \
--client-secret "${TOTIS_CLIENT_SECRET}" \
--server "${TOTIS_URL}"
totis build create \
--workspace my-company \
--project my-app \
--version "1.0.${CIRCLE_BUILD_NUM}" \
--name "Build ${CIRCLE_BUILD_NUM}" \
--platform ANDROID \
--type CI \
--commit "${CIRCLE_SHA1}" \
--branch "${CIRCLE_BRANCH}" \
--ci-url "${CIRCLE_BUILD_URL}" \
--tag circleci \
--file ./app/build/outputs/apk/release/app-release.apk
workflows:
build:
jobs:
- build-and-upload:
filters:
branches:
only: main
Bitbucket Pipelines¶
pipelines:
tags:
'v*':
- step:
name: Build and Upload
image: openjdk:17
script:
- ./gradlew assembleRelease
# Install Totis CLI
- curl -sL https://github.com/gameforgelabs/totis/releases/latest/download/totis-linux-amd64 -o totis
- chmod +x totis
# Authenticate and upload
- ./totis auth login --client-id "$TOTIS_CLIENT_ID" --client-secret "$TOTIS_CLIENT_SECRET" --server "$TOTIS_URL"
- |
./totis build create \
--workspace my-company \
--project my-app \
--version "${BITBUCKET_TAG#v}" \
--name "Release ${BITBUCKET_TAG}" \
--platform ANDROID \
--type RELEASE \
--commit "${BITBUCKET_COMMIT}" \
--branch "${BITBUCKET_BRANCH}" \
--ci-url "https://bitbucket.org/${BITBUCKET_WORKSPACE}/${BITBUCKET_REPO_SLUG}/pipelines/results/${BITBUCKET_BUILD_NUMBER}" \
--tag release \
--file ./app/build/outputs/apk/release/app-release.apk
Best Practices¶
Secure Credential Storage¶
- Never commit credentials to version control
- Use your CI/CD platform's secret management
- Create dedicated service accounts for CI/CD
- Rotate credentials regularly
Error Handling¶
Use --continue-on-error for non-critical files:
totis build create \
--workspace my-company \
--project my-app \
--version 1.0.0 \
--name "Release" \
--file app.apk \
--file mapping.txt \
--file debug-symbols.zip \
--continue-on-error
Tagging Strategy¶
Use consistent tags for filtering:
| Tag | Purpose |
|---|---|
ci |
All CI builds |
release |
Production releases |
beta |
Beta releases |
{branch} |
Branch name |
{version} |
Version number |
Versioning¶
Extract version from your build system: