Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
c6df4a1
Merge pull request #315 from ral-facilities/main
VKTB May 15, 2026
df04f41
Migrate project from pip to uv #299
VKTB Jun 22, 2026
afbfb1a
Add .python-version file #299
VKTB Jun 22, 2026
f729cf5
Configure uv to limit candidate packages before a specific publish da…
VKTB Jun 22, 2026
133f778
Update Dockerfile #299
VKTB Jun 22, 2026
163c877
Update README #299
VKTB Jun 22, 2026
d033b6e
Replace pip with uv Dependabot config #299
VKTB Jun 22, 2026
18315d0
Configure Dependabot to delay updates for a configurable number of da…
VKTB Jun 22, 2026
029794b
Switch to uv in CI GitHub Actions workflow #299
VKTB Jun 22, 2026
7910426
Regenerate uv.lock file following exclude-newer uv configuration #299
VKTB Jun 22, 2026
c24f4eb
Fix failing Dockerfile prod stage #299
VKTB Jun 22, 2026
b776c95
Add newline at the end of dependabot.yml file #299
VKTB Jun 23, 2026
64da9b0
Merge pull request #330 from ral-facilities/migrate-to-uv-#299
VKTB Jun 23, 2026
7737815
Bump python from `db66119` to `399babc`
dependabot[bot] Jun 23, 2026
93109f0
Bump the github-actions group across 1 directory with 6 updates
dependabot[bot] Jun 23, 2026
da09176
Update uv-build requirement from <0.12.0,>=0.11.13 to >=0.11.21,<0.12.0
dependabot[bot] Jun 23, 2026
e5bad69
Merge pull request #333 from ral-facilities/dependabot/github_actions…
VKTB Jun 23, 2026
7614c38
Merge pull request #335 from ral-facilities/dependabot/uv/develop/uv-…
VKTB Jun 23, 2026
966e35b
Bump the uv group across 1 directory with 2 updates
dependabot[bot] Jun 23, 2026
fb0fe45
Merge pull request #334 from ral-facilities/dependabot/uv/develop/uv-…
VKTB Jun 23, 2026
8d685f1
Bump actions/checkout from 6.0.3 to 7.0.0 in the github-actions group
dependabot[bot] Jun 24, 2026
c53eeed
Merge pull request #336 from ral-facilities/dependabot/github_actions…
VKTB Jun 25, 2026
31cc40a
Merge pull request #332 from ral-facilities/dependabot/docker/develop…
VKTB Jun 25, 2026
d306668
Add .python-version file to Dockerfile stages #338
VKTB Jun 25, 2026
0771865
Replace invalid .python-version file not detected during Docker build…
VKTB Jun 25, 2026
e2d4a8d
Merge pull request #339 from ral-facilities/dockerfile-missing-python…
VKTB Jun 26, 2026
38442ac
Bump the uv group across 1 directory with 3 updates
dependabot[bot] Jun 29, 2026
f350473
Merge pull request #341 from ral-facilities/dependabot/uv/develop/uv-…
VKTB Jun 29, 2026
79e0167
Update uv-build requirement from <0.12.0,>=0.11.21 to >=0.11.23,<0.12.0
dependabot[bot] Jun 29, 2026
12790a3
Fix casing for PyJWT dependency in pyproject.toml #342
VKTB Jun 29, 2026
c764b68
Merge pull request #343 from ral-facilities/fix-dependabot-update-fai…
VKTB Jun 29, 2026
85a9f6a
Update pyjwt dependency version in pyproject.toml to match that of uv…
VKTB Jun 29, 2026
accea9b
Regenerate file to fix uv build error #344
VKTB Jun 29, 2026
aa34311
Merge pull request #345 from ral-facilities/pyjwt-dependency-version-…
VKTB Jun 29, 2026
e27cefb
Merge pull request #340 from ral-facilities/dependabot/uv/develop/uv-…
VKTB Jun 29, 2026
0790b4e
Update project version to v1.4.0
VKTB Jun 29, 2026
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
26 changes: 21 additions & 5 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ updates:
interval: daily
time: "08:00"
timezone: "Europe/London"
cooldown:
default-days: 7
target-branch: "develop"
ignore:
- dependency-name: "python"
Expand All @@ -19,6 +21,8 @@ updates:
interval: daily
time: "08:00"
timezone: "Europe/London"
cooldown:
default-days: 7
target-branch: "main"
ignore:
- dependency-name: "python"
Expand All @@ -30,6 +34,8 @@ updates:
schedule:
# Check for updates every week
interval: "weekly"
cooldown:
default-days: 7
target-branch: "develop"
# Update multiple dependencies at the same time
groups:
Expand All @@ -43,21 +49,31 @@ updates:
schedule:
# Check for updates every week
interval: "weekly"
cooldown:
default-days: 7
target-branch: "main"
# Update multiple dependencies at the same time
groups:
github-actions:
patterns:
- "*"

# Maintain pip dependencies
- package-ecosystem: "pip"
# Maintain uv dependencies on the `develop` branch
- package-ecosystem: "uv"
directory: "/"
schedule:
# Check for updates every week
interval: "weekly"
# Update multiple dependencies at the same time
cooldown:
default-days: 7
target-branch: "develop"
groups:
pip:
uv:
patterns:
- "*"
- "*"
# Dependabot can check the lockfile, but cannot update these detected in pyproject.toml. As updates are grouped
# this causes all updates within the group to be skipped.
# E.g. `Skipping change to group uv in directory /: Previous version was not provided for: 'uv-build'`
exclude-patterns:
- "uv-build"
- "object-storage-api"
36 changes: 16 additions & 20 deletions .github/workflows/.ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,28 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
python-version: "3.13"
cache: "pip"
version: "0.11.21"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install .[code-analysis]
python -m pip install -r requirements.txt
run: uv sync

- name: Run black
run: black --check --line-length 120 object_storage_api test
run: uv run black --check --line-length 120 object_storage_api test

- name: Run pylint
run: pylint object_storage_api test
run: uv run pylint object_storage_api test

unit-tests:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- name: Create logging configuration file
run: cp logging.example.ini logging.ini
Expand All @@ -58,12 +54,12 @@ jobs:
--name object-storage-api \
--volume ./logging.ini:/app/logging.ini \
object-storage-api:test \
pytest --config-file test/pytest.ini --cov object_storage_api --cov-report xml test/unit -v
/app/.venv/bin/pytest --config-file test/pytest.ini --cov object_storage_api --cov-report xml test/unit -v
docker cp object-storage-api:/app/coverage.xml coverage.xml

- name: Upload coverage reports to Codecov
if: success()
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with:
token: ${{ secrets.CODECOV_TOKEN }}

Expand All @@ -73,7 +69,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- name: Create logging configuration file
run: cp logging.example.ini logging.ini
Expand All @@ -95,7 +91,7 @@ jobs:
--volume ./logging.ini:/app/logging.ini \
--add-host localhost:host-gateway \
object-storage-api:test \
pytest --config-file test/pytest.ini test/e2e -v
/app/.venv/bin/pytest --config-file test/pytest.ini test/e2e -v

- name: Output docker logs (mongodb)
if: failure()
Expand All @@ -115,24 +111,24 @@ jobs:
PUSH_DOCKER_IMAGE_TO_HARBOR: ${{ inputs.push-docker-image-to-harbor != null && inputs.push-docker-image-to-harbor || 'false' }}
steps:
- name: Check out repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
with:
images: ${{ vars.HARBOR_URL }}/object-storage-api

- name: Login to Harbor
if: ${{ fromJSON(env.PUSH_DOCKER_IMAGE_TO_HARBOR) }}
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ${{ vars.HARBOR_URL }}
username: ${{ secrets.HARBOR_USERNAME }}
password: ${{ secrets.HARBOR_TOKEN }}

- name: ${{ fromJSON(env.PUSH_DOCKER_IMAGE_TO_HARBOR) && 'Build and push Docker image to Harbor' || 'Build Docker image' }}
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .
push: ${{ fromJSON(env.PUSH_DOCKER_IMAGE_TO_HARBOR) }}
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- name: Login to Harbor
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ${{ vars.HARBOR_URL }}
username: ${{ secrets.HARBOR_USERNAME }}
password: ${{ secrets.HARBOR_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
with:
images: ${{ vars.HARBOR_URL }}/object-storage-api
tags: |
Expand All @@ -34,7 +34,7 @@ jobs:
latest=false

- name: Build and push Docker image to Harbor
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .
push: true
Expand Down
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.13
83 changes: 67 additions & 16 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,55 +1,106 @@
FROM python:3.13.13-alpine3.23@sha256:420cd0bf0f3998275875e02ecd5808168cf0843cbb4d3c536432f729247b2acc AS base
########################################################################################################################
# Base stage, includes uv
########################################################################################################################
FROM python:3.13.14-alpine3.24@sha256:399babc8b49529dabfd9c922f2b5eea81d611e4512e3ed250d75bd2e7683f4b0 AS base
COPY --from=ghcr.io/astral-sh/uv:0.11.21@sha256:ff07b86af50d4d9391d9daf4ff89ce427bc544f9aae87057e69a1cc0aa369946 /uv /uvx /bin/

# 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
# Disable use of uv-managed Python versions
ENV UV_NO_MANAGED_PYTHON=1
# Disable Python downloads so that the system interpreter is used across images
ENV UV_PYTHON_DOWNLOADS=0

WORKDIR /app

COPY pyproject.toml requirements.txt ./
COPY object_storage_api/ object_storage_api/
COPY pyproject.toml uv.lock .python-version README.md ./


########################################################################################################################
# Stage for local development
########################################################################################################################
FROM base AS dev

WORKDIR /app

RUN --mount=type=cache,target=/root/.cache \
RUN --mount=type=cache,target=/root/.cache/uv \
set -eux; \
\
pip install --no-cache-dir .[dev]; \
# Ensure the pinned versions of the production dependencies and subdependencies are installed \
pip install --no-cache-dir --requirement requirements.txt;
# Lock and install all dependencies but do not install the project \
uv sync --locked --no-install-project;

COPY object_storage_api/ object_storage_api/

RUN --mount=type=cache,target=/root/.cache/uv \
set -eux; \
\
# Install the project \
uv sync --locked;

CMD ["fastapi", "dev", "object_storage_api/main.py", "--host", "0.0.0.0", "--port", "8000"]

CMD ["/app/.venv/bin/fastapi", "dev", "object_storage_api/main.py", "--host", "0.0.0.0", "--port", "8000"]

EXPOSE 8000


########################################################################################################################
# Stage for running tests
########################################################################################################################
FROM dev AS test

WORKDIR /app

COPY test/ test/

CMD ["pytest", "--config-file", "test/pytest.ini", "-v"]
CMD ["/app/.venv/bin/pytest", "--config-file", "test/pytest.ini", "-v"]


########################################################################################################################
# Stage for production-ready build of the project
########################################################################################################################
FROM base AS prod-build

FROM base AS prod
# Omit development dependencies
ENV UV_NO_DEV=1

WORKDIR /app

RUN --mount=type=cache,target=/root/.cache \
RUN --mount=type=cache,target=/root/.cache/uv \
set -eux; \
\
# Lock and install all dependencies but do not install the project \
uv sync --locked --no-install-project;

COPY object_storage_api/ object_storage_api/

RUN --mount=type=cache,target=/root/.cache/uv \
set -eux; \
\
# Ensure the package gets installed properly using the pyproject.toml file \
pip install --no-cache-dir .; \
# Ensure the pinned versions of the production dependencies and subdependencies are installed \
pip install --no-cache-dir --requirement requirements.txt; \
# Install the project \
uv sync --locked;


########################################################################################################################
# Minimal production-ready image
########################################################################################################################
# The same image that matches the build stage must be used as the path to the Python executable must be the same.
FROM python:3.13.14-alpine3.24@sha256:399babc8b49529dabfd9c922f2b5eea81d611e4512e3ed250d75bd2e7683f4b0 AS prod

WORKDIR /app

RUN set -eux; \
\
# Create a non-root user to run as \
addgroup -g 500 -S object-storage-api; \
adduser -S -D -G object-storage-api -H -u 500 -h /app object-storage-api;

# Copy the application from the prod-build stage
COPY --from=prod-build /app /app

USER object-storage-api

CMD ["fastapi", "run", "object_storage_api/main.py", "--host", "0.0.0.0", "--port", "8000"]
CMD ["/app/.venv/bin/fastapi", "run", "object_storage_api/main.py", "--host", "0.0.0.0", "--port", "8000"]

EXPOSE 8000
Loading