Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manage project environment with uv #464

Merged
merged 1 commit into from
Sep 25, 2024
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
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