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
88 changes: 72 additions & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@ name: CI

on:
workflow_call:
inputs:
release-version:
description: Exact package version for a release-candidate build
required: false
type: string
push:
branches: [main, develop]
pull_request:
branches: [main]

permissions:
contents: read
Expand All @@ -18,6 +24,16 @@ concurrency:
cancel-in-progress: true

jobs:
dependency-review:
name: Dependency Review
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0

lint:
name: Lint
runs-on: ubuntu-latest
Expand Down Expand Up @@ -251,6 +267,8 @@ jobs:
documentation:
name: Documentation
runs-on: ubuntu-latest
env:
RELEASE_VERSION: ${{ inputs.release-version }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

Expand All @@ -265,29 +283,41 @@ jobs:
- name: Install documentation dependencies
run: uv sync --dev --extra docs --locked

- name: Record documentation identity
run: |
version="$RELEASE_VERSION"
if test -z "$version"; then
version="$(uv run python -c 'import ml4t.backtest as package; print(package.__version__)')"
fi
echo "ML4T_DOCS_VERSION=$version" >> "$GITHUB_ENV"
echo "ML4T_DOCS_COMMIT=$GITHUB_SHA" >> "$GITHUB_ENV"

- name: Build documentation with strict validation
run: uv run mkdocs build --strict

- name: Build candidate wheel for documentation examples
run: uv build --wheel --out-dir "$RUNNER_TEMP/docs-wheel"

- name: Install candidate wheel in an isolated environment
run: |
uv venv "$RUNNER_TEMP/docs-venv"
uv pip install \
--python "$RUNNER_TEMP/docs-venv/bin/python" \
"$RUNNER_TEMP"/docs-wheel/*.whl

- name: Execute selected documentation examples against the wheel
- name: Verify rendered documentation identity
run: >-
"$RUNNER_TEMP/docs-venv/bin/python"
validation/check_documentation_examples.py
uv run python validation/check_documentation_identity.py
--site site
--expected-library backtest
--expected-version "$ML4T_DOCS_VERSION"
--expected-commit "$ML4T_DOCS_COMMIT"

- name: Retain immutable documentation artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: docs-${{ github.sha }}
path: site/
if-no-files-found: error
retention-days: 90

build:
name: Build Package
runs-on: ubuntu-latest
needs:
[lint, typecheck, compatibility, security, coverage, runtime, public-parity, documentation]
env:
RELEASE_VERSION: ${{ inputs.release-version }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand All @@ -302,17 +332,37 @@ jobs:
run: uv python install ${{ env.PYTHON_VERSION }}

- name: Build package
run: uv build
run: |
if test -n "$RELEASE_VERSION"; then
export SETUPTOOLS_SCM_PRETEND_VERSION="$RELEASE_VERSION"
fi
uv build

- name: Rebuild package for reproducibility
run: uv build --out-dir dist-rebuild
run: |
if test -n "$RELEASE_VERSION"; then
export SETUPTOOLS_SCM_PRETEND_VERSION="$RELEASE_VERSION"
fi
uv build --out-dir dist-rebuild

- name: Validate distribution contents and reproducibility
run: uv run python validation/check_artifacts.py dist --compare dist-rebuild

- name: Validate package metadata and long description
run: uvx twine check dist/*

- name: Install the candidate wheel in a clean environment
run: |
uv venv --clear --python "${{ env.PYTHON_VERSION }}" "$RUNNER_TEMP/candidate-venv"
uv pip install \
--python "$RUNNER_TEMP/candidate-venv/bin/python" \
dist/*.whl

- name: Execute the documented quick starts against the wheel
run: >-
"$RUNNER_TEMP/candidate-venv/bin/python"
validation/check_documentation_examples.py

- name: Verify source provenance
run: |
test "$(git rev-parse HEAD)" = "$GITHUB_SHA"
Expand All @@ -322,10 +372,15 @@ jobs:
run: |
mkdir -p release-candidate/dist
cp dist/* release-candidate/dist/
version_args=()
if test -n "$RELEASE_VERSION"; then
version_args=(--expected-version "$RELEASE_VERSION")
fi
uv run python validation/release_candidate.py create \
--dist release-candidate/dist \
--commit "$GITHUB_SHA" \
--repository "$GITHUB_REPOSITORY" \
"${version_args[@]}" \
--gate compatibility=${{ needs.compatibility.result }} \
--gate correctness=${{ needs.public-parity.result }} \
--gate coverage=${{ needs.coverage.result }} \
Expand All @@ -341,7 +396,8 @@ jobs:
--dist release-candidate/dist \
--manifest release-candidate/release-candidate.json \
--expected-commit "$GITHUB_SHA" \
--expected-repository "$GITHUB_REPOSITORY"
--expected-repository "$GITHUB_REPOSITORY" \
"${version_args[@]}"

- name: Upload exact release candidate
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ on:
env:
UV_NO_SOURCES: "1"

permissions:
contents: read

jobs:
stable:
name: Stable (${{ matrix.os }}, Python ${{ matrix.python-version }})
Expand Down
35 changes: 21 additions & 14 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ concurrency:

jobs:
build:
name: Build & Deploy Docs
name: Build Docs
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand All @@ -30,21 +30,28 @@ jobs:
run: uv python install 3.12

- name: Install dependencies
run: uv sync --dev --extra docs
run: uv sync --dev --extra docs --locked

- name: Record documentation identity
run: |
echo "ML4T_DOCS_VERSION=$(uv run python -c 'import ml4t.backtest as package; print(package.__version__)')" >> "$GITHUB_ENV"
echo "ML4T_DOCS_COMMIT=$GITHUB_SHA" >> "$GITHUB_ENV"

- name: Build docs
run: uv run mkdocs build --strict

- name: Deploy to website repo
uses: cpina/github-action-push-to-another-repository@55306faa4ed53b815ae49e564af8cfb359d32ae2 # v1.7.3
env:
SSH_DEPLOY_KEY: ${{ secrets.DOCS_DEPLOY_KEY }}
- name: Verify rendered documentation identity
run: >-
uv run python validation/check_documentation_identity.py
--site site
--expected-library backtest
--expected-version "$ML4T_DOCS_VERSION"
--expected-commit "$ML4T_DOCS_COMMIT"

- name: Retain immutable documentation artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
source-directory: site/
destination-github-username: ml4t
destination-repository-name: website
target-directory: static/docs/backtest/
target-branch: main
commit-message: "docs(backtest): update from ml4t/backtest@${{ github.sha }}"
user-name: ml4t-bot
user-email: bot@ml4trading.io
name: docs-${{ github.sha }}
path: site/
if-no-files-found: error
retention-days: 90
4 changes: 2 additions & 2 deletions .github/workflows/private-comparisons.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
version: "latest"

Expand Down Expand Up @@ -74,7 +74,7 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
version: "latest"

Expand Down
Loading
Loading