ci: add semantic release and build/publish python wheel (#41)

Signed-off-by: Michele Dolfi <dol@zurich.ibm.com>
This commit is contained in:
Michele Dolfi
2025-02-13 16:49:43 +01:00
committed by GitHub
parent 1bf487b18e
commit 1615f977a2
16 changed files with 1480 additions and 693 deletions

49
.github/workflows/cd.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
name: "Run CD"
on:
workflow_dispatch:
jobs:
code-checks:
uses: ./.github/workflows/job-checks.yml
pre-release-check:
runs-on: ubuntu-latest
outputs:
TARGET_TAG_V: ${{ steps.version_check.outputs.TRGT_VERSION }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # for fetching tags, required for semantic-release
- uses: ./.github/actions/setup-poetry
- name: Check version of potential release
id: version_check
run: |
TRGT_VERSION=$(poetry run semantic-release print-version)
echo "TRGT_VERSION=${TRGT_VERSION}" >> "$GITHUB_OUTPUT"
echo "${TRGT_VERSION}"
- name: Check notes of potential release
run: poetry run semantic-release changelog --unreleased
release:
needs: [code-checks, pre-release-check]
if: needs.pre-release-check.outputs.TARGET_TAG_V != ''
environment: auto-release
runs-on: ubuntu-latest
concurrency: release
steps:
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.CI_APP_ID }}
private-key: ${{ secrets.CI_PRIVATE_KEY }}
- uses: actions/checkout@v4
with:
token: ${{ steps.app-token.outputs.token }}
fetch-depth: 0 # for fetching tags, required for semantic-release
- uses: ./.github/actions/setup-poetry
- name: Run release script
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
TARGET_VERSION: ${{ needs.pre-release-check.outputs.TARGET_TAG_V }}
CHGLOG_FILE: CHANGELOG.md
run: ./.github/scripts/release.sh
shell: bash

42
.github/workflows/ci-images-dryrun.yml vendored Normal file
View File

@@ -0,0 +1,42 @@
name: Dry run docling-serve image building
on:
workflow_call:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build_cpu_image:
name: Build docling-serve "CPU only" container image
permissions:
packages: write
contents: read
attestations: write
id-token: write
uses: ./.github/workflows/job-image.yml
with:
publish: false
build_args: |
--build-arg CPU_ONLY=true
ghcr_image_name: ds4sd/docling-serve-cpu
quay_image_name: ""
build_gpu_image:
name: Build docling-serve (with GPU support) container image
permissions:
packages: write
contents: read
attestations: write
id-token: write
uses: ./.github/workflows/job-image.yml
with:
publish: false
build_args: |
--build-arg CPU_ONLY=false
ghcr_image_name: ds4sd/docling-serve
quay_image_name: ""

25
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: "Run CI"
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
jobs:
code-checks:
# if: ${{ github.event_name == 'push' || (github.event.pull_request.head.repo.full_name != 'DS4SD/docling-serve' && github.event.pull_request.head.repo.full_name != 'ds4sd/docling-serve') }}
uses: ./.github/workflows/job-checks.yml
permissions:
packages: write
contents: read
attestations: write
id-token: write
build-images:
uses: ./.github/workflows/ci-images-dryrun.yml
permissions:
packages: write
contents: read
attestations: write
id-token: write

View File

@@ -1,105 +0,0 @@
name: Dry run docling-serve image building
on:
pull_request:
branches: ["main"]
env:
GHCR_REGISTRY: ghcr.io
GHCR_DOCLING_SERVE_CPU_IMAGE_NAME: ds4sd/docling-serve-cpu
GHCR_DOCLING_SERVE_GPU_IMAGE_NAME: ds4sd/docling-serve
jobs:
build_cpu_image:
name: Build docling-serve "CPU only" container image
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
attestations: write
id-token: write
steps:
- name: Check out the repo
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Extract metadata (tags, labels) for docling-serve (CPU only) ghcr image
id: ghcr_serve_cpu_meta
uses: docker/metadata-action@v5
with:
images: ${{ env.GHCR_REGISTRY }}/${{ env.GHCR_DOCLING_SERVE_CPU_IMAGE_NAME }}
- name: Build docling-serve-cpu image
id: build-serve-cpu-ghcr
uses: docker/build-push-action@v5
with:
context: .
push: false
tags: ${{ steps.ghcr_serve_cpu_meta.outputs.tags }}
labels: ${{ steps.ghcr_serve_cpu_meta.outputs.labels }}
platforms: linux/amd64, linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
file: Containerfile
build-args: |
--build-arg CPU_ONLY=true
- name: Remove Local Docker Images
run: |
docker image prune -af
build_gpu_image:
name: Build docling-serve (with GPU support) container image
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
attestations: write
id-token: write
steps:
- name: Check out the repo
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Extract metadata (tags, labels) for docling-serve (GPU) ghcr image
id: ghcr_serve_gpu_meta
uses: docker/metadata-action@v5
with:
images: ${{ env.GHCR_REGISTRY }}/${{ env.GHCR_DOCLING_SERVE_GPU_IMAGE_NAME }}
- name: Build docling-serve (GPU) image
id: build-serve-gpu-ghcr
uses: docker/build-push-action@v5
with:
context: .
push: false
tags: ${{ steps.ghcr_serve_gpu_meta.outputs.tags }}
labels: ${{ steps.ghcr_serve_gpu_meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
file: Containerfile
build-args: |
--build-arg CPU_ONLY=false

View File

@@ -7,190 +7,52 @@ on:
tags:
- 'v*'
env:
GHCR_REGISTRY: ghcr.io
GHCR_DOCLING_SERVE_CPU_IMAGE_NAME: ds4sd/docling-serve-cpu
GHCR_DOCLING_SERVE_GPU_IMAGE_NAME: ds4sd/docling-serve
QUAY_REGISTRY: quay.io
QUAY_DOCLING_SERVE_CPU_IMAGE_NAME: ds4sd/docling-serve-cpu
QUAY_DOCLING_SERVE_GPU_IMAGE_NAME: ds4sd/docling-serve
# env:
# GHCR_REGISTRY: ghcr.io
# # GHCR_DOCLING_SERVE_CPU_IMAGE_NAME: ds4sd/docling-serve-cpu
# # GHCR_DOCLING_SERVE_GPU_IMAGE_NAME: ds4sd/docling-serve
# QUAY_REGISTRY: quay.io
# # QUAY_DOCLING_SERVE_CPU_IMAGE_NAME: ds4sd/docling-serve-cpu
# # QUAY_DOCLING_SERVE_GPU_IMAGE_NAME: ds4sd/docling-serve
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build_and_publish_cpu_images:
name: Push docling-serve "CPU only" container image to GHCR and QUAY
runs-on: ubuntu-latest
environment: registry-creds
permissions:
packages: write
contents: read
attestations: write
id-token: write
secrets: inherit
steps:
- name: Check out the repo
uses: actions/checkout@v4
uses: ./.github/workflows/job-image.yml
with:
publish: true
environment: registry-creds
build_args: |
--build-arg CPU_ONLY=true
ghcr_image_name: ds4sd/docling-serve-cpu
quay_image_name: ds4sd/docling-serve-cpu
- name: Log in to the GHCR container image registry
uses: docker/login-action@v3
with:
registry: ${{ env.GHCR_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to the Quay container image registry
uses: docker/login-action@v3
with:
registry: ${{ env.QUAY_REGISTRY }}
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Extract metadata (tags, labels) for docling-serve (CPU only) ghcr image
id: ghcr_serve_cpu_meta
uses: docker/metadata-action@v5
with:
images: ${{ env.GHCR_REGISTRY }}/${{ env.GHCR_DOCLING_SERVE_CPU_IMAGE_NAME }}
- name: Build and push docling-serve-cpu image to ghcr.io
id: push-serve-cpu-ghcr
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.ghcr_serve_cpu_meta.outputs.tags }}
labels: ${{ steps.ghcr_serve_cpu_meta.outputs.labels }}
platforms: linux/amd64, linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
file: Containerfile
build-args: |
--build-arg CPU_ONLY=true
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.GHCR_REGISTRY }}/${{ env.GHCR_DOCLING_SERVE_CPU_IMAGE_NAME}}
subject-digest: ${{ steps.push-serve-cpu-ghcr.outputs.digest }}
push-to-registry: true
- name: Extract metadata (tags, labels) for docling-serve (CPU only) quay image
id: quay_serve_cpu_meta
uses: docker/metadata-action@v5
with:
images: ${{ env.QUAY_REGISTRY }}/${{ env.QUAY_DOCLING_SERVE_CPU_IMAGE_NAME }}
- name: Build and push docling-serve-cpu image to quay.io
id: push-serve-cpu-quay
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.quay_serve_cpu_meta.outputs.tags }}
labels: ${{ steps.quay_serve_cpu_meta.outputs.labels }}
platforms: linux/amd64, linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
file: Containerfile
build-args: |
--build-arg CPU_ONLY=true
- name: Remove Local Docker Images
run: |
docker image prune -af
build_and_publish_gpu_images:
name: Push docling-serve (with GPU support) container image to GHCR and QUAY
runs-on: ubuntu-latest
environment: registry-creds
permissions:
packages: write
contents: read
attestations: write
id-token: write
steps:
- name: Check out the repo
uses: actions/checkout@v4
uses: ./.github/workflows/job-image.yml
with:
publish: true
environment: registry-creds
build_args: |
--build-arg CPU_ONLY=false
ghcr_image_name: ds4sd/docling-serve
quay_image_name: ds4sd/docling-serve
- name: Log in to the GHCR container image registry
uses: docker/login-action@v3
with:
registry: ${{ env.GHCR_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to the Quay container image registry
uses: docker/login-action@v3
with:
registry: ${{ env.QUAY_REGISTRY }}
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Extract metadata (tags, labels) for docling-serve (GPU) ghcr image
id: ghcr_serve_gpu_meta
uses: docker/metadata-action@v5
with:
images: ${{ env.GHCR_REGISTRY }}/${{ env.GHCR_DOCLING_SERVE_GPU_IMAGE_NAME }}
- name: Build and push docling-serve (GPU) image to ghcr.io
id: push-serve-gpu-ghcr
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.ghcr_serve_gpu_meta.outputs.tags }}
labels: ${{ steps.ghcr_serve_gpu_meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
file: Containerfile
build-args: |
--build-arg CPU_ONLY=false
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.GHCR_REGISTRY }}/${{ env.GHCR_DOCLING_SERVE_GPU_IMAGE_NAME}}
subject-digest: ${{ steps.push-serve-gpu-ghcr.outputs.digest }}
push-to-registry: true
- name: Extract metadata (tags, labels) for docling-serve (GPU) quay image
id: quay_serve_gpu_meta
uses: docker/metadata-action@v5
with:
images: ${{ env.QUAY_REGISTRY }}/${{ env.QUAY_DOCLING_SERVE_GPU_IMAGE_NAME }}
- name: Build and push docling-serve (GPU) image to quay.io
id: push-serve-gpu-quay
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.quay_serve_gpu_meta.outputs.tags }}
labels: ${{ steps.quay_serve_gpu_meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
file: Containerfile
build-args: |
--build-arg CPU_ONLY=false

View File

@@ -1,20 +1,14 @@
name: Run linter checks
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
name: Run checks
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
on:
workflow_call:
jobs:
py-lint:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.11']
python-version: ['3.12']
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-poetry

145
.github/workflows/job-image.yml vendored Normal file
View File

@@ -0,0 +1,145 @@
name: Build docling-serve container image
on:
workflow_call:
inputs:
build_args:
type: string
description: "Extra build arguments for the build."
default: ""
ghcr_image_name:
type: string
description: "Name of the image for GHCR."
quay_image_name:
type: string
description: "Name of the image Quay."
platforms:
type: string
description: "Platform argument for building images."
default: linux/amd64, linux/arm64
publish:
type: boolean
description: "If true, the images will be published."
default: false
environment:
type: string
description: "GH Action environment"
default: ""
env:
GHCR_REGISTRY: ghcr.io
# GHCR_DOCLING_SERVE_CPU_IMAGE_NAME: ds4sd/docling-serve-cpu
# GHCR_DOCLING_SERVE_GPU_IMAGE_NAME: ds4sd/docling-serve
QUAY_REGISTRY: quay.io
# QUAY_DOCLING_SERVE_CPU_IMAGE_NAME: ds4sd/docling-serve-cpu
# QUAY_DOCLING_SERVE_GPU_IMAGE_NAME: ds4sd/docling-serve
jobs:
image:
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
attestations: write
id-token: write
environment: ${{ inputs.environment }}
steps:
- name: Free up space in github runner
# Free space as indicated here : https://github.com/actions/runner-images/issues/2840#issuecomment-790492173
run: |
df -h
sudo rm -rf "/usr/local/share/boost"
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
sudo rm -rf /usr/share/dotnet /opt/ghc /usr/local/lib/android /usr/local/share/powershell /usr/share/swift /usr/local/.ghcup
# shellcheck disable=SC2046
sudo docker rmi "$(docker image ls -aq)" >/dev/null 2>&1 || true
df -h
- name: Check out the repo
uses: actions/checkout@v4
- name: Log in to the GHCR container image registry
if: ${{ inputs.publish }}
uses: docker/login-action@v3
with:
registry: ${{ env.GHCR_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to the Quay container image registry
if: ${{ inputs.publish }}
uses: docker/login-action@v3
with:
registry: ${{ env.QUAY_REGISTRY }}
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Extract metadata (tags, labels) for docling-serve ghcr image
id: ghcr_meta
uses: docker/metadata-action@v5
with:
images: ${{ env.GHCR_REGISTRY }}/${{ inputs.ghcr_image_name }}
- name: Build and push image to ghcr.io
id: ghcr_push
uses: docker/build-push-action@v5
with:
context: .
push: ${{ inputs.publish }}
tags: ${{ steps.ghcr_meta.outputs.tags }}
labels: ${{ steps.ghcr_meta.outputs.labels }}
platforms: ${{ inputs.platforms}}
cache-from: type=gha
cache-to: type=gha,mode=max
file: Containerfile
build-args: ${{ inputs.build_args }}
# |
# --build-arg CPU_ONLY=true
- name: Generate artifact attestation
if: ${{ inputs.publish }}
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.GHCR_REGISTRY }}/${{ inputs.ghcr_image_name }}
subject-digest: ${{ steps.ghcr_push.outputs.digest }}
push-to-registry: true
- name: Extract metadata (tags, labels) for docling-serve quay image
if: ${{ inputs.publish }}
id: quay_meta
uses: docker/metadata-action@v5
with:
images: ${{ env.QUAY_REGISTRY }}/${{ inputs.quay_image_name }}
- name: Build and push image to quay.io
if: ${{ inputs.publish }}
# id: push-serve-cpu-quay
uses: docker/build-push-action@v5
with:
context: .
push: ${{ inputs.publish }}
tags: ${{ steps.quay_meta.outputs.tags }}
labels: ${{ steps.quay_meta.outputs.labels }}
platforms: ${{ inputs.platforms}}
cache-from: type=gha
cache-to: type=gha,mode=max
file: Containerfile
build-args: ${{ inputs.build_args }}
# |
# --build-arg CPU_ONLY=true
- name: Remove Local Docker Images
run: |
docker image prune -af

27
.github/workflows/pypi.yml vendored Normal file
View File

@@ -0,0 +1,27 @@
name: "Build and publish package"
on:
release:
types: [published]
permissions:
contents: read
jobs:
build-and-publish:
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/docling-serve # Replace <package-name> with your PyPI project name
permissions:
id-token: write # IMPORTANT: mandatory for trusted publishing
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-poetry
- name: Build
run: poetry build
- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
# currently not working with reusable workflows
attestations: false