Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ plugboard/**/__pycache__
plugboard/*.egg-info
!pyproject.toml
!uv.lock
!requirements.txt
!requirements.txt
!README.md
3 changes: 1 addition & 2 deletions .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,8 @@ jobs:
- name: Install project
id: install
run: |
VERSION=$(uvx dunamai from git --style semver)
uvx --from=toml-cli toml set --toml-path=pyproject.toml project.version $VERSION
uv sync --group docs
VERSION=$(uv run hatch version)
echo "version=$VERSION" >> $GITHUB_OUTPUT

- name: Set git credentials
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/pypi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ jobs:
- name: Build wheel
id: wheel
run: |
VERSION=$(uvx dunamai from git --style semver)
uvx --from=toml-cli toml set --toml-path=pyproject.toml project.version $VERSION
VERSION=$(uv run hatch version)
uv build
echo "version=$VERSION" >> $GITHUB_OUTPUT

Expand Down
13 changes: 7 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,22 @@ FROM base AS builder
ENV UV_PROJECT_ENVIRONMENT=/opt/venv
ENV PATH="${UV_PROJECT_ENVIRONMENT}/bin:${PATH}"
ENV UV_LINK_MODE=copy
ENV UV_CACHE_DIR=/root/.cache/uv

# Install dependencies with pip and requirements.txt to avoid potential cache invalidation
RUN --mount=from=ghcr.io/astral-sh/uv,source=/uv,target=/bin/uv \
--mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=requirements.txt,target=requirements.txt \
python -m venv ${UV_PROJECT_ENVIRONMENT} && \
uv pip install -r ./requirements.txt
uv venv ${UV_PROJECT_ENVIRONMENT} && \
uv pip install -r requirements.txt hatchling
Comment thread
chrisk314 marked this conversation as resolved.


# Final stage with production setup ---------------------------------------------------------------
FROM base AS prod
ENV UV_PROJECT_ENVIRONMENT=/opt/venv
ENV PATH="${UV_PROJECT_ENVIRONMENT}/bin:${PATH}"
ENV UV_LINK_MODE=copy
ENV UV_CACHE_DIR=/root/.cache/uv

# Ensure PATH with venv is set in user's bash profile for login shells (required for running in kuberay)
RUN echo "export PATH=${UV_PROJECT_ENVIRONMENT}/bin:\$PATH" >> /home/appuser/.profile && \
Expand All @@ -40,14 +42,13 @@ COPY --from=builder ${UV_PROJECT_ENVIRONMENT} ${UV_PROJECT_ENVIRONMENT}

# Install package with version string passed as build arg
ARG semver
ENV UV_VERSION_BYPASS=${semver}
ENV SETUPTOOLS_SCM_PRETEND_VERSION=${semver}
RUN --mount=from=ghcr.io/astral-sh/uv,source=/uv,target=/bin/uv \
--mount=type=bind,target=/app,rw \
--mount=type=tmpfs,target=/tmp/build \
--mount=type=cache,target=/root/.cache/uv \
uv tool run --from=toml-cli toml set --toml-path=pyproject.toml project.version $UV_VERSION_BYPASS && \
uv tool run --from=toml-cli toml unset --toml-path=pyproject.toml project.readme && \
uv sync --no-editable --compile-bytecode --all-extras
uv run hatch build -t wheel /tmp/build/dist && \
uv pip install --no-deps /tmp/build/dist/*.whl

# Get security updates. Relies on cache bust from previous steps.
RUN --mount=type=cache,id=apt,target=/var/cache/apt \
Expand Down
76 changes: 28 additions & 48 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,87 +1,65 @@
SHELL := /bin/bash
VENV := .venv
PROJECT := plugboard
PYTHON_VERSION ?= 3.12
WITH_PYENV := $(shell which pyenv > /dev/null && echo true || echo false)
VENV_NAME := $(PROJECT)-$(PYTHON_VERSION)
VIRTUAL_ENV ?= $(shell $(WITH_PYENV) && echo $(shell pyenv root)/versions/$(VENV_NAME) || echo $(PWD)/.venv)
VENV := $(VIRTUAL_ENV)
PYTHON_VERSION ?= 3.13
PY := python$(PYTHON_VERSION)
SRC := ./plugboard
TESTS := ./tests

PYTHON := $(VENV)/bin/python
# Windows compatibility
ifeq ($(OS), Windows_NT)
PYTHON := $(VENV)/Scripts/python
PY := python
endif

.EXPORT_ALL_VARIABLES:
VIRTUAL_ENV = $(VENV)
PATH = $(VENV)/bin:$(shell echo $$PATH)
POETRY_VIRTUALENVS_PREFER_ACTIVE_PYTHON = true
POETRY_VIRTUALENVS_CREATE = false
POETRY_VIRTUALENVS_IN_PROJECT = true

.PHONY: all
all: lint test

.PHONY: clean
clean:
$(WITH_PYENV) && pyenv virtualenv-delete -f $(VENV_NAME) || rm -rf $(VENV)
$(WITH_PYENV) && pyenv local --unset || true
rm -f poetry.lock
rm -rf $(VENV)
rm -f uv.lock
find $(SRC) -type f -name *.pyc -delete
find $(SRC) -type d -name __pycache__ -delete

$(VENV):
$(WITH_PYENV) && pyenv install -s $(PYTHON_VERSION) || true
$(WITH_PYENV) && pyenv virtualenv $(PYTHON_VERSION) $(VENV_NAME) || python$(PYTHON_VERSION) -m venv $(VENV)
$(WITH_PYENV) && pyenv local $(VENV_NAME) || true
uv venv ${VENV} --python $(PY)
mkdir -p $(VENV)/.stamps
@touch $@

$(VENV)/.stamps/init-poetry: $(VENV)
$(PYTHON) -m pip install --upgrade pip setuptools poetry poetry-dynamic-versioning[plugin]
@mkdir -p $(VENV)/.stamps
$(VENV)/.stamps/init: $(VENV) pyproject.toml
uv sync --all-extras --all-groups
@touch $@

$(VENV)/.stamps/install: $(VENV)/.stamps/init-poetry pyproject.toml
$(PYTHON) -m poetry install --with docs
@mkdir -p $(VENV)/.stamps
@touch $@

.PHONY: install
install: $(VENV)/.stamps/install

.PHONY: init
init: install
init: $(VENV)/.stamps/init

.PHONY: lint
lint: init
$(PYTHON) -m ruff check
$(PYTHON) -m ruff format --check
$(PYTHON) -m mypy $(SRC)/ --explicit-package-bases
$(PYTHON) -m mypy $(TESTS)/
uv run ruff check
uv run ruff format --check
uv run mypy $(SRC)/ --explicit-package-bases
uv run mypy $(TESTS)/

.PHONY: test
test: init
$(PYTHON) -m pytest -rs $(TESTS)/ --ignore=$(TESTS)/smoke
uv run pytest -rs $(TESTS)/ --ignore=$(TESTS)/smoke

.PHONY: build
build: $(VENV)
uv build

.PHONY: docs
docs: $(VENV)
$(PYTHON) -m mkdocs build
uv run -m mkdocs build

MKDOCS_PORT ?= 8000
.PHONY: docs-serve
docs-serve: $(VENV) docs
$(PYTHON) -m mkdocs serve -a localhost:$(MKDOCS_PORT)

.PHONY: build
build: $(VENV) docs
$(PYTHON) -m poetry build
uv run -m mkdocs serve -a localhost:$(MKDOCS_PORT)

GIT_HASH_SHORT ?= $(shell git rev-parse --short HEAD)
GIT_BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD | tr / -)
BUILD_DATE = $(shell date -u -Iseconds)
PACKAGE_VERSION ?= $(shell poetry version -s)
PACKAGE_VERSION ?= $(shell uv run hatch version)
PACKAGE_VERSION_DOCKER_SAFE = $(shell echo $(PACKAGE_VERSION) | tr + .)

DOCKER_FILE ?= Dockerfile
Expand All @@ -90,13 +68,15 @@ DOCKER_IMAGE ?= plugboard
DOCKER_REGISTRY_IMAGE=${DOCKER_REGISTRY}/plugboard-dev/${DOCKER_IMAGE}

requirements.txt: $(VENV) pyproject.toml
$(PYTHON) -m poetry export -f requirements.txt -o requirements.txt --without-hashes
uv export --all-extras --format requirements-txt --no-hashes --no-editable --no-dev --no-emit-project > requirements.txt
Comment thread
chrisk314 marked this conversation as resolved.
@touch $@

.PHONY: docker-build
docker-build: ${DOCKER_FILE} requirements.txt
docker build . \
docker buildx build . \
-f ${DOCKER_FILE} \
--provenance=false \
--cache-from ${DOCKER_IMAGE}:latest \
--build-arg semver=$(PACKAGE_VERSION) \
--build-arg git_hash_short=$(GIT_HASH_SHORT) \
--build-arg git_branch=$(GIT_BRANCH) \
Expand All @@ -108,7 +88,7 @@ docker-build: ${DOCKER_FILE} requirements.txt
-t ${DOCKER_REGISTRY_IMAGE}:${PACKAGE_VERSION_DOCKER_SAFE} \
-t ${DOCKER_REGISTRY_IMAGE}:${GIT_HASH_SHORT} \
-t ${DOCKER_REGISTRY_IMAGE}:${GIT_BRANCH} \
--progress=plain 2>&1 | tee docker-build.log
--progress=plain

.PHONY: docker-login
docker-login:
Expand Down
13 changes: 10 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "plugboard"
version = "0.0.0"
dynamic = ["version"]
description = "Plugboard is an event driven modelling and orchestration framework for simulating and driving complex processes with many interconnected stateful components."
readme = "README.md"
license = "Apache-2.0"
Expand Down Expand Up @@ -43,11 +43,15 @@ llm = [
"llama-index-core>=0.12.30,<1",
"llama-index-llms-openai>=0.3.33,<1",
]
ray = ["ray[default,tune]>=2.42.1,<3", "optuna>=3.0,<4"]
# Pinning Ray due to hanging in Github Actions. Possibly related to:
# https://github.com/ray-project/ray/issues/53848
ray = ["ray[default,tune]>=2.42.1,<2.47", "optuna>=3.0,<4"]
websockets = ["websockets>=14.2,<15"]

[dependency-groups]
dev = [
"hatch>=1.14.1",
"hatch-vcs>=0.5.0",
"ipython>=8.26,<9",
"ipywidgets>=8.1.5,<9",
"jupyterlab>=4.2,<5",
Expand Down Expand Up @@ -86,9 +90,12 @@ docs = [
]

[build-system]
requires = ["hatchling"]
requires = ["hatchling", "hatch-vcs"]
build-backend = "hatchling.build"

[tool.hatch.version]
source = "vcs"

[tool.uv]
package = true

Expand Down
Loading
Loading