Skip to content

swap to using uv for project management#213

Merged
joshuadavidthomas merged 15 commits intomainfrom
uv
Apr 10, 2025
Merged

swap to using uv for project management#213
joshuadavidthomas merged 15 commits intomainfrom
uv

Conversation

@joshuadavidthomas
Copy link
Copy Markdown
Member

@joshuadavidthomas joshuadavidthomas commented Apr 9, 2025

Close #148

@joshuadavidthomas joshuadavidthomas requested a review from a team as a code owner April 9, 2025 21:52
Comment on lines -21 to -26
echo "result=$(gh run list \
--branch=main \
--workflow=test.yml \
--json headBranch,workflowName,conclusion \
--jq '.[] | select(.headBranch=="main" and .conclusion=="success") | .conclusion' \
| head -n 1)" >> $GITHUB_OUTPUT
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🍺 pours one out for this code.

- id: set-matrix
run: |
echo "matrix=$(python -m nox -l --json | jq -c '[.[] | select(.name == "tests") | {"python-version": .python, "django-version": .call_spec.django}] | {include: .}')" >> $GITHUB_OUTPUT
uv run nox --session "gha_matrix"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's amazing how much this cleans stuff up.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, much easier to see what's going on here:

@nox.session
def gha_matrix(session):
    sessions = session.run("nox", "-l", "--json", silent=True)
    matrix = {
        "include": [
            {
                "python-version": session["python"],
                "django-version": session["call_spec"]["django"],
            }
            for session in json.loads(sessions)
            if session["name"] == "tests"
        ]
    }
    with Path(os.environ["GITHUB_OUTPUT"]).open("a") as fh:
        print(f"matrix={matrix}", file=fh)

Arguably you could unroll the comprehension too to help readability.

Comment on lines +112 to +113
cache-from: type=gha
cache-to: type=gha,mode=max
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀 oh, is this the trick?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, mode=max caches everything about PRs indefinitely across GitHub causing the whole service to come to a standstill.

Comment thread .dockerfiles/Dockerfile
RUN --mount=type=cache,target=/root/.cache \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --locked --no-dev --no-install-project
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have been struggling with these options. Maybe you have the correct combo but mine was trying to re-download when I run uv run ...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh this is totally lifted from Hynek's article about how he builds his Dockerfiles with uv. https://hynek.me/articles/docker-uv/

Just giving it a try to see if it works before rolling it out anywhere else.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't seem like it's redownloading -- first pass took 13s, second one didn't even clock

➜ just docker smoke
docker build --file .dockerfiles/Dockerfile --tag docker-email-relay:local .
[+] Building 12.5s (17/17) FINISHED                                                                                                                                                                   docker:default
 => [internal] load build definition from Dockerfile                                                                                                                                                            0.0s
 => => transferring dockerfile: 1.19kB                                                                                                                                                                          0.0s
 => WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 5)                                                                                                                                  0.0s
 => WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 17)                                                                                                                                 0.0s
 => WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 28)                                                                                                                                 0.0s
 => [internal] load metadata for ghcr.io/astral-sh/uv:latest                                                                                                                                                    0.7s
 => [internal] load metadata for docker.io/library/python:3.13-slim                                                                                                                                             0.8s
 => [internal] load .dockerignore                                                                                                                                                                               0.0s
 => => transferring context: 153B                                                                                                                                                                               0.0s
 => [internal] load build context                                                                                                                                                                               0.0s
 => => transferring context: 12.72kB                                                                                                                                                                            0.0s
 => FROM ghcr.io/astral-sh/uv:latest@sha256:3362a526af7eca2fcd8604e6a07e873fb6e4286d8837cb753503558ce1213664                                                                                                    0.0s
 => [base 1/2] FROM docker.io/library/python:3.13-slim@sha256:21e39cf1815802d4c6f89a0d3a166cc67ce58f95b6d1639e68a394c99310d2e5                                                                                  0.0s
 => CACHED [base 2/2] COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv                                                                                                                             0.0s
 => CACHED [builder 1/4] RUN --mount=type=cache,target=/root/.cache     --mount=type=bind,source=uv.lock,target=uv.lock     --mount=type=bind,source=pyproject.toml,target=pyproject.toml     uv sync --locked  0.0s
 => [builder 2/4] COPY . /src                                                                                                                                                                                   0.2s
 => [builder 3/4] WORKDIR /src                                                                                                                                                                                  0.1s
 => [builder 4/4] RUN --mount=type=cache,target=/root/.cache     uv sync --locked --no-dev --no-editable --extra hc --extra psycopg --extra relay                                                               2.3s
 => CACHED [final 1/4] RUN mkdir -p /app                                                                                                                                                                        0.0s
 => [final 2/4] COPY --from=builder /app /app                                                                                                                                                                   1.2s
 => [final 3/4] RUN addgroup -gid "1000" --system django   && adduser -uid "1000" -gid "1000" --home /home/django --system django   && chown -R django:django /app                                              5.6s
 => [final 4/4] WORKDIR /app                                                                                                                                                                                    0.1s
 => exporting to image                                                                                                                                                                                          0.9s
 => => exporting layers                                                                                                                                                                                         0.9s
 => => writing image sha256:7fe7610cb55734c197c5089f347c1890aaf495e2cbf6c1c74edcf37bb77ee235                                                                                                                    0.0s
 => => naming to docker.io/library/docker-email-relay:local                                                                                                                                                     0.0s
docker run --rm docker-email-relay:local uv run -m email_relay.service --help
usage: service.py [-h]

Run the Django Email Relay service.

options:
  -h, --help  show this help message and exit

django-email-relay on  uv  v3.13.0 (django-email-relay) took 13s
➜ just docker smoke
docker build --file .dockerfiles/Dockerfile --tag docker-email-relay:local .
[+] Building 0.5s (17/17) FINISHED                                                                                                                                                                    docker:default
 => [internal] load build definition from Dockerfile                                                                                                                                                            0.0s
 => => transferring dockerfile: 1.19kB                                                                                                                                                                          0.0s
 => WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 5)                                                                                                                                  0.0s
 => WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 17)                                                                                                                                 0.0s
 => WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 28)                                                                                                                                 0.0s
 => [internal] load metadata for ghcr.io/astral-sh/uv:latest                                                                                                                                                    0.1s
 => [internal] load metadata for docker.io/library/python:3.13-slim                                                                                                                                             0.3s
 => [internal] load .dockerignore                                                                                                                                                                               0.0s
 => => transferring context: 153B                                                                                                                                                                               0.0s
 => [internal] load build context                                                                                                                                                                               0.0s
 => => transferring context: 6.92kB                                                                                                                                                                             0.0s
 => FROM ghcr.io/astral-sh/uv:latest@sha256:3362a526af7eca2fcd8604e6a07e873fb6e4286d8837cb753503558ce1213664                                                                                                    0.0s
 => [base 1/2] FROM docker.io/library/python:3.13-slim@sha256:21e39cf1815802d4c6f89a0d3a166cc67ce58f95b6d1639e68a394c99310d2e5                                                                                  0.0s
 => CACHED [base 2/2] COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv                                                                                                                             0.0s
 => CACHED [final 1/4] RUN mkdir -p /app                                                                                                                                                                        0.0s
 => CACHED [builder 1/4] RUN --mount=type=cache,target=/root/.cache     --mount=type=bind,source=uv.lock,target=uv.lock     --mount=type=bind,source=pyproject.toml,target=pyproject.toml     uv sync --locked  0.0s
 => CACHED [builder 2/4] COPY . /src                                                                                                                                                                            0.0s
 => CACHED [builder 3/4] WORKDIR /src                                                                                                                                                                           0.0s
 => CACHED [builder 4/4] RUN --mount=type=cache,target=/root/.cache     uv sync --locked --no-dev --no-editable --extra hc --extra psycopg --extra relay                                                        0.0s
 => CACHED [final 2/4] COPY --from=builder /app /app                                                                                                                                                            0.0s
 => CACHED [final 3/4] RUN addgroup -gid "1000" --system django   && adduser -uid "1000" -gid "1000" --home /home/django --system django   && chown -R django:django /app                                       0.0s
 => CACHED [final 4/4] WORKDIR /app                                                                                                                                                                             0.0s
 => exporting to image                                                                                                                                                                                          0.0s
 => => exporting layers                                                                                                                                                                                         0.0s
 => => writing image sha256:7fe7610cb55734c197c5089f347c1890aaf495e2cbf6c1c74edcf37bb77ee235                                                                                                                    0.0s
 => => naming to docker.io/library/docker-email-relay:local                                                                                                                                                     0.0s
docker run --rm docker-email-relay:local uv run -m email_relay.service --help
usage: service.py [-h]

Run the Django Email Relay service.

options:
  -h, --help  show this help message and exit

django-email-relay on  uv  v3.13.0 (django-email-relay)
➜

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it did, it just didn't show up in my prompt. 12.5s build time first pass, 0.5s second pass.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or wait, are you talking about uv run redownloading later in the same build? I've confused myself.

@joshuadavidthomas joshuadavidthomas merged commit f48ee08 into main Apr 10, 2025
22 checks passed
@joshuadavidthomas joshuadavidthomas deleted the uv branch April 10, 2025 03:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add tests for service docker image

2 participants