UNPKG

com.wallstop-studios.unity-helpers

Version:

Treasure chest of Unity developer tools

357 lines (234 loc) 15.7 kB
# Unity Devcontainer Licensing (Codespaces and Local Dev Containers) This guide explains how to configure Unity licensing for `scripts/unity/run-unity-docker.sh` in Codespaces and local dev containers. The script supports three paths: 1. Personal online activation (`UNITY_EMAIL` + `UNITY_PASSWORD`) 2. Manual `.ulf` activation (`UNITY_LICENSE`) for serial-based licenses 3. Pro serial activation (`UNITY_SERIAL` + `UNITY_EMAIL` + `UNITY_PASSWORD`) It also persists Unity license cache artifacts between container runs using: - `${UNITY_TEST_PROJECT_DIR}/.unity-license-cache/local-share-unity3d` -> `/root/.local/share/unity3d` - `${UNITY_TEST_PROJECT_DIR}/.unity-license-cache/config-unity3d` -> `/root/.config/unity3d` By default, this is under `/home/vscode/.unity-test-project/.unity-license-cache` in the devcontainer. You can override it with `UNITY_LICENSE_CACHE_DIR` if needed. ## Recommended Setup for Personal License Use online activation. Unity Personal does not support manual activation via `.alf` / `.ulf` upload. ### Codespaces Secrets Set up secrets in GitHub first: 1. Open the repository on GitHub. 2. Go to `Settings` -> `Secrets and variables`. 3. Choose `Codespaces` (for Codespaces-only secrets) or `Actions` (for repository-level secrets reused by workflows). 4. Select `New repository secret` and add each value below. Reference: [Managing encrypted secrets for your codespaces](https://docs.github.com/en/codespaces/managing-your-codespaces/managing-your-account-specific-secrets-for-github-codespaces) Codespaces injects these secrets as environment variables inside the devcontainer. `run-unity-docker.sh` reads them and forwards them into the Unity container via Docker `-e` flags. Resulting license artifacts are persisted in the cache mounts. Add these secrets: - `UNITY_EMAIL` - `UNITY_PASSWORD` ### Local Dev Container Use one of these methods: - Export environment variables before running scripts. - Use `scripts/unity/setup-license.ps1` to generate `.unity-secrets/credentials.env`. `run-unity-docker.sh` auto-loads `.unity-secrets/credentials.env` when environment variables are not already set. ## Recommended Setup for Pro License Set all of these values: - `UNITY_SERIAL` - `UNITY_EMAIL` - `UNITY_PASSWORD` For Pro, `UNITY_SERIAL` is required. If serial credentials are incomplete, the script fails early with a clear error. ## Activation Behavior and Fallback Rules For Personal online activation: 1. Script attempts online activation with `UNITY_EMAIL` and `UNITY_PASSWORD`. 2. Script classifies failures as either hard licensing rejection or transient/network failure. 3. For hard rejection (for example `Found 0 entitlement groups`, `com.unity.editor.headless was not found`, invalid credentials), script fails fast. 4. If Unity reports `No license activation found for this computer` or `No ULF license found`, the script surfaces that as a machine-registration problem and stops. Unity Personal cannot recover through manual `.alf` upload. 5. If activation is still not successful, script exits with an actionable error. For manual `.ulf` activation: 1. This path is only for serial-based licenses. 2. The `.ulf` file must be generated for the same machine identity. 3. `UNITY_LICENSE` can be loaded from the environment or `.unity-secrets/license.ulf`. For all activation methods, script verifies that at least one local license artifact exists before running Unity commands. ## Post-Activation Verification The script checks for at least one of these files: - `/root/.local/share/unity3d/Unity/Unity_lic.ulf` - `/root/.config/unity3d/Unity/Unity_lic.ulf` - `/root/.local/share/unity3d/Unity/UnityEntitlementLicense.xml` - `/root/.config/unity3d/Unity/UnityEntitlementLicense.xml` If none exists, the script fails early and points to this guide. For personal online activation, the script also persists the raw activation log under: - `/root/.config/unity3d/.activation-<timestamp>.log` Because `/root/.config/unity3d` is mounted from host cache, that log persists and can be attached to support tickets. ## Entitlement Mismatch Symptoms If the account does not have a compatible entitlement for the requested activation path, Unity logs often contain: - `Found 0 entitlement groups` - `No valid Unity Editor license found` Typical causes: - Wrong Unity account for your organization/license. - Personal account trying a Pro-only entitlement path. - Expired or unavailable entitlement. Actions: 1. Verify the Unity account can activate the expected license type. 2. If using Personal, do not switch to manual activation; Unity Hub is the only supported activation path. 3. If using Pro, verify `UNITY_SERIAL`, `UNITY_EMAIL`, and `UNITY_PASSWORD` together. 4. Re-run the script and confirm license artifacts are created in the mounted cache paths. ## Headless Mode Notes For editor automation in CI/devcontainers, this repo already runs Unity with: - `-batchmode` - `-nographics` - `-quit` Those are the correct headless command-line flags for non-interactive workflows. There is no required "headless toggle" in the Unity dashboard for this script path; errors like `Found 0 entitlement groups` indicate a licensing-service decision for the current account/machine activation, not missing CLI flags. If you see these errors: ```text Found 0 entitlement groups and 0 free entitlements matching requested entitlement ids Error: 'com.unity.editor.headless' was not found. ``` the issue is usually Unity licensing state for this account/machine combination, not missing command-line flags. ### Dedicated Server vs Editor Automation - Dedicated Server build target is for built player binaries. - This repo is running `unity-editor` in headless mode for compile/test automation. - So Dedicated Server target does not replace editor license activation requirements. ### What To Do Instead 1. Keep using `-batchmode -nographics -quit` (already done in scripts). 2. Ensure credentials are correct (`UNITY_EMAIL`, `UNITY_PASSWORD`). 3. If using a serial-based `.ulf`, regenerate it for the same machine context (see next section). 4. If Unity still returns `Found 0 entitlement groups` or `com.unity.editor.headless`, open a Unity support ticket and include full activation logs. ### Why This Matters Headless flags control runtime/editor behavior, but license acceptance is still validated by Unity services. When services return no usable activation, local cache never gets populated and subsequent runs fail. ## Important: ULF Files are Machine-Specific `.ulf` license files are **encrypted with machine-specific hardware identifiers**. ### Why ULF Fallback Fails with "Machine bindings don't match" If you see this error: ```text Machine bindings don't match ``` Your `.ulf` file was generated on a different machine or with different hardware. ULF files cannot be ported across: - Different computers - Different Docker containers (each container is a unique "machine") - Different Codespaces instances ### What to Do **For local dev containers**: Use online activation (`UNITY_EMAIL` + `UNITY_PASSWORD`) instead. Once successful, the license artifact is cached and persists across container rebuilds. **For Codespaces**: Store `UNITY_EMAIL` and `UNITY_PASSWORD` in GitHub Secrets. Each Codespaces instance will regenerate the license on first run. **Generating new ULF files**: If you absolutely need a `.ulf` file for a serial-based license: 1. Generate an `.alf` with `npm run unity:generate-activation` 2. Complete Unity's manual activation flow with your serial 3. That `.ulf` will only work on this specific machine Unity Personal cannot use this manual activation path. ### Understanding the ULF Fallback Logic The script can consume a `.ulf` file when one is provided. **This should only succeed if:** 1. The `.ulf` was just generated moments ago in a _previous_ Docker run on _this machine_ 2. The Docker container still has the same hardware ID (unlikely after rebuild) In practice, ULF fallback will almost always fail with "Machine bindings don't match" if: - You're using `.ulf` from a different dev machine - You're trying `.ulf` in a new Codespaces instance - You rebuilt the devcontainer (new container = new machine binding) For Unity Personal, focus on online activation instead. Manual activation is not supported. ### Why Online Activation is Recommended Online activation (email + password) is superior because: - It generates a machine-specific license inside the container each time - The license artifact is automatically cached between runs - After first successful activation, subsequent runs don't re-authenticate - Persists across Docker image rebuilds (cache is preserved) - Works identically in Codespaces, CI/CD, and local dev containers ## Machine Not Registered ### When This Happens If Unity logs contain either of these messages: ```text No license activation found for this computer No ULF license found ``` the current machine identity is not registered with your Unity account. This typically occurs on first run in a new Docker container or Codespaces instance when online activation cannot issue a license for the current machine. ### If You Are Using Unity Personal Unity's current licensing docs state that manual activation does not work with Unity Personal. In this repo, `run-unity-docker.sh` treats this as a stop condition and points you back to supported options: 1. Activate through Unity Hub on a supported interactive machine. 2. If you already have a machine-matched `.ulf` from a serial-based manual activation, place it at `.unity-secrets/license.ulf`. 3. If this is unexpected for a Personal account, attach the saved activation log to a Unity support request. ### Manual Activation Workflow for Serial-Based Licenses Only If you are using a paid license with a serial key, this repo still supports manual activation: 1. **The `.alf` file is automatically placed at** `.unity-secrets/manual-activation.alf`. 2. **Upload it** at <https://license.unity3d.com/manual> (log in with your Unity account). 3. **Enter your serial** in Unity's manual activation flow, then download the `.ulf` file and save it as `.unity-secrets/license.ulf`. 4. **Run**: `npm run unity:retry-license` ### Dedicated Generation Command If for any reason the `.alf` was not auto-generated (for example, if the run was interrupted), generate it explicitly: ```bash npm run unity:generate-activation ``` This runs `scripts/unity/generate-activation.sh`, which requires `UNITY_SERIAL`, spins up a Docker container, calls `-createManualActivationFile`, and copies the result to `.unity-secrets/manual-activation.alf`. ### Retry Command After placing `.unity-secrets/license.ulf`, run: ```bash npm run unity:retry-license ``` `scripts/unity/retry-license.sh`: - Validates that `.unity-secrets/license.ulf` is present. - Clears stale cached license artifacts so Unity re-reads the new file. - Re-runs `compile.sh` with the new license loaded. ## Quick Troubleshooting Checklist 1. **Check for licensing-state errors**: If output contains `Found 0 entitlement groups` or `com.unity.editor.headless not found`, capture full logs and treat it as a Unity licensing-service/account-machine issue. 2. Confirm secrets/env vars are present in the shell running the script. 3. Confirm `.unity-secrets/credentials.env` and `.unity-secrets/license.ulf` are present if using file-based loading. 4. Check script output for entitlement mismatch strings. 5. **Verify credentials persist**: After first successful activation, run `ls -la ~/.unity-test-project/.unity-license-cache/` to confirm cache artifacts exist. 6. **For Docker image rebuilds**: If you rebuild the devcontainer, the cache persists but `post-create.sh` fixes permissions automatically on next run. 7. Confirm `.unity-test-project/.unity-license-cache/` directories are writable. 8. If output contains `No license activation found for this computer` or `No ULF license found`, treat it as a machine-registration problem. For Unity Personal, do not use manual activation; for serial-based licenses, follow the [Machine Not Registered](#machine-not-registered) section. ### Quick Validation with npm Script Before running expensive Docker operations, validate your setup quickly: ```bash npm run unity:validate ``` This script checks (without Docker): - ✓ Credentials are available (env vars or `.unity-secrets/`) - ✓ License files exist and are readable - ✓ Cache directory is writable - ✓ Docker daemon is running - ✓ Required scripts are in place It provides clear output showing what's missing and next steps. Additional scripts for manual activation: - `npm run unity:generate-activation` — generates `.unity-secrets/manual-activation.alf` for serial-based manual activation workflows. - `npm run unity:retry-license` — validates `.unity-secrets/license.ulf` is present, clears stale cached artifacts, and re-runs the compile command for serial-based manual activation. ### Manual Troubleshooting Steps If `npm run unity:validate` passes but compilation still fails, try: ```bash bash scripts/unity/run-unity-docker.sh -batchmode -nographics -quit -projectPath /project -logFile - ``` ## Credential Persistence Across Docker Rebuilds When you rebuild the devcontainer: 1. The devcontainer is stopped and a new one is built from scratch 2. **Your credentials (`UNITY_EMAIL`, `UNITY_PASSWORD`) are preserved** in `.unity-secrets/credentials.env` 3. **Your license cache is preserved** in `/home/vscode/.unity-test-project/.unity-license-cache/` (Docker persistent volume) 4. The `post-create.sh` script runs automatically and fixes directory permissions 5. Next compilation run: - Loads credentials from `.unity-secrets/credentials.env` - Mounts the persistent cache into the new container - Reuses the cached license artifact (no re-authentication needed) - If cache is empty, performs fresh online activation on first run **This means**: After successful first-time activation, subsequent compilations **reuse the cached license without re-authenticating**, greatly reducing startup overhead. Network access is still used to validate the license is still active, but you won't experience multiple authentication prompts. ### What Persists vs. What Doesn't | Item | Persists? | Details | | --------------------------------------------- | --------- | --------------------------------------------------- | | `.unity-secrets/credentials.env` | ✓ Yes | Kept in workspace .gitignore, survives all rebuilds | | `.unity-license-cache/` directory | ✓ Yes | Docker persistent volume, survives rebuilds | | License artifact files (.ulf / .xml) | ✓ Yes | Stored in persistent cache volume | | `/root/.local/share/unity3d` inside container | ✗ No | Recreated from persistent volume on each Docker run | | Docker image layers | ✗ No | Rebuilt each time, but cached locally | **Key takeaway**: **Credentials and cache both persist, enabling fast reuse** ### If Cache Doesn't Persist If you see `Token not found in cache` repeatedly: 1. First activation likely failed silently (check for entitlement errors above) 2. Run `ls -la ~/.unity-test-project/.unity-license-cache/` to check if any artifacts exist 3. If cache is empty, verify credentials are correct and regenerate machine-matched activation data 4. Delete cache and retry: `rm -rf ~/.unity-test-project/.unity-license-cache/` 5. Rerun compilation and check full output for error messages