diff --git a/unity-command/Dockerfile b/unity-command/Dockerfile index 084be27..526d14a 100644 --- a/unity-command/Dockerfile +++ b/unity-command/Dockerfile @@ -1,11 +1,19 @@ #Arg is replaced with the desired Unity container. -ARG IMAGE=unityci/editor:2023.1.16f1-windows-mono-3 +ARG IMAGE=ubuntu:latest FROM ${IMAGE} +ARG DOCKER_VERSION=20.10.23 + RUN apt-get update RUN apt-get install -y software-properties-common apt-transport-https wget chromium-browser RUN add-apt-repository -y ppa:savoury1/chromium -RUN apt-get update && apt-get install -y chromium-browser +RUN apt-get update && \ + apt-get install -y chromium-browser && \ + apt-get install -y curl + +# Install Docker CLI (static binary - much cleaner) +RUN apt-get update && apt-get install -y curl +RUN curl -fsSL https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz | tar -xzf - --strip=1 -C /usr/local/bin docker/docker #ADD https://minio.studiowhy.net/hackmd/UnityBuilder /usr/local/bin/ COPY UnityBuilder /usr/local/bin/ @@ -15,10 +23,5 @@ COPY entrypoint.sh / RUN chmod +x /entrypoint.sh COPY scripts/. /scripts -# Commented out until better image selection is enabled. -# RUN --mount=type=secret,id=SERIAL \ -# --mount=type=secret,id=USERNAME \ -# --mount=type=secret,id=PASSWORD \ -# bash /scripts/activate_license.sh ENTRYPOINT ["/entrypoint.sh"] diff --git a/unity-command/acquire_lock.sh b/unity-command/acquire_lock.sh new file mode 100644 index 0000000..ec0ea7c --- /dev/null +++ b/unity-command/acquire_lock.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# Script to acquire a Docker-based lock for Unity image retagging +# Usage: acquire_lock.sh + +LOCK_NAME="$1" +TIMEOUT=10 +WAIT_TIME=0.2 +if [ -z "$LOCK_NAME" ]; then + echo "Error: LOCK_NAME parameter is required" + exit 1 +fi + +echo "Acquiring Docker lock '$LOCK_NAME' (timeout 10s)..." + +# First, wait for any existing lock to be released +START_TS=$(date +%s) +while docker image ls --format '{{.Repository}}:{{.Tag}}' | grep -qx "$LOCK_NAME"; do + NOW_TS=$(date +%s) + ELAPSED=$((NOW_TS - START_TS)) + if [ "$ELAPSED" -ge $TIMEOUT ]; then + echo "Lock '$LOCK_NAME' still held after ${ELAPSED}s; proceeding anyway." + break + fi + echo "Lock '$LOCK_NAME' is held by another job. Waiting $WAIT_TIME seconds... (${ELAPSED}s elapsed)" + sleep $WAIT_TIME +done + +# Now create our lock +docker pull hello-world +docker tag hello-world "$LOCK_NAME" +echo "Lock acquired: $LOCK_NAME" diff --git a/unity-command/action.yaml b/unity-command/action.yaml index ac1682a..fa9fd2a 100644 --- a/unity-command/action.yaml +++ b/unity-command/action.yaml @@ -57,18 +57,19 @@ runs: version: ${{ inputs.version }} platform: ${{ inputs.platform }} - name: "Pull Unity container." + id: lock run: | + LOCK_NAME="unity-lock:unity-lock" + echo "lockName=$LOCK_NAME" >> "$GITHUB_OUTPUT" + + # Acquire Docker lock for exclusive access to retag the static image + bash ${{ github.action_path }}/acquire_lock.sh "$LOCK_NAME" + + IMAGE_TAG="${{ inputs.imageTag }}" CONTAINER="${{ steps.getContainer.outputs.container }}" - - CACHED_CONTAINER="$CONTAINER-activated" - # Activate the license on build. - # DOCKER_BUILDKIT=1 \ - # SERIAL="${{ inputs.serial }}" USERNAME="${{ inputs.email }}" PASSWORD="${{ inputs.password }}" \ - # docker build --secret id=SERIAL,env=SERIAL --secret id=USERNAME,env=USERNAME --secret id=PASSWORD,env=PASSWORD \ - # -t $CACHED_CONTAINER --build-arg IMAGE=$CONTAINER ${{ github.action_path }} - docker build -t $CACHED_CONTAINER --build-arg IMAGE=$CONTAINER ${{ github.action_path }} - - docker tag $CACHED_CONTAINER ${{ inputs.imageTag }} + CACHED_CONTAINER="$CONTAINER-cached" + docker build -t "$CACHED_CONTAINER" --build-arg IMAGE="$CONTAINER" ${{ github.action_path }} + docker tag "$CACHED_CONTAINER" "$IMAGE_TAG" shell: bash - name: "Get Unity Command." id: command @@ -87,6 +88,7 @@ runs: SSH_PUBLIC_KEY: ${{ inputs.sshPublicKey }} SSH_PRIVATE_KEY: ${{ inputs.sshPrivateKey }} CATCH_ERRORS: ${{ inputs.catchErrors }} + LOCK_NAME: ${{ steps.lock.outputs.lockName }} with: serial: ${{ inputs.serial }} # serial: "activated" @@ -94,4 +96,11 @@ runs: password: ${{ inputs.password }} command: ${{ steps.command.outputs.command }} unityBuilder: ${{ inputs.unityBuilder }} + - name: "Release Unity Docker lock." + if: ${{ always() }} + run: | + LOCK_NAME="${{ steps.lock.outputs.lockName }}" + echo "Releasing Docker lock '$LOCK_NAME'..." + docker rmi "$LOCK_NAME" >/dev/null 2>&1 || true + shell: bash diff --git a/unity-command/entrypoint.sh b/unity-command/entrypoint.sh index b8df157..aa7a879 100644 --- a/unity-command/entrypoint.sh +++ b/unity-command/entrypoint.sh @@ -1,5 +1,17 @@ #!/bin/bash -SERIAL=$1; EMAIL=$2; PASSWORD=$3; COMMAND=$4; UNITY_BUILDER=$5 +# Accept either positional arguments or environment variables +SERIAL=${1:-$SERIAL} +EMAIL=${2:-$EMAIL} +PASSWORD=${3:-$PASSWORD} +COMMAND=${4:-$COMMAND} +UNITY_BUILDER=${5:-$UNITY_BUILDER} + +# Best-effort cleanup for any Docker lock created by the composite action. +if [[ -n "$LOCK_NAME" ]]; then + echo "Removing Docker lock '$LOCK_NAME'..." + docker rmi "$LOCK_NAME" >/dev/null 2>&1 || true +fi + DEFAULT_ARGS="-quit -logFile -" rm -rf $HOME/.config/unity3d @@ -29,7 +41,8 @@ RESULT=$? echo "Unity command exited with code: $RESULT" echo "::endgroup::" -echo "exitCode=$RESULT" >> "$GITHUB_OUTPUT" +# Uncomment if movingback to a docker action. +#echo "exitCode=$RESULT" >> "$GITHUB_OUTPUT" if [[ "$CATCH_ERRORS" != "true" ]]; then exit $RESULT diff --git a/unity-command/scripts/activate_license.sh b/unity-command/scripts/activate_license.sh index 03b215a..c46a961 100644 --- a/unity-command/scripts/activate_license.sh +++ b/unity-command/scripts/activate_license.sh @@ -18,6 +18,7 @@ check_path USERNAME check_path PASSWORD if [[ -z "$SERIAL" || -z "$USERNAME" || -z "$PASSWORD" ]]; then + echo "Warning: License activation skipped - missing credentials" exit 0 fi @@ -25,7 +26,16 @@ fi if [[ "$SERIAL" == "personal" ]]; then echo "Obtaining personal license for Unity..." UnityBuilder activate -i /usr/bin/unity-editor -u $USERNAME -p $PASSWORD + ACTIVATION_RESULT=$? else echo "Activating Unity License with serial number." unity-editor $DEFAULT_ARGS -serial $SERIAL -username $USERNAME -password $PASSWORD -fi \ No newline at end of file + ACTIVATION_RESULT=$? +fi + +if [[ $ACTIVATION_RESULT -ne 0 ]]; then + echo "ERROR: Unity license activation failed with exit code $ACTIVATION_RESULT" + exit $ACTIVATION_RESULT +fi + +echo "Unity license activated successfully" \ No newline at end of file diff --git a/unity-project-cached-artifacts/action.yaml b/unity-project-cached-artifacts/action.yaml index 4515a37..fe970d0 100644 --- a/unity-project-cached-artifacts/action.yaml +++ b/unity-project-cached-artifacts/action.yaml @@ -138,6 +138,16 @@ runs: fi shell: bash - name: "Upload Artifacts." + id: upload_artifacts + uses: https://github.com/ChristopherHX/gitea-upload-artifact@v4 + with: + name: "${{ steps.get_product_name.outputs.nameShort }}_${{ inputs.artifactSuffix }}" + path: "${{ steps.find_output_dir.outputs.fullPath }}" + if-no-files-found: error + compression-level: ${{ inputs.compressionLevel }} + continue-on-error: true + - name: "Retry Upload Artifacts (if failed)." + if: ${{ steps.upload_artifacts.outcome == 'failure' }} uses: https://github.com/ChristopherHX/gitea-upload-artifact@v4 with: name: "${{ steps.get_product_name.outputs.nameShort }}_${{ inputs.artifactSuffix }}" diff --git a/unity-project-cached/action.yaml b/unity-project-cached/action.yaml index b449171..01ea029 100644 --- a/unity-project-cached/action.yaml +++ b/unity-project-cached/action.yaml @@ -68,6 +68,7 @@ outputs: runs: using: "composite" steps: + # Note: I may want to add the platform input to the cache key in the future if I want to cache per-platform. Though this will use more space. - name: "Get full cache key and build command." id: command run: |