.github/workflows/docker.yml
name: Docker
on:
workflow_dispatch:
push:
paths-ignore:
- '*'
- '**/**'
- '!.github/workflows/docker.yml'
- '!.github/macports.yml'
- '!app/third_party/conan/Native/**'
- '!deploy/Dockerfile*'
- '!scripts/install_dependencies.sh'
- '!scripts/compile_native.sh'
- '!scripts/helper_functions.sh'
- '!scripts/profile.sh'
- '!scripts/docker.sh'
- '!scripts/test/docker/dockerfile.sh'
- '!**/CMakeLists*'
- '!**/AndroidTest/resources/**'
- '!**/*.c*'
- '!**/*.h'
- '!**/*.hpp'
- '!**/*.ui*'
defaults:
run:
shell: sh
working-directory: .
concurrency:
group: ${{ github.workflow }} ${{ github.ref }}
cancel-in-progress: true
# Default environment variables.
env:
GITHUB_STEP_TIMEOUT_SMALL: 4
GITHUB_STEP_TIMEOUT_MEDIUM: 10
GITHUB_STEP_TIMEOUT_LONG: 20
jobs:
Build:
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
strategy:
fail-fast: false
matrix:
include:
- host_os: ubuntu-latest
BASE_IMAGE: ubuntu:24.04
- host_os: ubuntu-latest
BASE_IMAGE: tgagor/centos:stream9
- host_os: ubuntu-latest
BASE_IMAGE: archlinux/archlinux:base-devel
- host_os: ubuntu-latest
BASE_IMAGE: alpine:3.21.2
- host_os: ubuntu-latest
BASE_IMAGE: gentoo/stage3:latest
- host_os: windows-latest
BASE_IMAGE: mcr.microsoft.com/windows/servercore:ltsc2022
name: ${{ matrix.BASE_IMAGE }} (${{ matrix.host_os }})
runs-on: ${{ matrix.host_os }}
# Necessary timeout of +/- 300 min to be able to build MobileRT with gentoo.
# That's why we try to pull a previously available version and update it with a new layer instead.
timeout-minutes: 300
steps:
- name: Checkout
timeout-minutes: ${{ fromJSON(env.GITHUB_STEP_TIMEOUT_MEDIUM) }}
if: success()
uses: actions/checkout@v4
- name: Enable KVM group permissions
timeout-minutes: ${{ fromJSON(env.GITHUB_STEP_TIMEOUT_SMALL) }}
if: success() && startsWith(matrix.host_os, 'ubuntu')
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules;
sudo udevadm control --reload-rules;
sudo udevadm trigger --name-match=kvm;
- name: Add branch name and version to environment variables
timeout-minutes: ${{ fromJSON(env.GITHUB_STEP_TIMEOUT_SMALL) }}
if: success()
shell: bash
env:
BASE_IMAGE: ${{ matrix.BASE_IMAGE }}
run: |
export BRANCH=${GITHUB_REF#refs/heads/};
echo "BRANCH: ${BRANCH}";
echo "BRANCH=${BRANCH}" >> "${GITHUB_ENV}";
export VERSION="${BASE_IMAGE//\//-}";
export VERSION="${VERSION//:/-}";
echo "VERSION=${VERSION}" >> "${GITHUB_ENV}";
echo 'BUILD_IMAGE=yes' >> "${GITHUB_ENV}";
- name: Install MacPorts (MacOS 11)
timeout-minutes: ${{ fromJSON(env.GITHUB_STEP_TIMEOUT_MEDIUM) }}
if: success() && startsWith(matrix.host_os, 'macos-11')
uses: melusina-org/setup-macports@v1
with:
# Check available parameters in: https://github.com/melusina-org/setup-macports/blob/main/action.yaml
parameters: '.github/macports.yml'
- name: Install docker MacOS
timeout-minutes: ${{ fromJSON(env.GITHUB_STEP_TIMEOUT_LONG) }}
if: success() && startsWith(matrix.host_os, 'macos')
env:
BASE_IMAGE: ${{ matrix.BASE_IMAGE }}
run: |
# shellcheck disable=SC1091
. scripts/docker.sh && installDockerCommandForMacOS;
- name: Windows copy necessary tools to workspace
timeout-minutes: ${{ fromJSON(env.GITHUB_STEP_TIMEOUT_SMALL) }}
if: success() && env.BUILD_IMAGE == 'yes' && startsWith(matrix.host_os, 'windows')
shell: powershell
run: |
$ErrorActionPreference = 'Stop'
Write-Host "Copying shell binaries to workspace."
# where.exe sh
New-Item -Type dir .\\tools\\binariesShell
Copy-Item -Path "C:\\Program Files\\Git\\usr\\bin\\*" -Destination ".\\tools\\binariesShell" -Recurse
Write-Host "Copying resource compiler binaries to workspace."
# Get-ChildItem -Path "C:\\Program Files (x86)\\Windows Kits\\10\\bin" -Include rc.exe -File -Recurse -ErrorAction SilentlyContinue | ForEach-Object{$_.FullName}
New-Item -Type dir .\\tools\\binariesResourceCompiler
$windowsKitsVersion = Get-ChildItem -Path "C:\\Program Files (x86)\\Windows Kits\\10\\bin" | Where {$_.name -match "^[0-9\.]+$"} | Sort-Object -Descending | Select name | Select-Object -ExpandProperty Name | Select -first 1
Copy-Item -Path "C:\\Program Files (x86)\\Windows Kits\\10\\bin\\$windowsKitsVersion\\x64\\*" -Destination ".\\tools\\binariesResourceCompiler" -Recurse
- name: Set up Docker Buildx
timeout-minutes: ${{ fromJSON(env.GITHUB_STEP_TIMEOUT_SMALL) }}
if: success() && !startsWith(matrix.host_os, 'windows')
uses: docker/setup-buildx-action@v3
with:
# Check available parameters in: https://github.com/docker/setup-buildx-action/blob/master/action.yml
version: latest
platforms: linux/amd64
cache-binary: true
cleanup: false
- name: Login to DockerHub Registry
timeout-minutes: ${{ fromJSON(env.GITHUB_STEP_TIMEOUT_SMALL) }}
if: success()
uses: docker/login-action@v3
with:
# Check available parameters in: https://github.com/docker/login-action/blob/master/action.yml
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
ecr: false
logout: true
- name: Delete unnecessary Docker images
timeout-minutes: ${{ fromJSON(env.GITHUB_STEP_TIMEOUT_MEDIUM) }}
if: success()
run: |
baseImageRegex=$(echo "${{ matrix.BASE_IMAGE }}" | sed 's/:/.*/');
mobilertImageRegex=$(echo "mobile_rt.*${{ env.VERSION }}");
echo "baseImageRegex: ${baseImageRegex}";
echo "mobilertImageRegex: ${mobilertImageRegex}";
docker images -a;
docker images -a | grep GB | grep -v "${baseImageRegex}" | grep -v "${mobilertImageRegex}" | grep -v 'REPOSITORY' | head -1 | xargs docker rmi -f || true;
docker system prune --volumes --force;
docker images -a;
- name: Install Docker BuildKit & Buildx & build image Windows
timeout-minutes: 60
if: success() && env.BUILD_IMAGE == 'yes' && startsWith(matrix.host_os, 'windows') && false
shell: powershell
working-directory: .
run: |
$ErrorActionPreference = 'Stop'
$url = "https://api.github.com/repos/containerd/containerd/releases/latest"
$version = (Invoke-RestMethod -Uri $url -UseBasicParsing).tag_name
$version = $version -replace "v",""
$arch = "amd64" # arm64 also available
Write-Host "Downloading & extracting containerd $version - $arch"
curl.exe -LO https://github.com/containerd/containerd/releases/download/v$version/containerd-$version-windows-$arch.tar.gz
tar xvf .\containerd-$version-windows-$arch.tar.gz
Write-Host "Copy containerd Windows binaries."
Copy-Item -Path .\bin -Destination $Env:ProgramFiles\containerd -Recurse -Force
Write-Host "Add the binaries (containerd, ctr) in $env:Path."
$Path = [Environment]::GetEnvironmentVariable("PATH", "Machine") + [IO.Path]::PathSeparator + "$Env:ProgramFiles\containerd"
[Environment]::SetEnvironmentVariable( "Path", $Path, "Machine")
$Env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
Write-Host "Configuring containerd"
containerd config default | Out-File $Env:ProgramFiles\containerd\config.toml -Encoding ascii
Get-Content $Env:ProgramFiles\containerd\config.toml
Write-Host "Register and start containerd service"
containerd --register-service
Start-Service containerd
Write-Host "Enable Containers and Microsoft-Hyper-V features."
Enable-WindowsOptionalFeature -Online -FeatureName $("Containers","Microsoft-Hyper-V","Microsoft-Windows-Subsystem-Linux","VirtualMachinePlatform") -All
$url = "https://api.github.com/repos/moby/buildkit/releases/latest"
$version = (Invoke-RestMethod -Uri $url -UseBasicParsing).tag_name
$version = $version -replace "v",""
$arch = "amd64" # arm64 binary available too
Write-Host "Downloading buildkit $version - $arch"
curl.exe -LO https://github.com/moby/buildkit/releases/download/v$version/buildkit-v$version.windows-$arch.tar.gz
Write-Host "Extracting buildkit."
tar xvf .\buildkit-v$version.windows-$arch.tar.gz
Write-Host "Listing buildkit files."
Copy-Item -Path ".\bin" -Destination "$Env:ProgramFiles\buildkit" -Recurse -Force
Write-Host "Adding `buildkitd` and `buildctl` binaries in the $Env:PATH"
$Path = [Environment]::GetEnvironmentVariable("PATH", "Machine") + `
[IO.Path]::PathSeparator + "$Env:ProgramFiles\buildkit"
Write-Host "Storing the Path variable"
[Environment]::SetEnvironmentVariable( "Path", $Path, "Machine")
echo "Path=$Path" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Write-Host "Checking Path variable"
$Env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + `
[System.Environment]::GetEnvironmentVariable("Path","User")
$url = "https://api.github.com/repos/docker/buildx/releases/latest"
$version = (Invoke-RestMethod -Uri $url -UseBasicParsing).tag_name
$version = $version -replace "v",""
$arch = "amd64"
Write-Host "Downloading buildx $version - $arch"
curl.exe -LO https://github.com/docker/buildx/releases/download/v$version/buildx-v$version.windows-$arch.exe
Write-Host "Copying buildx to C:\ProgramData\Docker\cli-plugins"
Copy-Item -Path "buildx-v$version.windows-$arch.exe" -Destination "C:\ProgramData\Docker\cli-plugins\docker-buildx.exe" -Force
$DOCKER_CLI_EXPERIMENTAL = "enabled"
$Env:DOCKER_CLI_EXPERIMENTAL = "enabled"
$DOCKER_BUILDKIT = "1"
$Env:DOCKER_BUILDKIT = "1"
$networkName = 'nat'
# Get-HnsNetwork is available once you have enabled the 'Hyper-V Host Compute Service' feature
# which must have been done at the Quick setup above
# Enable-WindowsOptionalFeature -Online -FeatureName containers -All
# Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All -All
# the default one named `nat` should be available
$natInfo = Get-HnsNetwork -ErrorAction Ignore | Where-Object { $_.Name -eq $networkName }
if ($null -eq $natInfo) {
throw "NAT network not found, check if you enabled containers, Hyper-V features and restarted the machine"
}
$gateway = $natInfo.Subnets[0].GatewayAddress
$subnet = $natInfo.Subnets[0].AddressPrefix
$cniConfPath = "$env:ProgramFiles\containerd\cni\conf\0-containerd-nat.conf"
$cniBinDir = "$env:ProgramFiles\containerd\cni\bin"
$cniVersion = "0.3.0"
# get the CNI plugins (binaries)
mkdir $cniBinDir -Force
curl.exe -LO https://github.com/microsoft/windows-container-networking/releases/download/v$cniVersion/windows-container-networking-cni-amd64-v$cniVersion.zip
tar xvf windows-container-networking-cni-amd64-v$cniVersion.zip -C $cniBinDir
$natConfig = @"
{
"cniVersion": "$cniVersion",
"name": "$networkName",
"type": "nat",
"master": "Ethernet",
"ipam": {
"subnet": "$subnet",
"routes": [
{
"gateway": "$gateway"
}
]
},
"capabilities": {
"portMappings": true,
"dns": true
}
}
"@
Set-Content -Path $cniConfPath -Value $natConfig
Write-Host "Starting buildkitd."
Start-Process -NoNewWindow buildkitd -ArgumentList "--containerd-cni-config-path=`"C:\Program Files\containerd\cni\conf\0-containerd-nat.conf`"","--containerd-cni-binary-dir=`"C:\Program Files\containerd\cni\bin`""
docker buildx
docker buildx install
docker buildx version
docker buildx create --name buildkit-exp --use --driver=remote npipe:////./pipe/buildkitd
docker buildx use --default --global buildkit-exp
docker buildx inspect
docker buildx ls
buildctl build --help
Write-Host "Building image"
Get-Location
Get-ChildItem -Force
bash -c ". scripts/docker.sh && buildDockerImage ${{ matrix.BASE_IMAGE }} ${{ env.BRANCH }} ${{ env.VERSION }};"
if (-not $?) {throw "Failed to build image."}
docker images
- name: Pull base Docker image
timeout-minutes: 60
if: success()
run: |
if echo "${{ matrix.BASE_IMAGE }}" | grep -q -e 'gentoo'; then
echo "Pulling MobileRT docker image ${{ env.VERSION }}";
. scripts/docker.sh && pullDockerImage ptpuscas/mobile_rt:${{ env.VERSION }} &
pid_docker_pull="$!";
export BUILD_IMAGE='no';
wait ${pid_docker_pull};
echo "Squashing MobileRT docker image: ${{ env.VERSION }}";
. scripts/docker.sh && squashMobileRTDockerImage ${{ env.VERSION }} &
pid_docker="$!";
else
echo "Pulling docker base image ${{ matrix.BASE_IMAGE }}";
. scripts/docker.sh && pullDockerImage ${{ matrix.BASE_IMAGE }} &
pid_docker="$!";
export BUILD_IMAGE='yes';
fi
echo 'Waiting for docker pull.';
wait ${pid_docker};
dockerStatus=$?;
echo "BUILD_IMAGE=${BUILD_IMAGE}" >> "${GITHUB_ENV}";
docker images -a;
if [ "${dockerStatus}" != '0' ]; then
exit 1;
fi
- name: Build Docker image
timeout-minutes: 300
if: success() && env.BUILD_IMAGE == 'yes'
run: |
# shellcheck disable=SC1091
echo "BASE_IMAGE: ${{ matrix.BASE_IMAGE }}";
echo "BRANCH: ${{ env.BRANCH }}";
echo "VERSION: ${{ env.VERSION }}";
. scripts/docker.sh && buildDockerImage ${{ matrix.BASE_IMAGE }} ${{ env.BRANCH }} ${{ env.VERSION }};
- name: Build MobileRT
timeout-minutes: ${{ fromJSON(env.GITHUB_STEP_TIMEOUT_LONG) }}
if: success() && env.BUILD_IMAGE != 'yes'
run: |
# shellcheck disable=SC1091
echo "VERSION: ${{ env.VERSION }}";
. scripts/docker.sh && compileMobileRTInDockerContainer ${{ env.VERSION }};
- name: Commit MobileRT Docker image layer
timeout-minutes: ${{ fromJSON(env.GITHUB_STEP_TIMEOUT_SMALL) }}
if: success() && env.BUILD_IMAGE != 'yes'
run: |
# shellcheck disable=SC1091
echo "VERSION: ${{ env.VERSION }}";
. scripts/docker.sh && commitMobileRTDockerImage ${{ env.VERSION }};
- name: Run unit tests
timeout-minutes: ${{ fromJSON(env.GITHUB_STEP_TIMEOUT_SMALL) }}
if: success()
run: |
# shellcheck disable=SC1091
echo "VERSION: ${{ env.VERSION }}";
. scripts/docker.sh && executeUnitTestsInDockerContainer ${{ env.VERSION }} --gtest_filter=-*Engine*;
- name: Run system tests Ray Tracing engine (for code coverage)
timeout-minutes: ${{ fromJSON(env.GITHUB_STEP_TIMEOUT_SMALL) }}
if: success()
run: |
# shellcheck disable=SC1091
echo "VERSION: ${{ env.VERSION }}";
. scripts/docker.sh && executeUnitTestsInDockerContainer ${{ env.VERSION }} --gtest_filter=*Engine*;
- name: Run Dockerfile unit tests
timeout-minutes: ${{ fromJSON(env.GITHUB_STEP_TIMEOUT_SMALL) }}
if: success()
working-directory: .
run: |
if echo "${{ matrix.BASE_IMAGE }}" | grep -q 'alpine'; then
sh scripts/test/docker/dockerfile.sh ${{ env.VERSION }} 143; # Expect SIGTERM (15). 128 + 15 = 143
else
sh scripts/test/docker/dockerfile.sh ${{ env.VERSION }};
fi
- name: Push Docker image
timeout-minutes: ${{ fromJSON(env.GITHUB_STEP_TIMEOUT_LONG) }}
if: success() && env.BRANCH == 'master'
run: |
# shellcheck disable=SC1091
echo "VERSION: ${{ env.VERSION }}";
. scripts/docker.sh && pushMobileRTDockerImage ${{ env.VERSION }};