Skip to content

Commit d78c885

Browse files
authored
build: automated versioning with setuptools_scm and improved workflows (#182)
* ci: upgrade deploy and test ci * build: use `setuptools_scm` for dynamic versioning * build: update package versioning * build: use post-release versioning * docs: update email * fix: update java, use `uv` and point to tests dir * build: allow future pandas `stack` * docs: show docs also for older versions * chore: remove `requirements.yaml` * fix: clean up * test: skip url_retrieve test in gh runner * chore: set gh env
1 parent b947fde commit d78c885

File tree

13 files changed

+223
-173
lines changed

13 files changed

+223
-173
lines changed

.github/workflows/CI.yml

Lines changed: 0 additions & 43 deletions
This file was deleted.
Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,46 @@
1-
name: Deploy release
1+
name: Release
22

33
on:
44
push:
55
tags:
6-
- v*.*.*
6+
- v*.*.*
77

88
jobs:
9-
build-n-publish:
10-
name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI
9+
build:
10+
# Build the Python SDist and wheel, performs metadata and readme linting
11+
name: Build and verify package
1112
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: hynek/build-and-inspect-python-package@v2
1216

17+
release:
18+
# Publish a GitHub release from the given git tag
19+
name: Create GitHub Release
20+
needs: [build]
21+
runs-on: ubuntu-latest
1322
steps:
14-
- uses: actions/checkout@v4
15-
- name: Set up Python 3.9
16-
uses: actions/setup-python@v5
17-
with:
18-
python-version: 3.9
23+
- uses: actions/checkout@v4
24+
- uses: softprops/action-gh-release@v2
25+
with:
26+
generate_release_notes: true
1927

20-
- name: Install pypa/build
21-
run: >-
22-
python -m
23-
pip install
24-
build
25-
--user
26-
- name: Build a binary wheel and a source tarball
27-
run: >-
28-
python -m
29-
build
30-
--sdist
31-
--wheel
32-
--outdir dist/
33-
.
28+
publish:
29+
# Publish the built SDist and wheel from "dist" job to PyPI
30+
name: Publish to PyPI
31+
needs: [build]
32+
runs-on: ubuntu-latest
33+
environment:
34+
name: pypi
35+
url: https://pypi.org/project/powerplantmatching/
36+
permissions:
37+
id-token: write
38+
steps:
39+
- uses: actions/download-artifact@v4
40+
with:
41+
name: Packages
42+
path: dist
43+
- uses: pypa/gh-action-pypi-publish@release/v1
3444

3545
update-dataset:
3646
name: Update powerplants.csv in repository
@@ -70,4 +80,4 @@ jobs:
7080
git commit -m '[github-actions.ci] auto update `powerplants.csv`' || exit 0
7181
git push origin master
7282
env:
73-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
83+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/test.yml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: [ '*' ]
8+
schedule:
9+
- cron: "0 5 * * TUE"
10+
11+
# Cancel any in-progress runs when a new run is triggered
12+
concurrency:
13+
group: ${{ github.workflow }}-${{ github.ref }}
14+
cancel-in-progress: true
15+
16+
jobs:
17+
build:
18+
# Build the Python SDist and wheel, performs metadata and readme linting
19+
name: Build and verify package
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: actions/checkout@v4
23+
with:
24+
fetch-depth: 0 # Needed for setuptools_scm
25+
- uses: hynek/build-and-inspect-python-package@v2
26+
id: baipp
27+
28+
outputs:
29+
python-versions: ${{ steps.baipp.outputs.supported_python_classifiers_json_array }}
30+
31+
test:
32+
# Test package build in matrix of OS and Python versions
33+
name: Test package
34+
needs: [build]
35+
runs-on: ${{ matrix.os }}
36+
strategy:
37+
fail-fast: false
38+
matrix:
39+
python-version: ${{ fromJSON(needs.build.outputs.python-versions) }}
40+
os:
41+
- ubuntu-latest
42+
- macos-latest
43+
- windows-latest
44+
45+
steps:
46+
- uses: actions/checkout@v4
47+
with:
48+
fetch-depth: 0 # Needed for setuptools_scm
49+
50+
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
51+
uses: actions/setup-python@v5
52+
with:
53+
python-version: ${{ matrix.python-version }}
54+
55+
- name: Set up Java
56+
uses: actions/setup-java@v4
57+
with:
58+
distribution: 'temurin'
59+
java-version: 22
60+
61+
- name: Download package
62+
uses: actions/download-artifact@v4
63+
with:
64+
name: Packages
65+
path: dist
66+
67+
- name: Install package and dependencies
68+
run: |
69+
python -m pip install uv
70+
uv pip install --system "$(ls dist/*.whl)[dev]"
71+
72+
- name: Test with pytest
73+
run: |
74+
pytest
75+
env:
76+
GITHUB_ACTIONS: true
77+

doc/conf.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
# list see the documentation:
55
# https://www.sphinx-doc.org/en/master/usage/configuration.html
66

7+
from importlib.metadata import version as get_version
8+
79
# -- Path setup --------------------------------------------------------------
810

911
# If extensions (or modules to document with autodoc) are in another directory,
@@ -14,13 +16,17 @@
1416
# import sys
1517
# sys.path.insert(0, os.path.abspath('.'))
1618

17-
1819
# -- Project information -----------------------------------------------------
1920

2021
project = "powerplantmatching"
2122
copyright = "2021-2024, Fabian Hofmann, Fabian Gotzens, Jonas Hörsch, Martha Frysztacki"
2223
author = "Fabian Hofmann, Fabian Gotzens, Jonas Hörsch, Martha Frysztacki"
2324

25+
# -- Version information -------------------------------------------------
26+
27+
# The short X.Y version.
28+
release: str = get_version("powerplantmatching")
29+
version: str = ".".join(release.split(".")[:2])
2430

2531
# -- General configuration ---------------------------------------------------
2632

powerplantmatching/__init__.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,26 @@
2121
power plant databases.
2222
"""
2323

24-
__version__ = "0.5.15"
25-
__author__ = "Fabian Hofmann"
26-
__copyright__ = "Copyright 2017-2024 Technical University of Berlin"
27-
# The rough hierarchy of this package is
28-
# core, utils, heuristics, cleaning, matching, collection, data
24+
from importlib.metadata import version
2925

3026
from . import core, data, heuristics, plot, utils
3127
from .accessor import PowerPlantAccessor
3228
from .collection import powerplants
3329
from .core import get_config, package_config
3430

31+
__author__ = "Fabian Hofmann"
32+
__copyright__ = "Copyright 2017-2024 Technical University of Berlin"
33+
# The rough hierarchy of this package is
34+
# core, utils, heuristics, cleaning, matching, collection, data
35+
36+
# e.g. "0.5.15" or "0.5.15.post27+g761e814.d20240722" (if installed from master branch)
37+
__version__ = version("powerplantmatching")
38+
# e.g. "0.5.15", without the post part (if it exists, otherwise the same as __version__)
39+
latest_release = __version__.split(".post")[0]
40+
41+
assert latest_release != "0.1", "setuptools_scm could not find the version number"
42+
43+
3544
__all__ = [
3645
"powerplants",
3746
"get_config",

powerplantmatching/collection.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ def powerplants(
169169
Arguments passed to powerplantmatching.collection.Collection.
170170
171171
"""
172-
from . import __version__
172+
from . import latest_release
173173

174174
if config is None:
175175
if config_update is None:
@@ -200,7 +200,7 @@ def powerplants(
200200

201201
if from_url:
202202
fn = _data_out("matched_data_red.csv", config)
203-
url = config["matched_data_url"].format(tag="v" + __version__)
203+
url = config["matched_data_url"].format(tag="v" + latest_release)
204204
logger.info(f"Retrieving data from {url}")
205205
df = (
206206
pd.read_csv(url, index_col=0)
@@ -247,7 +247,9 @@ def powerplants(
247247
matched = matched[matched.lat.notnull()]
248248

249249
if isinstance(matched.columns, pd.MultiIndex):
250-
matched.stack().drop_duplicates(["Name", "Fueltype", "Country"]).unstack(-1)
250+
matched.stack(future_stack=True).drop_duplicates(
251+
["Name", "Fueltype", "Country"]
252+
).unstack(-1)
251253
else:
252254
matched.drop_duplicates(["Name", "Fueltype", "Country"])
253255

powerplantmatching/matching.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ def reduce_matched_dataframe(df, show_orig_names=False, config=None):
307307
sdf = (
308308
df.assign(Set=lambda df: df.Set.where(df.Set != "PP"))
309309
.assign(Fueltype=lambda df: df.Fueltype.where(df.Set != "Other"))
310-
.stack(1)
310+
.stack(1, future_stack=True)
311311
.reindex(rel_scores.index, level=1)
312312
.groupby(level=0)
313313
.agg(props_for_groups)

powerplantmatching/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ def fill_geoposition(
641641
if isinstance(df.columns, pd.MultiIndex):
642642
new_data = (
643643
df.drop(columns=["lat", "lon"])
644-
.stack()
644+
.stack(future_stack=True)
645645
.join(locs, on=["Name", "Country"])
646646
.unstack(-1)
647647
.reindex(columns=df.columns)

pyproject.toml

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,76 @@
1-
# Formater and linter settings
1+
[build-system]
2+
requires = ["setuptools>=64", "setuptools_scm>=8"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name="powerplantmatching"
7+
dynamic = ["version"]
8+
description="Toolset for generating and managing Power Plant Data"
9+
readme="README.md"
10+
authors = [{ name = "Fabian Hofmann (FIAS)", email = "fabianmarikhofmann@gmail.com" },
11+
{ name = "Jonas Hoersch (KIT)" },
12+
{ name = "Fabian Gotzens (FZ Jülich)" }]
13+
license = { file = "LICENSE" }
14+
classifiers=[
15+
"Programming Language :: Python :: 3.9",
16+
"Programming Language :: Python :: 3.10",
17+
"Programming Language :: Python :: 3.11",
18+
"Programming Language :: Python :: 3.12",
19+
"Environment :: Console",
20+
"Intended Audience :: Science/Research",
21+
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
22+
"Natural Language :: English",
23+
"Operating System :: OS Independent",
24+
]
25+
26+
requires-python = ">=3.9"
27+
28+
dependencies = [
29+
"numpy",
30+
"scipy",
31+
"pandas>=0.24.0",
32+
"networkx>=1.10",
33+
"pycountry",
34+
"country_converter",
35+
"xlrd",
36+
"seaborn",
37+
"pyyaml >=5.1.0",
38+
"requests",
39+
"matplotlib",
40+
"geopy",
41+
"xlrd",
42+
"unidecode",
43+
"entsoe-py >=0.3.1",
44+
"deprecation",
45+
"tqdm",
46+
"openpyxl",
47+
]
48+
49+
[project.urls]
50+
Homepage = "https://github.com/PyPSA/powerplantmatching"
51+
Source = "https://github.com/PyPSA/powerplantmatching"
52+
53+
[project.optional-dependencies]
54+
docs= [
55+
"numpydoc",
56+
"sphinx",
57+
"sphinx-book-theme",
58+
"nbsphinx",
59+
"sphinx-automodapi",
60+
]
61+
dev= ["pre-commit", "pytest", "pytest-cov"]
62+
63+
# setuptools_scm settings
64+
65+
[tool.setuptools_scm]
66+
version_scheme = "post-release"
67+
68+
[tool.setuptools.packages.find]
69+
include = ["powerplantmatching"]
70+
71+
# Formatter and linter settings
272

373
[tool.ruff]
4-
line-length = 88
574
extend-include = ['*.ipynb']
675

776
[tool.ruff.lint]
@@ -21,4 +90,4 @@ select = [
2190
[tool.pytest.ini_options]
2291
filterwarnings = [
2392
"error::FutureWarning", # Raise all FutureWarnings as errors
24-
]
93+
]

0 commit comments

Comments
 (0)