Skip to content
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
71 changes: 71 additions & 0 deletions .github/actions/python-distributions/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Verify Python distributions
description: Build and test SDK distributions with their declared dependencies.

inputs:
source-directory:
description: Path to the SDK project (requires Python 3.12).
required: true

outputs:
dist-directory:
description: Absolute path to the verified wheel and source distribution.
value: ${{ steps.build.outputs.dist-directory }}

runs:
using: composite
steps:
- name: Install packaging tools
shell: bash
run: python -m pip install 'build>=1.2,<2' 'twine>=5,<7'

- name: Build distributions
id: build
shell: bash
env:
SOURCE_DIRECTORY: ${{ inputs.source-directory }}
run: |
dist_directory="$(mktemp -d "${RUNNER_TEMP}/akernel-dist.XXXXXX")"
python -m build --outdir "${dist_directory}" "${SOURCE_DIRECTORY}"
test "$(find "${dist_directory}" -maxdepth 1 -name '*.whl' | wc -l)" -eq 1
test "$(find "${dist_directory}" -maxdepth 1 -name '*.tar.gz' | wc -l)" -eq 1
python -m twine check "${dist_directory}"/*
echo "dist-directory=${dist_directory}" >> "${GITHUB_OUTPUT}"

- name: Test installed distributions
shell: bash
env:
SOURCE_DIRECTORY: ${{ inputs.source-directory }}
DIST_DIRECTORY: ${{ steps.build.outputs.dist-directory }}
run: |
EXPECTED_VERSION="$(python - <<'PY'
import os
import pathlib
import tomllib

path = pathlib.Path(os.environ["SOURCE_DIRECTORY"]) / "pyproject.toml"
with path.open("rb") as stream:
print(tomllib.load(stream)["project"]["version"])
PY
)"
export EXPECTED_VERSION

for artifact in "${DIST_DIRECTORY}"/*.whl "${DIST_DIRECTORY}"/*.tar.gz; do
test_env="$(mktemp -d "${RUNNER_TEMP}/akernel-install.XXXXXX")"
python -m venv "${test_env}"
"${test_env}/bin/python" -m pip install "${artifact}"
"${test_env}/bin/python" -m pip check
"${test_env}/bin/python" -I - <<'PY'
import os
from importlib.metadata import distribution, version

import akernel_sdk

assert version("akernel-sdk") == os.environ["EXPECTED_VERSION"]
assert any(
entry.name == "ak" and entry.value == "akernel_sdk.cli:main"
for entry in distribution("akernel-sdk").entry_points
)
assert akernel_sdk.__name__ == "akernel_sdk"
PY
"${test_env}/bin/ak" --help
done
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,27 @@ jobs:
run: |
make sdk-check

sdk-distributions:
name: Python SDK distributions
runs-on: ubuntu-latest
timeout-minutes: 15

steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.12"
cache: pip
cache-dependency-path: sdk/python/pyproject.toml

- name: Build and verify distributions
uses: ./.github/actions/python-distributions
with:
source-directory: sdk/python

deployment-script-syntax:
name: Deployment script syntax
runs-on: ubuntu-latest
Expand Down
34 changes: 7 additions & 27 deletions .github/workflows/release-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,43 +67,23 @@ jobs:
- name: Install build dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e './sdk/python[dev]' 'twine>=5,<7'
python -m pip install -e './sdk/python[dev]'

- name: Check SDK
run: |
make sdk-check

- name: Build distributions
run: |
rm -rf sdk/python/dist
python -m build --outdir sdk/python/dist sdk/python
test "$(find sdk/python/dist -maxdepth 1 -name '*.whl' | wc -l)" -eq 1
test "$(find sdk/python/dist -maxdepth 1 -name '*.tar.gz' | wc -l)" -eq 1
python -m twine check sdk/python/dist/*

- name: Test installed wheel
run: |
python -m venv /tmp/akernel-wheel-test
/tmp/akernel-wheel-test/bin/python -m pip install \
--no-deps sdk/python/dist/*.whl
/tmp/akernel-wheel-test/bin/python - <<'PY'
from importlib.metadata import distribution, version

import akernel_sdk

assert version("akernel-sdk") == "${{ github.event.release.tag_name }}".removeprefix("v")
assert any(
entry.name == "ak" and entry.value == "akernel_sdk.cli:main"
for entry in distribution("akernel-sdk").entry_points
)
assert akernel_sdk.__name__ == "akernel_sdk"
PY
- name: Build and verify distributions
id: distributions
uses: ./.github/actions/python-distributions
with:
source-directory: sdk/python

- name: Upload distributions
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: python-distributions
path: sdk/python/dist/
path: ${{ steps.distributions.outputs.dist-directory }}
if-no-files-found: error
retention-days: 7

Expand Down
5 changes: 5 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,11 @@ the wheel and source distribution, and publishes them through the PyPI trusted
publisher configured for the `pypi` GitHub environment. Do not add a PyPI
password or API token to the repository.

PR CI and publishing share `.github/actions/python-distributions`, which
builds the wheel and source distribution and installs each in a separate clean
environment with its declared dependencies. Keep dependency validation,
isolated imports, version checks, and CLI smoke tests in this shared action.

## Test

Run SDK unit tests with:
Expand Down