Skip to content
Open
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
50 changes: 49 additions & 1 deletion .github/workflows/deploy_pkg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
release:
types:
- published
workflow_dispatch:

jobs:
build:
Expand All @@ -14,6 +15,7 @@ jobs:
- uses: actions/checkout@v4
with:
persist-credentials: false
fetch-depth: 0 # Required for dynamic versioning

- name: Install python
uses: actions/setup-python@v5
Expand Down Expand Up @@ -56,11 +58,38 @@ jobs:
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
skip-existing: true # Prevents failure on re-runs

verify-testpypi:
name: Verify TestPyPI Install 🕵️
needs: publish-to-testpypi
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Wait for TestPyPI indexing
run: sleep 60

- name: Install from TestPyPI
# --extra-index-url allows pip to find dependencies (pandas, numpy) on the real PyPI
if: github.event_name == 'release'
run: pip install --pre --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ "DoubleML==${{ github.ref_name }}"

- name: Install from TestPyPI (workflow_dispatch)
# For manual runs, install the latest pre-release version
if: github.event_name == 'workflow_dispatch'
run: pip install --pre --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ DoubleML

- name: Import Smoke Test
run: python -c "import doubleml; print(f'Successfully imported DoubleML version {doubleml.__version__}')"

publish-to-pypi:
name: Publish to PyPI 🚀
needs: publish-to-testpypi
needs: verify-testpypi
runs-on: ubuntu-latest
if: github.event_name == 'release' # Do not publish on workflow_dispatch
environment:
name: pypi
url: https://pypi.org/p/DoubleML
Expand All @@ -76,3 +105,22 @@ jobs:

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

verify-pypi:
name: Verify PyPI Install 🕵️
needs: publish-to-pypi
runs-on: ubuntu-latest
if: github.event_name == 'release'
steps:
- uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Wait for PyPI indexing
run: sleep 60

- name: Install from PyPI
run: pip install "DoubleML==${{ github.ref_name }}"

- name: Import Smoke Test
run: python -c "import doubleml; print(f'Successfully imported DoubleML version {doubleml.__version__}')"
2 changes: 1 addition & 1 deletion .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
fetch-depth: 0 # allow version retrieval with setuptools_scm

- name: Set up Python ${{ matrix.config.python-version }}
uses: actions/setup-python@v5
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ MANIFEST
*.vscode
.flake8
.coverage

# Setuptools SCM
doubleml/_version.py
4 changes: 3 additions & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import os
import sys

import doubleml

sys.path.insert(0, os.path.abspath(".."))


Expand All @@ -23,7 +25,7 @@
author = "Bach, P., Chernozhukov, V., Klaassen, S., Kurz, M. S., and Spindler, M."

# The full version, including alpha/beta/rc tags
release = "0.12.dev0"
release = doubleml.__version__


# -- General configuration ---------------------------------------------------
Expand Down
12 changes: 9 additions & 3 deletions doubleml/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import importlib.metadata

from .data import DoubleMLClusterData, DoubleMLData, DoubleMLDIDData, DoubleMLPanelData, DoubleMLRDDData, DoubleMLSSMData
from .did.did import DoubleMLDID
from .did.did_cs import DoubleMLDIDCS
Expand Down Expand Up @@ -46,4 +44,12 @@
"DoubleMLLPLR",
]

__version__ = importlib.metadata.version("doubleml")
try:
from ._version import version as __version__
except ImportError:
import importlib.metadata

try:
__version__ = importlib.metadata.version("doubleml")
except importlib.metadata.PackageNotFoundError:
__version__ = "0.0.0+unknown"
38 changes: 38 additions & 0 deletions doubleml/tests/test_init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import importlib
import sys
from unittest.mock import patch

import pytest


@pytest.mark.ci
def test_version_from_version_file():
"""Test version is imported from _version.py when available."""
import doubleml

assert hasattr(doubleml, "__version__")
assert isinstance(doubleml.__version__, str)


@pytest.mark.ci
def test_version_fallback_to_metadata():
"""Test fallback to importlib.metadata when _version.py is missing."""
with patch.dict(sys.modules, {"doubleml._version": None}):
with patch("importlib.metadata.version", return_value="1.2.3"):
# Re-import to trigger the fallback
importlib.reload(importlib.import_module("doubleml"))
import doubleml

assert doubleml.__version__ == "1.2.3"


@pytest.mark.ci
def test_version_fallback_to_unknown():
"""Test fallback to 0.0.0+unknown when package not found."""
mock_error = importlib.metadata.PackageNotFoundError()
with patch.dict(sys.modules, {"doubleml._version": None}):
with patch("importlib.metadata.version", side_effect=mock_error):
importlib.reload(importlib.import_module("doubleml"))
import doubleml

assert doubleml.__version__ == "0.0.0+unknown"
9 changes: 7 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[build-system]
requires = ["setuptools>=65", "wheel"]
requires = ["setuptools>=80", "wheel", "setuptools-scm>=8"]
build-backend = "setuptools.build_meta"

[project]
name = "DoubleML"
version = "0.12.dev0"
dynamic = ["version"]
description = "Double Machine Learning in Python"
readme = {file = "README.md", content-type = "text/markdown"}
license = {file = "LICENSE"}
Expand Down Expand Up @@ -56,6 +56,11 @@ Documentation = "https://docs.doubleml.org"
Source = "https://github.com/DoubleML/doubleml-for-py"
"Bug Tracker" = "https://github.com/DoubleML/doubleml-for-py/issues"

[tool.setuptools_scm]
version_scheme = "guess-next-dev"
local_scheme = "dirty-tag"
write_to = "doubleml/_version.py"

[tool.pytest.ini_options]
markers = [
"ci: mark a test as a continuous integration test which will be executed in github actions.",
Expand Down
Loading