Skip to content

Commit

Permalink
Manage project environment with uv
Browse files Browse the repository at this point in the history
  • Loading branch information
sevein committed Sep 25, 2024
1 parent 7c7e19a commit 6e3f6a7
Show file tree
Hide file tree
Showing 25 changed files with 1,467 additions and 5,303 deletions.
5 changes: 4 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
**

!/requirements*
# We need .git to not be excluded from the context (hatch-vcs).
!/.git/**

!/a3m/**
!/.python-version
!/uv.lock
!/pyproject.toml
!/README.rst
!/LICENSE
Expand Down
101 changes: 18 additions & 83 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,93 +6,30 @@ on:
- main
jobs:
tests:
name: "Test on ${{ matrix.os }}"
runs-on: "${{ matrix.os }}-latest"
strategy:
fail-fast: false
matrix:
os:
- ubuntu
name: "Test"
runs-on: "ubuntu-22.04"
steps:
- name: "Check out source code"
uses: "actions/checkout@v4"
- name: "Install Python"
uses: "actions/setup-python@v4"
- name: Install the latest version of uv
uses: astral-sh/setup-uv@v2
with:
python-version: |
3.11
3.12
- name: "Restore cache"
id: "restore-cache"
uses: "actions/cache@v3"
enable-cache: true
version: latest
- name: Run tests
run: ./test.sh
- name: "Upload coverage report"
if: github.repository == 'artefactual-labs/a3m'
uses: "codecov/codecov-action@v4"
with:
path: |
.tox/
.venv/
key: "cache-python-${{ steps.setup-python.outputs.python-version }}-os-${{ runner.os }}-hash-${{ hashFiles('pyproject.toml', 'requirements.txt', 'requirements-dev.txt') }}"
- name: "Install tox"
if: "steps.restore-cache.outputs.cache-hit == false"
run: |
python -m venv .venv
.venv/bin/python -m pip install -U setuptools
.venv/bin/python -m pip install tox
- name: "Run tox"
run: |
.venv/bin/python -m tox -e py
- name: "Upload coverage data"
uses: actions/upload-artifact@v3
files: ./coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}
- name: Upload test results to Codecov
if: ${{ !cancelled() }}
uses: codecov/test-results-action@v1
with:
name: covdata
path: .coverage.*
coverage:
name: Coverage
needs: tests
runs-on: ubuntu-latest
steps:
- name: "Check out the repo"
uses: "actions/checkout@v4"
- name: "Set up Python"
uses: "actions/setup-python@v4"
with:
python-version-file: ".python-version"
cache: pip
cache-dependency-path: "requirements-dev.txt"
- name: "Install tox"
run: |
python -m pip install -U setuptools
python -m pip install tox
- name: "Download coverage data"
uses: actions/download-artifact@v3
with:
name: covdata
- name: "Combine and report"
run: |
python -m tox -e coverage
export TOTAL=$(python -c "import json;print(json.load(open('coverage.json'))['totals']['percent_covered_display'])")
echo "total=$TOTAL" >> $GITHUB_ENV
echo "### Total coverage: ${TOTAL}%" >> $GITHUB_STEP_SUMMARY
- name: "Codecov"
uses: codecov/codecov-action@v3
with:
files: coverage.xml
pre-commit:
name: "Run pre-commit"
runs-on: "ubuntu-latest"
steps:
- name: "Check out the repo"
uses: "actions/checkout@v4"
- name: "Set up Python"
uses: "actions/setup-python@v4"
with:
python-version-file: ".python-version"
cache: pip
cache-dependency-path: "requirements-dev.txt"
- name: "Install requirements"
run: |
python -m pip install -U setuptools
python -m pip install -r requirements-dev.txt
- name: "Run pre-commit"
run: tox -e pre-commit
files: ./junit.xml
token: ${{ secrets.CODECOV_TOKEN }}
e2e:
name: "Run E2E tests"
runs-on: ubuntu-latest
Expand Down Expand Up @@ -121,5 +58,3 @@ jobs:
-m a3m.cli.client \
--name=MARBLES \
https://github.com/artefactual/archivematica-sampledata/raw/master/SampleTransfers/Images/pictures/MARBLES.TGA
# TODO: main branch? push image to a3m:main
# TODO: and tagged? push image to a3m:${tag} and a3m:latest
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ coverage.*
# pytest's working directory
.cache
.pytest_cache

# tox working directory
.tox/
junit.xml

# mypy cache
.mypy_cache/
Expand Down
42 changes: 3 additions & 39 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
repos:

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
Expand All @@ -12,61 +11,26 @@ repos:
a3m/assets/.*\.json|
tests/server/fixtures/workflow-integration-test.json
)
- repo: https://github.com/PyCQA/doc8
rev: v1.1.2
hooks:
- id: doc8
files: ^docs/.*\.rst$

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.3
rev: v0.6.7
hooks:
- id: ruff
args:
- "--fix"
- "--exit-non-zero-on-fix"
- id: ruff-format

- repo: https://github.com/adamchainz/django-upgrade
rev: "1.21.0"
hooks:
- id: django-upgrade
args:
- "--target-version=4.2"

- repo: local
hooks:
- id: mypy
name: mypy
entry: mypy
language: system
types: [python]
pass_filenames: false
args:
- "a3m"

- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.4.5
rev: 0.4.16
hooks:
- id: pip-compile
args:
- "--python-version=3.12"
- "--output-file=requirements.txt"
- "pyproject.toml"
files: |
(?x)^(
pyproject.toml|
requirements.txt
)$
- id: pip-compile
args:
- "--python-version=3.12"
- "--output-file=requirements-dev.txt"
- "pyproject.toml"
- "--extra=dev"
files: |
(?x)^(
pyproject.toml|
requirements-dev.txt
)$
- id: uv-lock
2 changes: 1 addition & 1 deletion .python-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.12.5
3.12.6
13 changes: 6 additions & 7 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ version: 2
build:
os: "ubuntu-22.04"
tools:
python: "3.11"
jobs:
post_checkout:
- "git fetch --unshallow"
python: "3.12"
commands:
- pip install uv
- uv sync --frozen
- git fetch --unshallow
- .venv/bin/python -m sphinx -T -b html -d docs/_build/doctrees -D language=en docs $READTHEDOCS_OUTPUT/html
sphinx:
configuration: "docs/conf.py"
python:
install:
- requirements: "requirements-dev.txt"
11 changes: 11 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ See the fragment files in the `changelog.d directory`_.

.. scriv-insert-here
.. _changelog-0.8.0:

0.8.0 - 2024-09-25
==================

Changed
-------

- Use Python 3.12.6.
- Use ``uv`` to manage the project environment.

.. _changelog-0.7.14:

0.7.14 - 2024-09-24
Expand Down
97 changes: 44 additions & 53 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# syntax=docker/dockerfile:1.10.0-labs

ARG SYSTEM_IMAGE=ubuntu:22.04
ARG UV_VERSION=0.4.16
ARG USER_ID=1000
ARG GROUP_ID=1000

#
# Base
#

FROM ${SYSTEM_IMAGE} AS base

ARG USER_ID=1000
ARG GROUP_ID=1000

ENV DEBIAN_FRONTEND=noninteractive
ENV PYTHONUNBUFFERED=1

Expand Down Expand Up @@ -67,64 +69,53 @@ RUN set -ex \
uuid \
&& rm -rf /var/lib/apt/lists/*

# Python build.
RUN set -ex \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
libbz2-dev \
libffi-dev \
liblzma-dev \
libncursesw5-dev \
libreadline-dev \
libsqlite3-dev \
libssl-dev \
libxml2-dev \
libxmlsec1-dev \
tk-dev \
xz-utils \
zlib1g-dev

# Create a3m user
RUN set -ex \
&& groupadd --gid ${GROUP_ID} --system a3m \
&& useradd --uid ${USER_ID} --gid ${GROUP_ID} --create-home --home-dir /home/a3m --system a3m \
&& mkdir -p /home/a3m/.local/share/a3m/share \
&& chown -R a3m:a3m /home/a3m/.local
# -----------------------------------------------------------------------------

FROM ghcr.io/astral-sh/uv:${UV_VERSION} AS uv

#
# a3m
#
# -----------------------------------------------------------------------------

FROM base AS a3m

ARG DJANGO_SETTINGS_MODULE=a3m.settings.common
ENV DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE}
ENV PYENV_ROOT="/home/a3m/.pyenv"
ENV PATH=$PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH
ARG PYTHON_VERSION=""
ARG REQUIREMENTS=/a3m/requirements.txt
ARG USER_ID
ARG GROUP_ID

COPY ./.python-version /a3m/.python-version
RUN set -ex \
&& curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash \
&& if [ -z "${PYTHON_VERSION}" ]; then PYTHON_VERSION=$(cat /a3m/.python-version); fi \
&& pyenv install ${PYTHON_VERSION} \
&& pyenv global ${PYTHON_VERSION}

COPY ./requirements.txt /a3m/requirements.txt
COPY ./requirements-dev.txt /a3m/requirements-dev.txt
COPY ./pyproject.toml /a3m/pyproject.toml
# Create a3m user.
RUN set -ex \
&& pyenv exec python3 -m pip install --upgrade pip setuptools \
&& pyenv exec python3 -m pip install --requirement ${REQUIREMENTS} \
&& pyenv rehash
&& groupadd --gid ${GROUP_ID} --system a3m \
&& useradd --uid ${USER_ID} --gid ${GROUP_ID} --home-dir /home/a3m --system a3m \
&& mkdir -p /home/a3m/.local/share/a3m/share \
&& chown -R a3m:a3m /home/a3m

# Install uv.
COPY --from=uv /uv /bin/uv

COPY . /a3m
WORKDIR /a3m
RUN pip install . --no-deps
# Enable bytecode compilation.
ENV UV_COMPILE_BYTECODE=1

# Copy from the cache instead of linking since it's a mounted volume.
ENV UV_LINK_MODE=copy

# Change the current user.
USER a3m

ENTRYPOINT ["python", "-m", "a3m.cli.server"]
# Install the project into `/app`.
WORKDIR /app

# Install the project's dependencies using the lockfile and settings.
RUN --mount=type=cache,target=/home/a3m/.cache/uv,uid=${USER_ID},gid=${GROUP_ID} \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --frozen --no-install-project --no-dev

# Add the rest of the project source code and install it.
# Installing separately from its dependencies allows optimal layer caching.
COPY --exclude=.git . /app
RUN --mount=type=cache,target=/home/a3m/.cache/uv,uid=${USER_ID},gid=${GROUP_ID} \
--mount=type=bind,source=.git,target=.git \
uv sync --frozen --no-dev

# Place executables in the environment at the front of the path.
ENV PATH="/app/.venv/bin:$PATH"

CMD ["a3md"]
Loading

0 comments on commit 6e3f6a7

Please sign in to comment.