Repository navigation
CI CD Integration
Daisuke Tsukada edited this page Aug 26, 2025
·
1 revision
Integrate Unity Remote Server into your continuous integration and deployment pipelines.
.github/workflows/unity-build.yml:
name: Unity Build
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Start Unity with Remote Server
run: |
# Start Unity in batch mode with your project
$UNITY_PATH -batchmode \
-projectPath . \
-logFile - &
# Wait for Remote Server to be ready
while ! curl -s http://127.0.0.1:8787/health; do
echo "Waiting for Unity Remote Server..."
sleep 5
done
- name: Build Android
run: |
curl -X POST http://127.0.0.1:8787/build \
-H "Content-Type: application/json" \
-d '{
"platform": "android",
"outputPath": "Builds/game.apk"
}'
- name: Upload Build Artifacts
uses: actions/upload-artifact@v3
with:
name: android-build
path: Builds/game.apkname: Multi-Platform Build
on:
release:
types: [created]
jobs:
build:
strategy:
matrix:
platform: [android, ios, windows, mac, linux]
include:
- platform: android
output: game.apk
- platform: ios
output: ios-build
- platform: windows
output: game.exe
- platform: mac
output: game.app
- platform: linux
output: game.x86_64
runs-on: ${{ matrix.platform == 'mac' && 'macos-latest' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v3
- name: Setup Unity
uses: game-ci/unity-builder@v2
with:
unityVersion: 2022.3.10f1
- name: Install Remote Server Package
run: |
# Add package via manifest
jq '.dependencies += {"com.dsgarage.unity-remote-server": "https://github.com/dsgarage/UnityRemoteServer.git"}' \
Packages/manifest.json > tmp.json && mv tmp.json Packages/manifest.json
- name: Build ${{ matrix.platform }}
run: |
# Use the provided build script
./Scripts/unity-build.sh ${{ matrix.platform }} Builds/${{ matrix.output }}
- name: Upload ${{ matrix.platform }} Build
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.platform }}-build
path: Builds/${{ matrix.output }}Jenkinsfile:
pipeline {
agent any
environment {
UNITY_PATH = '/Applications/Unity/Hub/Editor/2022.3.10f1/Unity.app/Contents/MacOS/Unity'
PROJECT_PATH = "${WORKSPACE}"
REMOTE_SERVER = 'http://127.0.0.1:8787'
}
stages {
stage('Setup') {
steps {
sh 'git clean -fdx'
sh 'git checkout main'
sh 'git pull origin main'
}
}
stage('Start Unity') {
steps {
sh """
${UNITY_PATH} -batchmode \
-projectPath ${PROJECT_PATH} \
-logFile unity.log &
# Wait for Remote Server
for i in {1..60}; do
if curl -s ${REMOTE_SERVER}/health; then
echo "Unity Remote Server is ready"
break
fi
echo "Waiting for Unity... (\$i/60)"
sleep 5
done
"""
}
}
stage('Run Tests') {
steps {
sh """
curl -X POST ${REMOTE_SERVER}/test/run \
-H "Content-Type: application/json" \
-d '{"runAll": true}'
# Wait for tests to complete
sleep 30
# Get test results
curl ${REMOTE_SERVER}/test/results > test-results.json
"""
junit 'test-results.xml'
}
}
stage('Build') {
parallel {
stage('Android') {
steps {
sh './Scripts/unity-build.sh android Builds/game.apk'
archiveArtifacts 'Builds/game.apk'
}
}
stage('iOS') {
when {
expression { env.NODE_NAME == 'mac-agent' }
}
steps {
sh './Scripts/unity-build.sh ios Builds/ios'
archiveArtifacts 'Builds/ios/**/*'
}
}
}
}
stage('Deploy') {
when {
branch 'main'
}
steps {
// Deploy to app stores
sh 'fastlane deploy'
}
}
}
post {
always {
// Get Unity logs
sh 'curl ${REMOTE_SERVER}/errors > unity-errors.log'
archiveArtifacts 'unity-errors.log'
// Stop Unity
sh 'pkill -f Unity || true'
}
}
}.gitlab-ci.yml:
variables:
UNITY_VERSION: "2022.3.10f1"
UNITY_PATH: "/opt/Unity/Editor/Unity"
BUILD_NAME: "game"
stages:
- test
- build
- deploy
before_script:
- apt-get update && apt-get install -y curl jq
- |
# Start Unity with Remote Server
$UNITY_PATH -batchmode \
-projectPath . \
-logFile - &
UNITY_PID=$!
# Wait for server
for i in $(seq 1 60); do
if curl -s http://127.0.0.1:8787/health; then
echo "Remote Server ready"
break
fi
sleep 5
done
test:
stage: test
script:
- |
# Run unit tests
curl -X POST http://127.0.0.1:8787/test/run \
-H "Content-Type: application/json" \
-d '{"runAll": true}'
# Check for compilation errors
ERRORS=$(curl -s http://127.0.0.1:8787/errors?level=error)
if [ $(echo "$ERRORS" | jq '. | length') -gt 0 ]; then
echo "Compilation errors found:"
echo "$ERRORS" | jq '.'
exit 1
fi
artifacts:
reports:
junit: test-results.xml
build:android:
stage: build
script:
- ./Scripts/unity-build.sh android Builds/${BUILD_NAME}.apk
artifacts:
paths:
- Builds/${BUILD_NAME}.apk
expire_in: 1 week
build:ios:
stage: build
tags:
- mac
script:
- ./Scripts/unity-build.sh ios Builds/ios
artifacts:
paths:
- Builds/ios/
expire_in: 1 week
deploy:production:
stage: deploy
only:
- main
script:
- echo "Deploying to production..."
# Add deployment scripts hereDockerfile:
FROM unityci/editor:ubuntu-2022.3.10f1-android-1.0.1
# Install dependencies
RUN apt-get update && \
apt-get install -y \
curl \
jq \
git
# Copy project
COPY . /project
WORKDIR /project
# Install Unity Remote Server
RUN echo '{"dependencies":{"com.dsgarage.unity-remote-server":"https://github.com/dsgarage/UnityRemoteServer.git"}}' \
| jq -s '.[0] * .[1]' Packages/manifest.json - > tmp.json && \
mv tmp.json Packages/manifest.json
# Copy build scripts
COPY Scripts/ /scripts/
RUN chmod +x /scripts/*.sh
# Start script
COPY docker-entrypoint.sh /
RUN chmod +x /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]docker-entrypoint.sh:
#!/bin/bash
set -e
# Start Unity with Remote Server
echo "Starting Unity..."
xvfb-run --auto-servernum --server-args='-screen 0 640x480x24' \
unity-editor \
-projectPath /project \
-batchmode \
-nographics \
-logFile - &
# Wait for Remote Server
echo "Waiting for Remote Server..."
for i in $(seq 1 60); do
if curl -s http://127.0.0.1:8787/health; then
echo "Remote Server is ready!"
break
fi
sleep 5
done
# Execute command
exec "$@"Usage:
# Build Docker image
docker build -t unity-builder .
# Run build
docker run --rm \
-v $(pwd)/Builds:/project/Builds \
unity-builder \
/scripts/unity-build.sh android /project/Builds/game.apk.circleci/config.yml:
version: 2.1
orbs:
unity: game-ci/unity@1.0.0
jobs:
test-and-build:
machine:
image: ubuntu-2204:current
steps:
- checkout
- run:
name: Install Unity
command: |
# Install Unity Hub
wget -q -O- https://hub.unity3d.com/linux/keys/public | sudo apt-key add -
sudo sh -c 'echo "deb https://hub.unity3d.com/linux/repos/deb stable main" > /etc/apt/sources.list.d/unityhub.list'
sudo apt update && sudo apt install unityhub
# Install Unity version
unityhub install --version 2022.3.10f1 --module android
- run:
name: Start Unity with Remote Server
background: true
command: |
Unity -batchmode \
-projectPath . \
-logFile unity.log
- run:
name: Wait for Remote Server
command: |
for i in $(seq 1 60); do
if curl -s http://127.0.0.1:8787/health; then
echo "Server ready"
exit 0
fi
sleep 5
done
exit 1
- run:
name: Run Tests
command: |
python3 Scripts/unity-control.py compile --timeout 120
python3 Scripts/unity-control.py errors --level error
- run:
name: Build Android
command: |
./Scripts/unity-build.sh android Builds/game.apk
- store_artifacts:
path: Builds/game.apk
destination: android-build
workflows:
build-and-test:
jobs:
- test-and-build:
filters:
branches:
only:
- main
- developazure-pipelines.yml:
trigger:
branches:
include:
- main
- develop
pool:
vmImage: 'ubuntu-latest'
variables:
UNITY_VERSION: '2022.3.10f1'
UNITY_REMOTE_SERVER: 'http://127.0.0.1:8787'
stages:
- stage: Test
jobs:
- job: RunTests
steps:
- task: UnityBuildTask@3
inputs:
buildTarget: 'StandaloneLinux64'
unityVersion: $(UNITY_VERSION)
cmdArgs: '-batchmode -quit -runTests'
- script: |
# Check compilation errors
curl $(UNITY_REMOTE_SERVER)/errors?level=error > errors.json
if [ $(jq '. | length' errors.json) -gt 0 ]; then
echo "##vso[task.logissue type=error]Compilation errors found"
cat errors.json | jq '.'
exit 1
fi
displayName: 'Check Compilation Errors'
- stage: Build
dependsOn: Test
jobs:
- job: BuildAndroid
steps:
- script: |
chmod +x Scripts/unity-build.sh
./Scripts/unity-build.sh android $(Build.ArtifactStagingDirectory)/game.apk
displayName: 'Build Android'
- task: PublishBuildArtifacts@1
inputs:
pathtoPublish: '$(Build.ArtifactStagingDirectory)'
artifactName: 'android-build'
- stage: Deploy
dependsOn: Build
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- deployment: DeployToStore
environment: 'production'
strategy:
runOnce:
deploy:
steps:
- script: echo "Deploy to store"Always verify server is ready:
wait_for_server() {
local max_attempts=60
local attempt=0
while [ $attempt -lt $max_attempts ]; do
if curl -s http://127.0.0.1:8787/health > /dev/null; then
echo "Server is ready!"
return 0
fi
echo "Waiting for server... ($attempt/$max_attempts)"
sleep 5
((attempt++))
done
echo "Server failed to start"
return 1
}Check for compilation errors before building:
def check_compilation():
client = UnityRemoteClient()
# Wait for compilation
result = client.await_compile(timeout=300)
if not result.get('ok'):
raise Exception(f"Compilation failed: {result.get('error')}")
# Check for errors
errors = client.get_errors(level='error')
if errors:
print("Compilation errors found:")
for error in errors:
print(f" - {error['message']}")
raise Exception("Build aborted due to compilation errors")Build multiple platforms concurrently:
jobs:
build:
strategy:
matrix:
platform: [android, ios, windows]
runs-on: ${{ matrix.runner }}
steps:
- run: ./Scripts/unity-build.sh ${{ matrix.platform }} output.${{ matrix.ext }}Cache Unity Library folder:
- uses: actions/cache@v3
with:
path: Library
key: Library-${{ matrix.platform }}-${{ hashFiles('Assets/**', 'Packages/**', 'ProjectSettings/**') }}
restore-keys: |
Library-${{ matrix.platform }}-
Library-Send build status notifications:
notify_slack() {
local status=$1
local platform=$2
curl -X POST $SLACK_WEBHOOK \
-H 'Content-Type: application/json' \
-d "{
\"text\": \"Build $status for $platform\",
\"color\": \"$([[ $status == 'success' ]] && echo 'good' || echo 'danger')\"
}"
}- Check Unity license activation
- Verify Unity installation path
- Check available system resources
- Ensure Remote Server package is installed
- Check if port 8787 is available
- Review Unity logs for errors
- Check disk space
- Verify platform modules installed
- Review compilation errors
- Increase timeout values
- Optimize project size
- Use incremental builds