Update CI updates #10115
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: ci | |
| on: | |
| pull_request: | |
| branches: | |
| - main | |
| push: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} | |
| jobs: | |
| lint: | |
| if: | | |
| github.event_name == 'pull_request' || | |
| github.ref == 'refs/heads/main' || | |
| github.repository_owner != 'containers' | |
| name: Lint Code | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Determine minimum supported Python | |
| id: min-python | |
| shell: bash | |
| run: | | |
| req="$(sed -nE "s/^requires-python\s*=\s*['\"]([^'\"]+)['\"]/\1/p" pyproject.toml | head -n1)" | |
| min="$(printf '%s\n' "$req" \ | |
| | grep -oE '(>=|>)[[:space:]]*[0-9]+(\.[0-9]+){0,2}' \ | |
| | sed -E 's/(>=|>)\s*//' \ | |
| | sort -V \ | |
| | tail -n1)" | |
| test -n "$min" || { echo "Failed to parse requires-python: $req"; exit 1; } | |
| echo "version=$min" >> "$GITHUB_OUTPUT" | |
| - name: Install the latest version of uv | |
| uses: astral-sh/setup-uv@v8.3.2 | |
| with: | |
| python-version: ${{ steps.min-python.outputs.version }} | |
| # Manpage roff build (make -C docs / make docs) needs go-md2man; Ubuntu | |
| # runners do not put cached Go on PATH, so `go install` from install-tools | |
| # is unreliable. The distro package is sufficient. | |
| - name: Install go-md2man | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y go-md2man | |
| - name: Install dependencies | |
| run: | | |
| uv run -- make install-requirements | |
| - name: Run format check | |
| run: | | |
| uv run -- make check-format | |
| - name: Run lint | |
| run: | | |
| uv run -- make lint | |
| - name: Run man check | |
| run: | | |
| uv run -- make man-check | |
| - name: Run type checking | |
| run: | | |
| uv run -- make type-check | |
| unit-test: | |
| if: | | |
| github.event_name == 'pull_request' || | |
| github.ref == 'refs/heads/main' || | |
| github.repository_owner != 'containers' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| variant: | |
| - title: "" | |
| runs-on: ubuntu-24.04 | |
| uv-options: {} | |
| - title: " (python 3.9)" | |
| runs-on: ubuntu-24.04 | |
| uv-options: | |
| python-version: '3.9' | |
| - title: " (MacOS)" | |
| runs-on: macos-26 | |
| uv-options: {} | |
| name: Unit Tests${{ matrix.variant.title }} | |
| runs-on: ${{ matrix.variant.runs-on }} | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install the latest version of uv | |
| uses: astral-sh/setup-uv@v8.3.2 | |
| with: ${{ matrix.variant.uv-options }} | |
| - name: Run unit tests | |
| env: | |
| HF_TOKEN: ${{ secrets.HF_TOKEN }} | |
| run: | | |
| uv run -- make unit-tests | |
| e2e-tests: | |
| if: | | |
| github.event_name == 'pull_request' || | |
| github.ref == 'refs/heads/main' || | |
| github.repository_owner != 'containers' | |
| needs: | |
| - lint | |
| - unit-test | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| variant: | |
| - title: "" | |
| uv-options: | |
| activate-environment: true | |
| - title: " (python 3.9)" | |
| uv-options: | |
| python-version: '3.9' | |
| activate-environment: true | |
| name: E2E Tests${{ matrix.variant.title }} | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Check HF token | |
| id: hf | |
| run: echo "has_token=${{ secrets.HF_TOKEN != '' }}" >> "$GITHUB_OUTPUT" | |
| - name: Install the latest version of uv | |
| uses: astral-sh/setup-uv@v8.3.2 | |
| with: ${{ matrix.variant.uv-options }} | |
| - name: install requirements | |
| shell: bash | |
| run: | | |
| df -h | |
| # /mnt has ~ 65 GB free disk space. / is too small. | |
| sudo mkdir -m a=rwx -p /mnt/runner | |
| sudo mkdir -m o=rwx -p /home/runner/.local | |
| sudo chown runner:runner /mnt/runner /home/runner/.local | |
| sudo mount --bind /mnt/runner /home/runner/.local | |
| sudo apt-get update | |
| sudo apt-get install podman bash codespell | |
| uv tool install tox --with tox-uv | |
| uv pip install ".[dev]" | |
| - name: install ollama | |
| shell: bash | |
| run: ./.github/scripts/install-ollama.sh | |
| - name: Upgrade to podman 5 | |
| run: | | |
| set -e | |
| # Enable universe repository which contains podman | |
| sudo add-apt-repository "deb http://old-releases.ubuntu.com/ubuntu oracular universe" | |
| # Update package lists | |
| sudo apt-get update | |
| sudo apt-get purge firefox | |
| # Install specific podman version | |
| sudo apt-get upgrade -y podman crun | |
| - name: Start HF mirror | |
| if: steps.hf.outputs.has_token != 'true' | |
| run: | | |
| podman run -d --name hfmirror -p 5000:5000 quay.io/ramalama/hfmirror:latest | |
| timeout 120 bash -c 'until curl -sf http://127.0.0.1:5000/v2/ >/dev/null 2>&1; do sleep 2; done' | |
| - name: run e2e-tests | |
| env: | |
| HF_TOKEN: ${{ secrets.HF_TOKEN }} | |
| HF_ENDPOINT: ${{ secrets.HF_TOKEN == '' && 'http://127.0.0.1:5000' || '' }} | |
| run: | | |
| make e2e-tests | |
| e2e-tests-nocontainer: | |
| if: | | |
| github.event_name == 'pull_request' || | |
| github.ref == 'refs/heads/main' || | |
| github.repository_owner != 'containers' | |
| needs: | |
| - lint | |
| - unit-test | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| variant: | |
| - title: "" | |
| uv-options: | |
| activate-environment: true | |
| - title: " (python 3.9)" | |
| uv-options: | |
| python-version: '3.9' | |
| activate-environment: true | |
| name: E2E Tests (--no-container)${{ matrix.variant.title }} | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Check HF token | |
| id: hf | |
| run: echo "has_token=${{ secrets.HF_TOKEN != '' }}" >> "$GITHUB_OUTPUT" | |
| - name: Install the latest version of uv | |
| uses: astral-sh/setup-uv@v8.3.2 | |
| with: ${{ matrix.variant.uv-options }} | |
| - name: install requirements | |
| shell: bash | |
| run: | | |
| df -h | |
| sudo apt-get update | |
| sudo apt-get install podman bash codespell git cmake libcurl4-openssl-dev | |
| sudo ./container-images/scripts/build_llama.sh | |
| sudo cp -a /tmp/install/bin/ /usr/ | |
| sudo cp -a /tmp/install/lib/*.so* /usr/lib/ | |
| uv tool install tox --with tox-uv | |
| uv pip install ".[dev]" | |
| - name: install ollama | |
| shell: bash | |
| run: ./.github/scripts/install-ollama.sh | |
| - name: Upgrade to podman 5 | |
| run: | | |
| set -e | |
| # Enable universe repository which contains podman | |
| sudo add-apt-repository "deb http://old-releases.ubuntu.com/ubuntu oracular universe" | |
| # Update package lists | |
| sudo apt-get update | |
| sudo apt-get purge firefox | |
| # Install specific podman version | |
| sudo apt-get upgrade -y podman crun | |
| - name: Start HF mirror | |
| if: steps.hf.outputs.has_token != 'true' | |
| run: | | |
| podman run -d --name hfmirror -p 5000:5000 quay.io/ramalama/hfmirror:latest | |
| timeout 120 bash -c 'until curl -sf http://127.0.0.1:5000/v2/ >/dev/null 2>&1; do sleep 2; done' | |
| - name: run e2e-tests-nocontainer | |
| env: | |
| HF_TOKEN: ${{ secrets.HF_TOKEN }} | |
| HF_ENDPOINT: ${{ secrets.HF_TOKEN == '' && 'http://127.0.0.1:5000' || '' }} | |
| run: | | |
| make e2e-tests-nocontainer | |
| e2e-tests-docker: | |
| if: | | |
| github.event_name == 'pull_request' || | |
| github.ref == 'refs/heads/main' || | |
| github.repository_owner != 'containers' | |
| needs: | |
| - lint | |
| - unit-test | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| variant: | |
| - title: "" | |
| uv-options: | |
| activate-environment: true | |
| - title: " (python 3.9)" | |
| uv-options: | |
| python-version: '3.9' | |
| activate-environment: true | |
| name: E2E Tests (docker)${{ matrix.variant.title }} | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Check HF token | |
| id: hf | |
| run: echo "has_token=${{ secrets.HF_TOKEN != '' }}" >> "$GITHUB_OUTPUT" | |
| - name: Install the latest version of uv | |
| uses: astral-sh/setup-uv@v8.3.2 | |
| with: ${{ matrix.variant.uv-options }} | |
| - name: install requirements | |
| shell: bash | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install bash codespell | |
| uv tool install tox --with tox-uv | |
| uv pip install ".[dev]" | |
| - name: install ollama | |
| shell: bash | |
| run: ./.github/scripts/install-ollama.sh | |
| - name: Upgrade to podman 5 | |
| run: | | |
| set -e | |
| # Enable universe repository which contains podman | |
| sudo add-apt-repository "deb http://old-releases.ubuntu.com/ubuntu oracular universe" | |
| # Update package lists | |
| sudo apt-get update | |
| sudo apt-get purge firefox | |
| # Install specific podman version | |
| sudo apt-get upgrade -y podman crun | |
| - name: Free Disk Space Linux | |
| shell: bash | |
| run: | | |
| sudo docker rmi "$(docker image ls -aq)" >/dev/null 2>&1 || true | |
| sudo rm -rf \ | |
| /usr/share/dotnet /usr/local/lib/android /opt/ghc \ | |
| /usr/local/share/powershell /usr/share/swift /usr/local/.ghcup \ | |
| /usr/lib/jvm || true | |
| # /mnt has ~ 65 GB free disk space. / is too small. | |
| - name: Reconfigure Docker data-root | |
| run: | | |
| sudo mkdir -p /mnt/docker /etc/docker | |
| echo '{"data-root": "/mnt/docker"}' > /tmp/daemon.json | |
| sudo mv /tmp/daemon.json /etc/docker/daemon.json | |
| cat /etc/docker/daemon.json | |
| sudo systemctl restart docker.service | |
| sudo mkdir -m a=rwx -p /mnt/tmp /mnt/runner | |
| sudo mkdir -m o=rwx -p /home/runner/.local | |
| sudo chown runner:runner /mnt/runner /home/runner/.local | |
| sudo mount --bind /mnt/runner /home/runner/.local | |
| df -h | |
| - name: Start HF mirror | |
| if: steps.hf.outputs.has_token != 'true' | |
| run: | | |
| docker run -d --name hfmirror -p 5000:5000 quay.io/ramalama/hfmirror:latest | |
| timeout 120 bash -c 'until curl -sf http://127.0.0.1:5000/v2/ >/dev/null 2>&1; do sleep 2; done' | |
| - name: run e2e-tests-docker | |
| env: | |
| HF_TOKEN: ${{ secrets.HF_TOKEN }} | |
| HF_ENDPOINT: ${{ secrets.HF_TOKEN == '' && 'http://127.0.0.1:5000' || '' }} | |
| run: | | |
| docker info | |
| make e2e-tests-docker | |
| e2e-tests-macos: | |
| if: | | |
| github.event_name == 'pull_request' || | |
| github.ref == 'refs/heads/main' || | |
| github.repository_owner != 'containers' | |
| needs: | |
| - lint | |
| - unit-test | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| variant: | |
| - title: "" | |
| uv-options: | |
| activate-environment: true | |
| - title: " (python 3.9)" | |
| uv-options: | |
| python-version: '3.9' | |
| activate-environment: true | |
| name: E2E Tests (MacOS)${{ matrix.variant.title }} | |
| runs-on: macos-26 | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Check HF token | |
| id: hf | |
| run: echo "has_token=${{ secrets.HF_TOKEN != '' }}" >> "$GITHUB_OUTPUT" | |
| - name: Install the latest version of uv | |
| uses: astral-sh/setup-uv@v8.3.2 | |
| with: ${{ matrix.variant.uv-options }} | |
| - name: install requirements | |
| shell: bash | |
| run: | | |
| brew install go bash jq llama.cpp shellcheck podman | |
| uv tool install tox --with tox-uv | |
| uv run -- make install-requirements | |
| - name: install ollama | |
| shell: bash | |
| run: ./.github/scripts/install-ollama.sh | |
| - uses: actions/cache@v4 | |
| if: steps.hf.outputs.has_token != 'true' | |
| id: hfmirror-cache | |
| with: | |
| path: /tmp/hfmirror/models | |
| key: hfmirror-models-v1 | |
| - name: Install crane | |
| if: steps.hf.outputs.has_token != 'true' && steps.hfmirror-cache.outputs.cache-hit != 'true' | |
| uses: imjasonh/setup-crane@v0.7 | |
| - name: Extract models from container image | |
| if: steps.hf.outputs.has_token != 'true' && steps.hfmirror-cache.outputs.cache-hit != 'true' | |
| run: | | |
| mkdir -p /tmp/hfmirror | |
| crane export quay.io/ramalama/hfmirror:latest - | tar -xf - -C /tmp/hfmirror --strip-components=1 data/models | |
| - name: Start HF mirror | |
| if: steps.hf.outputs.has_token != 'true' | |
| run: | | |
| uv pip install flask | |
| HFMIRROR_MODELS_DIR=/tmp/hfmirror/models HFMIRROR_INDEX="" python3 container-images/hfmirror/server.py & | |
| for i in $(seq 1 60); do curl -sf http://127.0.0.1:5000/v2/ >/dev/null 2>&1 && break || sleep 2; done | |
| curl -sf http://127.0.0.1:5000/v2/ >/dev/null 2>&1 || { echo "HF mirror failed to start"; exit 1; } | |
| - name: run e2e-tests-nocontainer | |
| shell: bash | |
| env: | |
| HF_TOKEN: ${{ secrets.HF_TOKEN }} | |
| HF_ENDPOINT: ${{ secrets.HF_TOKEN == '' && 'http://127.0.0.1:5000' || '' }} | |
| run: | | |
| make e2e-tests-nocontainer | |
| e2e-tests-windows: | |
| if: | | |
| github.event_name == 'pull_request' || | |
| github.ref == 'refs/heads/main' || | |
| github.repository_owner != 'containers' | |
| needs: | |
| - lint | |
| - unit-test | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| variant: | |
| - title: "" | |
| uv-options: | |
| activate-environment: true | |
| - title: " (python 3.9)" | |
| uv-options: | |
| python-version: '3.9' | |
| activate-environment: true | |
| name: E2E Tests (Windows)${{ matrix.variant.title }} | |
| runs-on: windows-latest | |
| timeout-minutes: 90 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v7 | |
| - name: Check HF token | |
| id: hf | |
| shell: bash | |
| run: echo "has_token=${{ secrets.HF_TOKEN != '' }}" >> "$GITHUB_OUTPUT" | |
| - name: Enable long path support | |
| shell: pwsh | |
| run: | | |
| New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v8.3.2 | |
| with: ${{ matrix.variant.uv-options }} | |
| - name: Update WSL2 | |
| shell: pwsh | |
| run: | | |
| Write-Host "Updating WSL2..." | |
| wsl --update | |
| wsl --shutdown | |
| - name: Install Podman | |
| shell: pwsh | |
| run: | | |
| Write-Host "Installing Podman on Windows..." | |
| winget install --accept-source-agreements --silent --disable-interactivity --exact --id RedHat.Podman | |
| # TODO: remove when this just works https://github.com/microsoft/winget-cli/issues/549 | |
| # Add Podman to PATH for current session | |
| $podmanPath = "$env:ProgramFiles" + "\RedHat\Podman" | |
| $env:PATH = "$podmanPath;$env:PATH" | |
| [Environment]::SetEnvironmentVariable("PATH", $env:PATH, [EnvironmentVariableTarget]::Process) | |
| # Update PATH for future steps | |
| Add-Content -Path $env:GITHUB_PATH -Value "$podmanPath" | |
| Write-Host "Verifying Podman installation..." | |
| podman --version | |
| Write-Host "Initializing Podman machine..." | |
| podman machine init --now --rootful | |
| # Wait for Podman to be ready | |
| $maxAttempts = 30 | |
| $attempt = 0 | |
| while ($attempt -lt $maxAttempts) { | |
| try { | |
| podman info | Out-Null | |
| Write-Host "Podman is ready!" | |
| break | |
| } | |
| catch { | |
| $attempt++ | |
| Write-Host "Waiting for Podman to be ready (attempt $attempt/$maxAttempts)..." | |
| Start-Sleep -Seconds 2 | |
| } | |
| } | |
| if ($attempt -eq $maxAttempts) { | |
| Write-Error "Podman failed to start" | |
| exit 1 | |
| } | |
| Write-Host "Podman info:" | |
| podman info | |
| - name: Install OpenSSL | |
| shell: pwsh | |
| run: | | |
| winget install --accept-source-agreements --silent --disable-interactivity --exact --id ShiningLight.OpenSSL.Light | |
| # Add OpenSSL to PATH for current session | |
| $opensslPath = "$env:ProgramFiles" + "\OpenSSL-Win64\bin" | |
| $env:PATH = "$opensslPath;$env:PATH" | |
| [Environment]::SetEnvironmentVariable("PATH", $env:PATH, [EnvironmentVariableTarget]::Process) | |
| # Update PATH for future steps | |
| Add-Content -Path $env:GITHUB_PATH -Value "$opensslPath" | |
| openssl version | |
| - name: Start HF mirror | |
| if: steps.hf.outputs.has_token != 'true' | |
| shell: pwsh | |
| run: | | |
| podman run -d --name hfmirror -p 5000:5000 quay.io/ramalama/hfmirror:latest | |
| $maxAttempts = 60 | |
| $attempt = 0 | |
| while ($attempt -lt $maxAttempts) { | |
| try { | |
| Invoke-WebRequest -Uri http://127.0.0.1:5000/v2/ -UseBasicParsing | Out-Null | |
| Write-Host "HF mirror is ready!" | |
| break | |
| } | |
| catch { | |
| $attempt++ | |
| Write-Host "Waiting for HF mirror (attempt $attempt/$maxAttempts)..." | |
| Start-Sleep -Seconds 2 | |
| } | |
| } | |
| if ($attempt -eq $maxAttempts) { | |
| Write-Error "HF mirror failed to start" | |
| exit 1 | |
| } | |
| - name: Run E2E tests | |
| shell: pwsh | |
| env: | |
| RAMALAMA_CONTAINER_ENGINE: podman | |
| HF_TOKEN: ${{ secrets.HF_TOKEN }} | |
| HF_ENDPOINT: ${{ secrets.HF_TOKEN == '' && 'http://127.0.0.1:5000' || '' }} | |
| run: | | |
| Write-Host "Running E2E tests..." | |
| # Add uv tools to PATH | |
| $uvToolsPath = "$env:USERPROFILE\.local\bin" | |
| $env:PATH = "$uvToolsPath;$env:PATH" | |
| # Run tests | |
| uv run tox -e e2e -- -v | |
| - name: Debug - Show Podman logs on failure | |
| if: failure() | |
| shell: pwsh | |
| run: | | |
| Write-Host "=== Podman Machine List ===" | |
| podman machine list | |
| Write-Host "`n=== Podman System Connection List ===" | |
| podman system connection list | |
| Write-Host "`n=== Podman Info ===" | |
| podman info || true | |
| Write-Host "`n=== Podman Version ===" | |
| podman version || true | |
| Write-Host "`n=== Running Containers ===" | |
| podman ps -a || true | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: windows-e2e-test-results | |
| path: | | |
| test-results/ | |
| *.log | |
| retention-days: 7 | |
| # FIXME: ci script should be able to run on MAC. | |
| # - name: Run ci | |
| # shell: bash | |
| # run: make ci |