Skip to content

[DAPS-1800] - Python Client Build Script & CI Job#1811

Open
nedvedba wants to merge 8 commits intodevelfrom
feat-DAPS-1800-python-client-build-script-ci
Open

[DAPS-1800] - Python Client Build Script & CI Job#1811
nedvedba wants to merge 8 commits intodevelfrom
feat-DAPS-1800-python-client-build-script-ci

Conversation

@nedvedba
Copy link
Copy Markdown
Collaborator

@nedvedba nedvedba commented Dec 9, 2025

Ticket

#1800

Description

Added python client dockerfile, build script, and CI job.

How Has This Been Tested?

Run through CI job for both datafed pypi repos with successful deployments.

Tasks

  • - A description of the PR has been provided, and a diagram included if it is a new feature.
  • - Formatter has been run
  • - CHANGELOG comment has been added
  • - Labels have been assigned to the pr
  • - A reviwer has been added
  • - A user has been assigned to work on the pr
  • - If new feature a unit test has been added

Summary by Sourcery

Add Docker-based build and CI/CD pipeline support for the DataFed Python client, including image build, validation, and PyPI deployment.

Enhancements:

  • Adjust CMake Python client requirements copy to target the package directory rather than a specific filename.
  • Add Dockerfile for building the Python client package inside the dependencies image.
  • Add a helper script to build the Python package via Docker and extract distributions locally.

Build:

  • Add Dockerfile and build script to produce the Python client package artifacts using the DataFed dependencies image.
  • Introduce GitLab child pipeline configs to build and retag the python-client Docker image, including a forced-build variant.

CI:

  • Wire new Python client image-check and build jobs into the existing GitLab pipeline, using generated image configuration artifacts.
  • Include a dedicated GitLab stage and jobs for building and deploying the Python client package to PyPI with optional prerelease tagging.
  • Reference the new PyPI deployment stage from the main GitLab CI configuration.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai bot commented Dec 9, 2025

Reviewer's Guide

Adds a Docker-based build pipeline and GitLab CI jobs for the DataFed Python client, including an image for building/publishing the package to PyPI, a local build script, and wiring into existing image-check and deploy stages, plus a small CMake fix for requirements.txt copying and minor whitespace/formatting updates.

Sequence diagram for deploy:pypi:manual CI job uploading Python package to PyPI

sequenceDiagram
  participant Dev as Developer
  participant GL as GitLabCI
  participant Job as deploy:pypi:manual job
  participant Reg as DockerRegistry
  participant Img as datafed-python-client-deploy image
  participant PyPI as PyPI_Server

  Dev->>GL: Click manual job deploy:pypi:manual
  GL->>Job: Start job in stage deploy-pypi-package

  Job->>Reg: docker login ${REGISTRY} using HARBOR_USER and token
  Job->>Job: Compute DOWNSTREAM_SHA from external/DataFedDependencies submodule
  Job->>Job: Optionally modify cmake/Version.cmake

  Job->>Reg: Pull base dependencies image
  Job->>Img: docker build datafed-python-client-deploy:latest
  Note over Job,Img: Uses python/datafed_pkg/docker/Dockerfile
  Job->>Job: mkdir -p dist

  Job->>Img: docker run to copy /dist/* to CI dist/ directory

  Job->>Job: Restore Version.cmake if prerelease was enabled
  Job->>Job: ls -lh dist/ to verify artifacts

  Job->>Img: docker run twine upload dist/*
  Img->>PyPI: HTTPS upload of wheels and sdists
  PyPI-->>Img: Upload success response
  Img-->>Job: Twine exit code 0
  Job-->>GL: Job success with dist/ as artifact
  GL-->>Dev: Pipeline shows successful PyPI deployment
Loading

File-Level Changes

Change Details Files
Introduce Dockerfile and build script to build the DataFed Python client package inside a container and extract artifacts.
  • Add python/datafed_pkg/docker/Dockerfile that builds the Python client using the dependencies image, runs CMake with BUILD_PYTHON_CLIENT, builds the pydatafed target, installs Python build tools, installs requirements, and produces sdist/wheel artifacts exported to /dist.
  • Add scripts/build_python_package.sh to orchestrate a Docker build of the python-client image (using either registry or locally built dependencies image), then copy the built distributions out of the container into python/datafed_pkg/dist and print upload instructions.
python/datafed_pkg/docker/Dockerfile
scripts/build_python_package.sh
Add GitLab CI jobs and configuration to build, check, and deploy the Python client image and PyPI package.
  • Add .gitlab/build/build_python_client_image.yml defining a docker_build_script-based build-python-client job triggered on relevant path changes, plus a retag-image job for python-client images.
  • Add .gitlab/build/force_build_python_client_image.yml to always build the python-client image when invoked, using the same docker_build_script template.
  • Extend .gitlab/stage_image_check.yml with check-python-client-image using the shared .image_check template and appropriate PROJECT/COMPONENT variables.
  • Extend .gitlab/stage_build.yml with run-python-client-build-job that depends on run-build-dependencies and check-python-client-image and triggers the downstream python_client_image.yml artifact pipeline.
  • Introduce .gitlab/stage_deploy_pypi.yml defining reusable .deploy_pypi_base and a deploy:pypi:manual job that logs into the registry, optionally adjusts Version.cmake for prereleases, builds the python-client deploy image, extracts dist artifacts, and uploads them to PyPI via twine.
  • Include the new stage_deploy_pypi.yml in the main .gitlab-ci.yml so the deploy-pypi-package stage is available.
.gitlab/build/build_python_client_image.yml
.gitlab/build/force_build_python_client_image.yml
.gitlab/stage_image_check.yml
.gitlab/stage_build.yml
.gitlab/stage_deploy_pypi.yml
.gitlab-ci.yml
Adjust CMake Python client configuration so requirements.txt is copied into the package directory, and apply minor formatting tweaks to existing JS asset and docs files.
  • Change the CMakeLists.txt COPY command for requirements.txt to copy into the python/datafed_pkg/ directory instead of specifying the filename to ensure it is present where the Dockerfile expects.
  • Apply whitespace-only edits and minor line-wrapping adjustments in the CoffeeScript worker JS bundle and a static html5shiv JS asset (no functional changes).
CMakeLists.txt
web/static/ace/worker-coffee.js
docs/_static/js/html5shiv-printshiv.min.js

Possibly linked issues

  • #[Feature] Python Client Build Script & Automated CI Deployments: PR adds Dockerfile, build script, and GitLab CI jobs that implement the requested Python client build and PyPI deploy.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • The COMPONENT name for the Python client is inconsistent between jobs (e.g., python-client in .gitlab/build/build_python_client_image.yml vs python_client in the image-check and deploy configs), which will likely break shared registry paths and helper scripts that depend on a consistent COMPONENT; consider standardizing on a single identifier.
  • The Docker build invocation and dependency image resolution logic are duplicated between scripts/build_python_package.sh and .gitlab/stage_deploy_pypi.yml; extracting the common logic into a shared script or template would reduce the chance of the two paths diverging over time.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The COMPONENT name for the Python client is inconsistent between jobs (e.g., `python-client` in `.gitlab/build/build_python_client_image.yml` vs `python_client` in the image-check and deploy configs), which will likely break shared registry paths and helper scripts that depend on a consistent COMPONENT; consider standardizing on a single identifier.
- The Docker build invocation and dependency image resolution logic are duplicated between `scripts/build_python_package.sh` and `.gitlab/stage_deploy_pypi.yml`; extracting the common logic into a shared script or template would reduce the chance of the two paths diverging over time.

## Individual Comments

### Comment 1
<location> `.gitlab-ci.yml:29` </location>
<code_context>
     - local: .gitlab/stage_test.yml
     - local: .gitlab/stage_unit.yml
     - local: .gitlab/end_to_end.yml
+    - local: .gitlab/stage_deploy_pypi.yml

 stages:
</code_context>

<issue_to_address>
**issue (bug_risk):** New `deploy-pypi-package` stage is not added to the global `stages:` list, so jobs in that stage may never run

`.deploy_pypi_base` in `.gitlab/stage_deploy_pypi.yml` is configured with `stage: deploy-pypi-package`, but that stage is not declared in the root `.gitlab-ci.yml` `stages:` list. Please add `deploy-pypi-package` there so these jobs run in the correct stage and pipeline order.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@nedvedba nedvedba self-assigned this Dec 9, 2025
@nedvedba nedvedba added Component: Python API Relates to Python API Component: Build Related to the build system Component: Scripts Helper scripts or admin scripts Component: CI labels Dec 9, 2025
@nedvedba nedvedba requested a review from JoshuaSBrown December 9, 2025 03:58
@JoshuaSBrown
Copy link
Copy Markdown
Collaborator

JoshuaSBrown commented Dec 9, 2025

@nedvedba, what was the reason for creating a whole new Dockerfile, there is already one in python/docker/Dockerfile for the client.

It would probably make a lot of sense to have a single Dockerfile that is building the client possibly with a layer that will spit outs the python package. The dockerfiles in python/docker/ are a bit dated anyways.

If you want an example of intermediate image builds take a look at the the web Dockerfile.

Comment on lines +78 to +83
# Manual deployment job - can be triggered via button in GitLab UI
deploy:pypi:manual:
extends: .deploy_pypi_base
when: manual
rules:
- when: manual
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think this is the best choice too.

@JoshuaSBrown
Copy link
Copy Markdown
Collaborator

Another point, when making print statements in the scripts. I would recommend prepending:
TRACE -
INFO -
DEBUG -
ERROR -
WARNING -

As is appropriate similar to what we are trying to do elsewhere in the repo and logs.

@JoshuaSBrown JoshuaSBrown changed the title Python Client Build Script & CI Job [DAPS-1800] - Python Client Build Script & CI Job Jan 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Component: Build Related to the build system Component: CI Component: Python API Relates to Python API Component: Scripts Helper scripts or admin scripts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants