@@ -67,53 +67,123 @@ jobs:
6767 echo "No MCP Python deps found (skipping)"
6868 fi
6969
70- # --- Use game-ci for Unity activation (handles all license types) ---
71- - name : Activate Unity using game-ci
72- uses : game-ci/unity-activator@v2
70+ # --- Licensing: allow both ULF and EBL when available ---
71+ - name : Decide license sources
72+ id : lic
73+ shell : bash
7374 env :
75+ UNITY_LICENSE : ${{ secrets.UNITY_LICENSE }}
7476 UNITY_EMAIL : ${{ secrets.UNITY_EMAIL }}
7577 UNITY_PASSWORD : ${{ secrets.UNITY_PASSWORD }}
76- UNITY_LICENSE : ${{ secrets.UNITY_LICENSE }}
7778 UNITY_SERIAL : ${{ secrets.UNITY_SERIAL }}
78- with :
79- unity-version : 2021.3.45f2
79+ run : |
80+ set -eu
81+ use_ulf=false; use_ebl=false
82+ [[ -n "${UNITY_LICENSE:-}" ]] && use_ulf=true
83+ [[ -n "${UNITY_EMAIL:-}" && -n "${UNITY_PASSWORD:-}" ]] && use_ebl=true
84+ echo "use_ulf=$use_ulf" >> "$GITHUB_OUTPUT"
85+ echo "use_ebl=$use_ebl" >> "$GITHUB_OUTPUT"
86+ echo "has_serial=$([[ -n "${UNITY_SERIAL:-}" ]] && echo true || echo false)" >> "$GITHUB_OUTPUT"
87+
88+ - name : Stage Unity .ulf license (from secret)
89+ if : steps.lic.outputs.use_ulf == 'true'
90+ id : ulf
91+ env :
92+ UNITY_LICENSE : ${{ secrets.UNITY_LICENSE }}
93+ shell : bash
94+ run : |
95+ set -eu
96+ mkdir -p "$RUNNER_TEMP/unity-license-ulf" "$RUNNER_TEMP/unity-local/Unity"
97+ f="$RUNNER_TEMP/unity-license-ulf/Unity_lic.ulf"
98+ if printf "%s" "$UNITY_LICENSE" | base64 -d - >/dev/null 2>&1; then
99+ printf "%s" "$UNITY_LICENSE" | base64 -d - > "$f"
100+ else
101+ printf "%s" "$UNITY_LICENSE" > "$f"
102+ fi
103+ chmod 600 "$f" || true
104+ # If someone pasted an entitlement XML into UNITY_LICENSE by mistake, re-home it:
105+ if head -c 100 "$f" | grep -qi '<\?xml'; then
106+ mkdir -p "$RUNNER_TEMP/unity-config/Unity/licenses"
107+ mv "$f" "$RUNNER_TEMP/unity-config/Unity/licenses/UnityEntitlementLicense.xml"
108+ echo "ok=false" >> "$GITHUB_OUTPUT"
109+ elif grep -qi '<Signature>' "$f"; then
110+ # provide it in the standard local-share path too
111+ cp -f "$f" "$RUNNER_TEMP/unity-local/Unity/Unity_lic.ulf"
112+ echo "ok=true" >> "$GITHUB_OUTPUT"
113+ else
114+ echo "ok=false" >> "$GITHUB_OUTPUT"
115+ fi
80116
81- # Copy activation artifacts to Docker mount locations
82- - name : Prepare Unity license for Docker containers
117+ # --- Activate via EBL inside the same Unity image (writes host-side entitlement) ---
118+ - name : Activate Unity (EBL via container - host-mount)
119+ if : steps.lic.outputs.use_ebl == 'true'
83120 shell : bash
121+ env :
122+ UNITY_IMAGE : ${{ env.UNITY_IMAGE }}
123+ UNITY_EMAIL : ${{ secrets.UNITY_EMAIL }}
124+ UNITY_PASSWORD : ${{ secrets.UNITY_PASSWORD }}
125+ UNITY_SERIAL : ${{ secrets.UNITY_SERIAL }}
84126 run : |
85127 set -euxo pipefail
128+ # host dirs to receive the full Unity config and local-share
86129 mkdir -p "$RUNNER_TEMP/unity-config" "$RUNNER_TEMP/unity-local"
87130
88- # game-ci stores license files in standard Unity locations
89- # Copy them to our Docker mount points
90- if [ -d "$HOME/.local/share/unity3d" ]; then
91- cp -r "$HOME/.local/share/unity3d"/* "$RUNNER_TEMP/unity-local/" || true
92- fi
93- if [ -d "$HOME/.config/unity3d" ]; then
94- cp -r "$HOME/.config/unity3d"/* "$RUNNER_TEMP/unity-config/" || true
131+ # Try Pro first if serial is present, otherwise named-user EBL.
132+ docker run --rm --network host \
133+ -e HOME=/root \
134+ -e UNITY_EMAIL -e UNITY_PASSWORD -e UNITY_SERIAL \
135+ -v "$RUNNER_TEMP/unity-config:/root/.config/unity3d" \
136+ -v "$RUNNER_TEMP/unity-local:/root/.local/share/unity3d" \
137+ "$UNITY_IMAGE" bash -lc '
138+ set -euxo pipefail
139+ if [[ -n "${UNITY_SERIAL:-}" ]]; then
140+ /opt/unity/Editor/Unity -batchmode -nographics -logFile - \
141+ -username "$UNITY_EMAIL" -password "$UNITY_PASSWORD" -serial "$UNITY_SERIAL" -quit || true
142+ else
143+ /opt/unity/Editor/Unity -batchmode -nographics -logFile - \
144+ -username "$UNITY_EMAIL" -password "$UNITY_PASSWORD" -quit || true
145+ fi
146+ ls -la /root/.config/unity3d/Unity/licenses || true
147+ '
148+
149+ # Verify entitlement written to host mount; allow ULF-only runs to proceed
150+ if ! find "$RUNNER_TEMP/unity-config" -type f -iname "*.xml" | grep -q .; then
151+ if [[ "${{ steps.ulf.outputs.ok }}" == "true" ]]; then
152+ echo "EBL entitlement not found; proceeding with ULF-only (ok=true)."
153+ else
154+ echo "No entitlement produced and no valid ULF; cannot continue." >&2
155+ exit 1
156+ fi
95157 fi
96158
97- # Verify license files exist
98- echo "Unity license files prepared:"
99- find "$RUNNER_TEMP/unity-local" -type f || true
100- find "$RUNNER_TEMP/unity-config" -type f || true
159+ # EBL entitlement is already written directly to $RUNNER_TEMP/unity-config by the activation step
101160
102161 # ---------- Warm up project (import Library once) ----------
103162 - name : Warm up project (import Library once)
104- if : steps.detect .outputs.unity_ok == 'true'
163+ if : steps.lic .outputs.use_ulf == 'true' || steps.lic.outputs.use_ebl == 'true'
105164 shell : bash
106165 env :
107166 UNITY_IMAGE : ${{ env.UNITY_IMAGE }}
167+ ULF_OK : ${{ steps.ulf.outputs.ok }}
168+ UNITY_EMAIL : ${{ secrets.UNITY_EMAIL }}
169+ UNITY_PASSWORD : ${{ secrets.UNITY_PASSWORD }}
170+ UNITY_LICENSE : ${{ secrets.UNITY_LICENSE }}
108171 run : |
109172 set -euxo pipefail
173+ manual_args=()
174+ if [[ "${ULF_OK:-false}" == "true" ]]; then
175+ manual_args=(-manualLicenseFile "/root/.local/share/unity3d/Unity/Unity_lic.ulf")
176+ fi
110177 docker run --rm --network host \
111178 -e HOME=/root \
179+ -e UNITY_EMAIL="${UNITY_EMAIL:-}" \
180+ -e UNITY_PASSWORD="${UNITY_PASSWORD:-}" \
112181 -v "${{ github.workspace }}:/workspace" -w /workspace \
113182 -v "$RUNNER_TEMP/unity-config:/root/.config/unity3d" \
114183 -v "$RUNNER_TEMP/unity-local:/root/.local/share/unity3d" \
115184 "$UNITY_IMAGE" /opt/unity/Editor/Unity -batchmode -nographics -logFile - \
116185 -projectPath /workspace/TestProjects/UnityMCPTests \
186+ "${manual_args[@]}" \
117187 -quit
118188
119189 # ---------- Clean old MCP status ----------
@@ -125,16 +195,27 @@ jobs:
125195
126196 # ---------- Start headless Unity (persistent bridge) ----------
127197 - name : Start Unity (persistent bridge)
128- if : steps.detect .outputs.unity_ok == 'true'
198+ if : steps.lic .outputs.use_ulf == 'true' || steps.lic.outputs.use_ebl == 'true'
129199 shell : bash
130200 env :
131201 UNITY_IMAGE : ${{ env.UNITY_IMAGE }}
202+ ULF_OK : ${{ steps.ulf.outputs.ok }}
203+ UNITY_EMAIL : ${{ secrets.UNITY_EMAIL }}
204+ UNITY_PASSWORD : ${{ secrets.UNITY_PASSWORD }}
205+ UNITY_LICENSE : ${{ secrets.UNITY_LICENSE }}
132206 run : |
133207 set -euxo pipefail
208+ manual_args=()
209+ if [[ "${ULF_OK:-false}" == "true" ]]; then
210+ manual_args=(-manualLicenseFile "/root/.local/share/unity3d/Unity/Unity_lic.ulf")
211+ fi
212+
134213 mkdir -p "$RUNNER_TEMP/unity-status"
135214 docker rm -f unity-mcp >/dev/null 2>&1 || true
136215 docker run -d --name unity-mcp --network host \
137216 -e HOME=/root \
217+ -e UNITY_EMAIL="${UNITY_EMAIL:-}" \
218+ -e UNITY_PASSWORD="${UNITY_PASSWORD:-}" \
138219 -e UNITY_MCP_ALLOW_BATCH=1 \
139220 -e UNITY_MCP_STATUS_DIR=/root/.unity-mcp \
140221 -e UNITY_MCP_BIND_HOST=127.0.0.1 \
@@ -145,6 +226,7 @@ jobs:
145226 "$UNITY_IMAGE" /opt/unity/Editor/Unity -batchmode -nographics -logFile - \
146227 -stackTraceLogType Full \
147228 -projectPath /workspace/TestProjects/UnityMCPTests \
229+ "${manual_args[@]}" \
148230 -executeMethod MCPForUnity.Editor.MCPForUnityBridge.StartAutoConnect
149231
150232 # ---------- Wait for Unity bridge ----------
@@ -885,7 +967,7 @@ jobs:
885967 docker rm -f unity-mcp || true
886968
887969 - name : Return Pro license (if used)
888- if : always()
970+ if : always() && steps.lic.outputs.use_ebl == 'true' && steps.lic.outputs.has_serial == 'true'
889971 uses : game-ci/unity-return-license@v2
890972 continue-on-error : true
891973 env :
0 commit comments