Studio Tests workflow (datachain-ai/datachain)
The Studio Tests workflow from datachain-ai/datachain, explained and optimized by Latchkey.
CI health: C - fair
Point runs-on at Latchkey and get caching, job timeouts, SHA-pinned actions, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the Studio Tests workflow from the datachain-ai/datachain repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
name: Studio Tests
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
env:
FORCE_COLOR: "1"
BRANCH: ${{ github.head_ref || github.ref_name }}
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
studio:
if: '!github.event.pull_request.head.repo.fork'
runs-on: ubuntu-latest
strategy:
matrix:
pyv: ['3.13']
group: [1, 2, 3, 4, 5, 6]
services:
postgres:
image: postgres:16.3
ports:
- 5432:5432
env:
POSTGRES_USER: test
POSTGRES_DB: database
POSTGRES_HOST_AUTH_METHOD: trust
options: >-
--add-host=host.docker.internal:host-gateway
clickhouse:
image: clickhouse/clickhouse-server:25.8
ports:
- 8123:8123
- 9010:9000
env:
CLICKHOUSE_DB: studio_local_db
CLICKHOUSE_USER: studio_local
CLICKHOUSE_PASSWORD: ch123456789!
CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1
options: >-
--add-host=host.docker.internal:host-gateway
redis:
image: redis:7.2.5
ports:
- 6379:6379
options: >-
--add-host=host.docker.internal:host-gateway
steps:
- name: Studio branch name
env:
BRANCH: ${{ env.BRANCH }}
STUDIO_READ_ACCESS_TOKEN: ${{ secrets.ITERATIVE_STUDIO_READ_ACCESS_TOKEN }}
run: |
echo "DataChain branch: $BRANCH"
if git ls-remote --heads https://"$STUDIO_READ_ACCESS_TOKEN"@github.com/datachain-ai/studio.git "$BRANCH" | grep -F "$BRANCH" 2>&1>/dev/null
then
STUDIO_BRANCH="$BRANCH"
else
STUDIO_BRANCH=main
fi
echo "STUDIO_BRANCH=$STUDIO_BRANCH" >> $GITHUB_ENV
echo "Studio branch: $STUDIO_BRANCH"
- name: Check out Studio
uses: actions/checkout@v7
with:
fetch-depth: 1
repository: datachain-ai/studio
ref: ${{ env.STUDIO_BRANCH }}
token: ${{ secrets.ITERATIVE_STUDIO_READ_ACCESS_TOKEN }}
- name: Check out DataChain
uses: actions/checkout@v7
with:
path: './datachain'
fetch-depth: 1
- name: Set up Python ${{ matrix.pyv }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.pyv }}
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-suffix: studio
cache-dependency-glob: |
datachain_saas/pyproject.toml
datachain/pyproject.toml
- name: Use CPU-only PyTorch on Linux
# torch 2.11+ on PyPI pulls CUDA deps missing libnppicc (nvidia-npp)
run: echo "UV_TORCH_BACKEND=cpu" >> "$GITHUB_ENV"
- name: Update DataChain requirement in Studio
if: ${{ env.BRANCH != 'main' }}
working-directory: backend
run: make update_datachain_deps "${{ env.BRANCH }}"
- name: Install FFmpeg
run: |
sudo apt update
sudo apt install -y ffmpeg
- name: Install dependencies
run: uv pip install --system ./datachain_saas[tests] ./datachain[tests]
- name: Print installed system packages
run: uv pip list --system
- name: Initialize datachain venv
env:
PYTHON_VERSION: ${{ matrix.pyv }}
DATACHAIN_VENV_DIR: /tmp/local/datachain_venv/python${{ matrix.pyv }}
run: |
virtualenv -p "$(which python"${PYTHON_VERSION}")" "${DATACHAIN_VENV_DIR}"
pip_cache_dir="${DATACHAIN_VENV_DIR}/.cache/pip"
pip_wheel_dir="${pip_cache_dir}/wheels"
pip_bin="${DATACHAIN_VENV_DIR}/bin/pip"
mkdir -p "$pip_cache_dir"
mkdir -p "$pip_wheel_dir"
uv_cache_dir="${DATACHAIN_VENV_DIR}/.cache/uv"
mkdir -p "$uv_cache_dir"
$pip_bin install -U pip wheel setuptools \
--cache-dir="$pip_cache_dir"
$pip_bin wheel ./datachain_saas \
--wheel-dir="$pip_wheel_dir" \
--cache-dir="$pip_cache_dir"
uv venv --python "$PYTHON_VERSION" "${DATACHAIN_VENV_DIR}/default"
uv pip install -r ./compute/requirements-worker-venv.txt \
--find-links="$pip_wheel_dir" \
--cache-dir="${DATACHAIN_VENV_DIR}/.cache/uv" \
-p "${DATACHAIN_VENV_DIR}/default/bin/python"
- name: Print installed worker venv packages
env:
DATACHAIN_VENV_DIR: /tmp/local/datachain_venv/python${{ matrix.pyv }}
run: uv pip list -p "${DATACHAIN_VENV_DIR}/default/bin/python"
- name: Run tests
# Generate `.test_durations` file with `pytest --store-durations --durations-path ../.github/.test_durations ...`
run: >
PYTHONPATH="$(pwd)/..:${PYTHONPATH}"
pytest
--config-file=pyproject.toml -rs
--splits=6 --group=${{ matrix.group }} --durations-path=../../.github/.test_durations
--benchmark-skip
tests ../datachain/tests
working-directory: datachain_saas
The same workflow, on Latchkey
Estimated ~20% faster on cache hits, plus fewer wasted runs and a safer supply chain. Added and changed lines are highlighted.
name: Studio Tests on: push: branches: [main] pull_request: workflow_dispatch: env: FORCE_COLOR: "1" BRANCH: ${{ github.head_ref || github.ref_name }} concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: studio: timeout-minutes: 30 if: '!github.event.pull_request.head.repo.fork' runs-on: latchkey-small strategy: matrix: pyv: ['3.13'] group: [1, 2, 3, 4, 5, 6] services: postgres: image: postgres:16.3 ports: - 5432:5432 env: POSTGRES_USER: test POSTGRES_DB: database POSTGRES_HOST_AUTH_METHOD: trust options: >- --add-host=host.docker.internal:host-gateway clickhouse: image: clickhouse/clickhouse-server:25.8 ports: - 8123:8123 - 9010:9000 env: CLICKHOUSE_DB: studio_local_db CLICKHOUSE_USER: studio_local CLICKHOUSE_PASSWORD: ch123456789! CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1 options: >- --add-host=host.docker.internal:host-gateway redis: image: redis:7.2.5 ports: - 6379:6379 options: >- --add-host=host.docker.internal:host-gateway steps: - name: Studio branch name env: BRANCH: ${{ env.BRANCH }} STUDIO_READ_ACCESS_TOKEN: ${{ secrets.ITERATIVE_STUDIO_READ_ACCESS_TOKEN }} run: | echo "DataChain branch: $BRANCH" if git ls-remote --heads https://"$STUDIO_READ_ACCESS_TOKEN"@github.com/datachain-ai/studio.git "$BRANCH" | grep -F "$BRANCH" 2>&1>/dev/null then STUDIO_BRANCH="$BRANCH" else STUDIO_BRANCH=main fi echo "STUDIO_BRANCH=$STUDIO_BRANCH" >> $GITHUB_ENV echo "Studio branch: $STUDIO_BRANCH" - name: Check out Studio uses: actions/checkout@v7 with: fetch-depth: 1 repository: datachain-ai/studio ref: ${{ env.STUDIO_BRANCH }} token: ${{ secrets.ITERATIVE_STUDIO_READ_ACCESS_TOKEN }} - name: Check out DataChain uses: actions/checkout@v7 with: path: './datachain' fetch-depth: 1 - name: Set up Python ${{ matrix.pyv }} uses: actions/setup-python@v6 with: cache: 'pip' python-version: ${{ matrix.pyv }} - name: Setup uv uses: astral-sh/setup-uv@v7 with: enable-cache: true cache-suffix: studio cache-dependency-glob: | datachain_saas/pyproject.toml datachain/pyproject.toml - name: Use CPU-only PyTorch on Linux # torch 2.11+ on PyPI pulls CUDA deps missing libnppicc (nvidia-npp) run: echo "UV_TORCH_BACKEND=cpu" >> "$GITHUB_ENV" - name: Update DataChain requirement in Studio if: ${{ env.BRANCH != 'main' }} working-directory: backend run: make update_datachain_deps "${{ env.BRANCH }}" - name: Install FFmpeg run: | sudo apt update sudo apt install -y ffmpeg - name: Install dependencies run: uv pip install --system ./datachain_saas[tests] ./datachain[tests] - name: Print installed system packages run: uv pip list --system - name: Initialize datachain venv env: PYTHON_VERSION: ${{ matrix.pyv }} DATACHAIN_VENV_DIR: /tmp/local/datachain_venv/python${{ matrix.pyv }} run: | virtualenv -p "$(which python"${PYTHON_VERSION}")" "${DATACHAIN_VENV_DIR}" pip_cache_dir="${DATACHAIN_VENV_DIR}/.cache/pip" pip_wheel_dir="${pip_cache_dir}/wheels" pip_bin="${DATACHAIN_VENV_DIR}/bin/pip" mkdir -p "$pip_cache_dir" mkdir -p "$pip_wheel_dir" uv_cache_dir="${DATACHAIN_VENV_DIR}/.cache/uv" mkdir -p "$uv_cache_dir" $pip_bin install -U pip wheel setuptools \ --cache-dir="$pip_cache_dir" $pip_bin wheel ./datachain_saas \ --wheel-dir="$pip_wheel_dir" \ --cache-dir="$pip_cache_dir" uv venv --python "$PYTHON_VERSION" "${DATACHAIN_VENV_DIR}/default" uv pip install -r ./compute/requirements-worker-venv.txt \ --find-links="$pip_wheel_dir" \ --cache-dir="${DATACHAIN_VENV_DIR}/.cache/uv" \ -p "${DATACHAIN_VENV_DIR}/default/bin/python" - name: Print installed worker venv packages env: DATACHAIN_VENV_DIR: /tmp/local/datachain_venv/python${{ matrix.pyv }} run: uv pip list -p "${DATACHAIN_VENV_DIR}/default/bin/python" - name: Run tests # Generate `.test_durations` file with `pytest --store-durations --durations-path ../.github/.test_durations ...` run: > PYTHONPATH="$(pwd)/..:${PYTHONPATH}" pytest --config-file=pyproject.toml -rs --splits=6 --group=${{ matrix.group }} --durations-path=../../.github/.test_durations --benchmark-skip tests ../datachain/tests working-directory: datachain_saas
What changed
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Cache dependency installs on the setup step so they are served from cache.
- Add a job timeout so a hung step cannot burn hours of runner time.
1 third-party action is referenced by a movable tag. Pin it to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.
What Latchkey heals here
This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:
- Dependency installs
This workflow runs 1 job (6 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.