CI/CD Integration
Shield runs as part of your standard Gradle build, so integrating it into CI/CD pipelines requires only adding the project token as a secret and ensuring internet connectivity during builds.
Prerequisites
- Shield configured in your project (see Gradle Setup)
- Project token stored as a CI/CD secret (never hardcode it in your repository)
- Internet access during the build (Shield validates the license with ByteHide cloud)
GitHub Actions
# .github/workflows/release.yml
name: Release Build
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- name: Build Release APK
env:
BYTEHIDE_PROJECT_TOKEN: ${{ secrets.BYTEHIDE_PROJECT_TOKEN }}
run: ./gradlew assembleRelease
- name: Upload APK
uses: actions/upload-artifact@v4
with:
name: release-apk
path: app/build/outputs/apk/release/*.apk# .github/workflows/release.yml
name: Release Build
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- name: Build Release APK
env:
BYTEHIDE_PROJECT_TOKEN: ${{ secrets.BYTEHIDE_PROJECT_TOKEN }}
run: ./gradlew assembleRelease
- name: Upload APK
uses: actions/upload-artifact@v4
with:
name: release-apk
path: app/build/outputs/apk/release/*.apkAdd BYTEHIDE_PROJECT_TOKEN in Settings → Secrets and variables → Actions → New repository secret.
GitLab CI
# .gitlab-ci.yml
stages:
- build
build-release:
stage: build
image: openjdk:17-jdk
variables:
BYTEHIDE_PROJECT_TOKEN: $BYTEHIDE_PROJECT_TOKEN
before_script:
- export GRADLE_USER_HOME=$(pwd)/.gradle
script:
- ./gradlew assembleRelease
artifacts:
paths:
- app/build/outputs/apk/release/*.apk
cache:
paths:
- .gradle/# .gitlab-ci.yml
stages:
- build
build-release:
stage: build
image: openjdk:17-jdk
variables:
BYTEHIDE_PROJECT_TOKEN: $BYTEHIDE_PROJECT_TOKEN
before_script:
- export GRADLE_USER_HOME=$(pwd)/.gradle
script:
- ./gradlew assembleRelease
artifacts:
paths:
- app/build/outputs/apk/release/*.apk
cache:
paths:
- .gradle/Add BYTEHIDE_PROJECT_TOKEN in Settings → CI/CD → Variables.
Bitrise
Add a Script step before your Android Build step:
envman add --key BYTEHIDE_PROJECT_TOKEN --value "$BYTEHIDE_PROJECT_TOKEN"envman add --key BYTEHIDE_PROJECT_TOKEN --value "$BYTEHIDE_PROJECT_TOKEN"Add BYTEHIDE_PROJECT_TOKEN as a secret in Workflow → Secrets.
Token Configuration
In your build.gradle, reference the token from the environment:
shield {
projectToken = System.getenv('BYTEHIDE_PROJECT_TOKEN')
}shield {
projectToken = System.getenv('BYTEHIDE_PROJECT_TOKEN')
}This pattern works in all CI/CD systems. The token is never committed to the repository.
Caching
Shield does not produce cacheable intermediate artifacts. However, caching the Gradle wrapper and dependencies speeds up builds significantly:
GitHub Actions
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3The gradle/actions/setup-gradle action handles caching automatically.
GitLab CI
cache:
paths:
- .gradle/cache:
paths:
- .gradle/CLI Integration (Direct JAR Protection)
Instead of using the Gradle plugin, you can run Shield CLI directly on the .jar output in your pipeline. This is useful for non-Gradle projects, custom build systems, or when you want to protect an already-built artifact:
GitHub Actions
- name: Build JAR
run: ./gradlew build
- name: Download Shield CLI
run: curl -O https://repo1.maven.org/maven2/com/bytehide/shield/shield-java-cli/1.1.5/shield-java-cli-1.1.5.jar
- name: Protect JAR with Shield
env:
BYTEHIDE_PROJECT_TOKEN: ${{ secrets.BYTEHIDE_PROJECT_TOKEN }}
run: java -jar shield-java-cli-1.1.5.jar -c shield-config.json- name: Build JAR
run: ./gradlew build
- name: Download Shield CLI
run: curl -O https://repo1.maven.org/maven2/com/bytehide/shield/shield-java-cli/1.1.5/shield-java-cli-1.1.5.jar
- name: Protect JAR with Shield
env:
BYTEHIDE_PROJECT_TOKEN: ${{ secrets.BYTEHIDE_PROJECT_TOKEN }}
run: java -jar shield-java-cli-1.1.5.jar -c shield-config.jsonCreate a shield-config.json in your repository:
{
"projectToken": "${BYTEHIDE_PROJECT_TOKEN}",
"inputJars": ["build/libs/my-app.jar"],
"outputJar": "build/libs/my-app-protected.jar",
"protections": {
"StringEncryption": true,
"ConstantMutation": true,
"DebugInfoRemoval": true,
"ControlFlowMatrix": true,
"NameObfuscation": true,
"ReferenceProxy": true
},
"renameMode": "LETTERS",
"excludedPackages": ["com.example.api"]
}{
"projectToken": "${BYTEHIDE_PROJECT_TOKEN}",
"inputJars": ["build/libs/my-app.jar"],
"outputJar": "build/libs/my-app-protected.jar",
"protections": {
"StringEncryption": true,
"ConstantMutation": true,
"DebugInfoRemoval": true,
"ControlFlowMatrix": true,
"NameObfuscation": true,
"ReferenceProxy": true
},
"renameMode": "LETTERS",
"excludedPackages": ["com.example.api"]
}This approach gives you access to all 9 protections (including ReferenceProxy and ResourceProtection which are CLI/JSON-only) and full control over advanced options. See CLI Reference for the complete configuration guide.
Build Artifacts
After a successful build with Shield, the protected APK or AAB is in the standard output directory:
| Build Type | Output Path |
|---|---|
| APK | app/build/outputs/apk/release/ |
| AAB | app/build/outputs/bundle/release/ |
The mapping file is also generated and uploaded to the ByteHide Cloud Panel automatically for stack trace deobfuscation.