Skip to content

WIP: Poetry to UV/Hatch #4353

WIP: Poetry to UV/Hatch

WIP: Poetry to UV/Hatch #4353

Workflow file for this run

name: Tests
on: [push, pull_request]
permissions:
contents: read
defaults:
run:
shell: bash
jobs:
#-------------------------
# Building
#-------------------------
build_package:
name: Build and Cache Packages
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.set_tag.outputs.tag }}
tag_short: ${{ steps.set_tag_short.outputs.tag_short }}
branch: ${{ steps.set_branch.outputs.branch }}
is_merge_commit: ${{ steps.set_is_merge_commit.outputs.is_merge_commit }}
is_tag_build: ${{ steps.set_is_tag_build.outputs.is_tag_build }}
python_version: ${{ steps.set_python_version.outputs.python_version }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
# Set up Python and Poetry and cache build dependencies
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- uses: astral-sh/setup-uv@v5
with:
# Required for dependency groups
version: ">=0.4.27"
# enable-cache: true
# cache-dependency-glob: "uv.lock"
- run: |
uv venv --python 3.11
source $VENV
- name: Install the project
run: uv sync
# any local changes would make hatch-vcs set a "local version" (+dev0...), so we ignore any uv.lock updates:
# - run: git update-index --assume-unchanged uv.lock
# Install node and yarn in order to build the front end during packaging
- name: Set Node.js 22.x
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: 'yarn'
cache-dependency-path: locust/webui/yarn.lock
- name: Install Yarn
run: npm install -g yarn
# Build and upload the project artifacts only once
- name: Build Python project and front end
run: uv build
- name: Upload Python dist as Artifact
uses: actions/upload-artifact@v4
with:
name: python-dist
path: dist/*
- name: Upload Web UI as Artifact
uses: actions/upload-artifact@v4
with:
name: webui-dist
path: locust/webui/dist/*
- name: Build UI library
run: yarn webui:build:lib
- name: Upload web UI library as Artifact
uses: actions/upload-artifact@v4
with:
name: webui-lib-dist
path: locust/webui/lib
# Set workflow metadata in one place so we can pull it out later
- id: set_tag
run: echo "tag=$(hatch version)" | tee -a "$GITHUB_OUTPUT"
- id: set_tag_short
run: echo "tag_short=$(hatch version | cut -d '.' -f1-3)" | tee -a "$GITHUB_OUTPUT"
- id: set_branch
run: echo "branch=${{ github.head_ref || github.ref_name }}" | tee -a "$GITHUB_OUTPUT"
- id: set_is_merge_commit
run: echo "is_merge_commit=$( [ $(git rev-list --count $GITHUB_SHA^@) -eq 2 ] && echo 'true' || echo 'false' )" | tee -a "$GITHUB_OUTPUT"
- id: set_is_tag_build
run: echo "is_tag_build=${{ startsWith(github.event.ref, 'refs/tags') }}" | tee -a "$GITHUB_OUTPUT"
- id: set_python_version
run: echo "python_version=$(python -VV | sha256sum | cut -d' ' -f1)" | tee -a "$GITHUB_OUTPUT"
print_metadata:
name: Display metadata for build
runs-on: ubuntu-latest
needs: build_package
steps:
- run: |
echo "tag: ${{ needs.build_package.outputs.tag }}"
echo "tag_short: ${{ needs.build_package.outputs.tag_short }}"
echo "branch: ${{ needs.build_package.outputs.branch }}"
echo "is_merge_commit: ${{ needs.build_package.outputs.is_merge_commit }}"
echo "is_tag_build: ${{ needs.build_package.outputs.is_tag_build }}"
echo "python_version: ${{ needs.build_package.outputs.python_version }}"
#-------------------------
# Testing
#-------------------------
tests:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
needs: build_package
strategy:
fail-fast: false
matrix:
include:
# Static analysis and utilities
- { name: "Ruff", python: "3.12", os: ubuntu-latest, env: "lint:format" }
- { name: "Mypy", python: "3.12", os: ubuntu-latest, env: "lint:types" }
# Verification of builds and other aspects
- { name: "Docs Build", python: "3.12", os: ubuntu-latest, env: "docs:build" }
# OS Integration tests
- { name: "Linux", python: "3.12", os: ubuntu-latest, env: "test:fail_fast" }
- { name: "Windows", python: '3.12', os: windows-latest, env: "test:fail_fast" }
- { name: "MacOS", python: '3.12', os: macos-latest, env: "test:fail_fast" }
# Unit tests on Python versions
- { name: "Python 3.13", python: "3.13", os: ubuntu-latest, env: "test:all" }
- { name: "Python 3.12", python: "3.12", os: ubuntu-latest, env: "test:all" }
- { name: "Python 3.11", python: "3.11", os: ubuntu-latest, env: "test:all" }
- { name: "Python 3.10", python: "3.10", os: ubuntu-latest, env: "test:all" }
- { name: "Python 3.9", python: "3.9", os: ubuntu-latest, env: "test:all" }
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Set up Python and Poetry and cache build dependencies
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
- uses: astral-sh/setup-uv@v5
with:
# Required for dependency groups
version: ">=0.4.27"
# enable-cache: true
# cache-dependency-glob: "uv.lock"
- run: |
uv venv --python ${{ matrix.python }}
source $VENV
# Install what we need to run hatch envs but not the project itself
- name: Install CI dependencies
run: uv sync --all-groups --no-install-package locust
# Grab the built artifacts to ensure we're testing what we eventually publish
- name: Download Python dist
uses: actions/download-artifact@v4
with:
name: python-dist
path: dist
- name: Download WebUI dist
uses: actions/download-artifact@v4
with:
name: webui-dist
path: locust/webui/dist
# Install the package built earlier
- name: Install the built package
run: uv pip install ./dist/locust*.whl
# Run tests!
- name: Run hatch tests
run: hatch run +py=${{ matrix.python }} ${{ matrix.env }}
# test_docker_image:
# name: Test Docker Image
# runs-on: ubuntu-latest
# needs: build_package
# steps:
# - uses: actions/checkout@v4
# with:
# fetch-depth: 0
# # Grab the built artifacts to ensure we're testing what we eventually publish
# - name: Download Python dist
# uses: actions/download-artifact@v4
# with:
# name: python-dist
# path: dist
# # Set up Docker daemon dependencies for building and publishing
# - name: Set up QEMU
# uses: docker/setup-qemu-action@v3
# - name: Set up Docker Buildx
# uses: docker/setup-buildx-action@v3
# # Build and load Docker image to the local daemon
# - name: Build and push
# uses: docker/build-push-action@v6
# with:
# context: .
# file: ./Dockerfile.ci
# platforms: linux/amd64
# load: true
# tags: locustio/locust:${{ github.sha }}-test
# # Run a basic test on the image
# - name: Test docker image
# run: |
# docker run --rm locustio/locust:${{ github.sha }}-test --version
lint_typecheck_test_webui:
name: Web UI Lint and Type Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set Node.js 22.x
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: 'yarn'
cache-dependency-path: locust/webui/yarn.lock
- uses: borales/actions-yarn@v5
with:
cmd: install
dir: locust/webui
- uses: borales/actions-yarn@v5
with:
cmd: build
dir: locust/webui
- uses: borales/actions-yarn@v5
with:
cmd: test
dir: locust/webui
- uses: borales/actions-yarn@v5
with:
cmd: lint
dir: locust/webui
- uses: borales/actions-yarn@v5
with:
cmd: type-check
dir: locust/webui
# -------------------------
# Publishing
# -------------------------
# publish:
# needs: [tests, lint_typecheck_test_webui, test_docker_image, build_package]
# if: github.repository_owner == 'locustio' && ( github.ref == 'refs/heads/master' || startsWith(github.event.ref, 'refs/tags') )
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v4
# with:
# fetch-depth: 0
# # Download Python dist artifact
# - name: Download Python dist
# uses: actions/download-artifact@v4
# with:
# name: python-dist
# path: dist
# # Download Web UI lib artifact
# - name: Download UI lib
# uses: actions/download-artifact@v4
# with:
# name: webui-lib-dist
# path: locust/webui/lib
# # Staged docker builds using exports/artifacts is currently difficult using multi-arch builds with buildx
# # So let's just build it here
# # Set docker image and tag values
# - name: Docker meta
# id: docker_meta
# uses: docker/metadata-action@v5
# with:
# images: locustio/locust
# tags: |
# type=raw,value=latest,enable=${{ needs.build_package.outputs.is_tag_build }}
# type=raw,value=${{ needs.build_package.outputs.tag }}
# type=raw,value=${{ needs.build_package.outputs.branch }}
# # Set up Docker daemon dependencies for building and publishing
# - uses: docker/login-action@v3
# with:
# username: locustbuild
# password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
# - name: Set up QEMU
# uses: docker/setup-qemu-action@v3
# - name: Set up Docker Buildx
# uses: docker/setup-buildx-action@v3
# # Build and push Docker image
# - name: Build and push
# uses: docker/build-push-action@v6
# with:
# context: .
# file: ./Dockerfile.ci
# platforms: linux/amd64,linux/arm64
# push: ${{ github.event_name != 'pull_request' }}
# tags: ${{ steps.docker_meta.outputs.tags }}
# # Publish Python package
# - name: Publish prerelease version to PyPI
# uses: pypa/gh-action-pypi-publish@release/v1
# with:
# user: __token__
# password: ${{ secrets.PYPI_API_TOKEN }}
# skip-existing: true
# # Publish UI lib
# # On commits to trunk
# - uses: borales/actions-yarn@v5
# name: Publish package on NPM
# if: github.ref == 'refs/heads/master'
# env:
# NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
# with:
# cmd: publish --no-git-tag-version --non-interactive --tag next --new-version ${{ needs.build_package.outputs.tag_short }}-next-${{ github.run_id }}
# dir: locust/webui
# # On tag builds
# - uses: borales/actions-yarn@v5
# name: Publish package on NPM
# if: startsWith(github.event.ref, 'refs/tags')
# env:
# NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
# with:
# cmd: publish --no-git-tag-version --non-interactive --new-version ${{ github.ref_name }}
# dir: locust/webui