Release and Pages automation¶
This page documents the release and documentation deployment parts of dpone CI/CD. For the complete release checklist, see Release.
Release path¶
sequenceDiagram
participant Dev as Maintainer
participant Git as GitHub master
participant GHA as GitHub Actions release.yml
participant Runtime as Runtime image workflow
participant PyPI as PyPI dpone
participant GHCR as GHCR dpone-runtime
Dev->>Git: Push annotated tag vX.Y.Z
Git->>GHA: Trigger Release workflow
Git->>Runtime: Trigger Runtime image workflow
GHA->>GHA: Validate exact tag, commit, versions, required checks
GHA->>GHA: Build and attest four wheel/sdist pairs
GHA->>PyPI: Publish via Trusted Publishing
PyPI-->>GHA: Release accepted
GHA->>PyPI: Verify exact filenames/SHA-256 + resolver install
PyPI-->>GHA: Candidate bytes installable
Runtime->>PyPI: Rebuild and match exact candidate bytes
Runtime->>Runtime: Build + smoke candidate
Runtime->>GHCR: Push ghcr.io/paulkov/dpone-runtime:X.Y.Z
Runtime->>GHCR: Pull and smoke sha256 digest
Runtime->>GHCR: Publish provenance + SBOM attestations
Trusted Publishing¶
Preferred PyPI publishing mode is Trusted Publishing through GitHub OIDC.
Expected PyPI Pending Publisher settings:
| Field | Value |
|---|---|
| Project | dpone |
| Owner | PaulKov |
| Repository | dpone |
| Workflow filename | release.yml |
| Environment | pypi |
The GitHub workflow uses environment pypi and id-token: write permission for the publish job.
Token fallback¶
Manual token fallback exists only for emergencies and only when the workflow is dispatched from the annotated release tag:
- Workflow input:
use_pypi_token=true. - GitHub secret:
PYPI_API_TOKEN. - Scope: package-specific PyPI token when possible.
If token mode is requested without the secret, the workflow fails before publication. Build and attestation jobs never receive this secret. After fallback use, rotate the token. Never use a token that has been pasted into chat, an issue, a PR, or logs.
Release checklist¶
Before tagging:
uv sync --all-extras
uv run ruff check .
uv run ruff format --check .
uv run mypy --config-file mypy.ini
uv run pytest -m "not integration_live" --cov=src/dpone --cov-report=xml
uv build
uv build packages/dpone-native-accel --out-dir dist
uv build packages/dpone-airflow-pack --out-dir dist
uv build packages/apache-airflow-providers-dpone --out-dir dist
uv run twine check dist/*
Then:
After publishing:
uv run python tools/pypi_release_smoke_dist.py \
--dist-dir dist \
--expected-version X.Y.Z \
--install-smoke \
--dpone-install-extra accel
If this check fails while the version-specific endpoint exists, either the
project/simple indexes are stale or public bytes do not match the immutable
candidate set. Do not announce the release as installable until every expected
wheel and sdist matches. The tag workflow uploads pypi-resolver-smoke with
pypi_release_smoke.md as 90-day release evidence.
Runtime image smoke:
image="ghcr.io/paulkov/dpone-runtime@sha256:${DPONE_RUNTIME_IMAGE_DIGEST:?set digest from runtime-image-evidence}"
docker run --rm "$image" --version
docker run --rm --entrypoint bcp "$image" -v
docker run --rm --entrypoint sqlcmd "$image" -?
docker run --rm --entrypoint clickhouse-client "$image" --version
docker run --rm "$image" runtime native-accel doctor --format json
docker run --rm "$image" airflow runtime-init-fetch --help
docker run --rm "$image" airflow runtime-pack-exec --help
GitHub Pages path¶
flowchart LR
DocsChange["docs/** or mkdocs.yml change"] --> Build["mkdocs build --strict"]
Build --> Artifact["Upload Pages artifact"]
Artifact --> Deploy["Deploy GitHub Pages"]
Deploy --> Site["paulkov.github.io/dpone"]
The docs workflow:
- builds on pull requests but does not deploy;
- builds and deploys on push to
master; - can be started manually;
- deploys through GitHub Actions Pages source.
Local preview:
Production build:
Pages runbook shortcuts¶
If the site is stale:
- Check the latest
docsworkflow run onmaster. - Check repository
Settings -> Pagesand confirm the source is GitHub Actions. - Confirm the changed page is reachable from MkDocs nav or from an indexed docs page.
If Mermaid renders as code:
- Confirm
mkdocs.ymlhaspymdownx.superfenceswith amermaidcustom fence. - Confirm the diagram block starts with
```mermaid. - Run
mkdocs build --strictand inspect generated HTML forclass="mermaid".