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
2 changes: 1 addition & 1 deletion .github/workflows/python-library.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.12"
python-version: "3.13"

- name: Install build dependencies
shell: bash
Expand Down
213 changes: 213 additions & 0 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
name: Wheels

on:
workflow_dispatch:
push:
branches:
- main
tags:
- v*.*.*

permissions:
contents: read

jobs:
check_version:
name: Check Python version
runs-on: ubuntu-latest
outputs:
should_build: ${{ steps.version.outputs.should_build }}
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Check whether the Python package version changed
id: version
shell: bash
env:
EVENT_NAME: ${{ github.event_name }}
REF: ${{ github.ref }}
BEFORE_SHA: ${{ github.event.before }}
run: |
python - <<'PY'
import os
import subprocess
import tomllib

with open("pyproject.toml", "rb") as config:
current_version = tomllib.load(config)["project"]["version"]

should_build = False
previous_version = None
before_sha = os.environ.get("BEFORE_SHA", "")

if os.environ["EVENT_NAME"] == "workflow_dispatch":
should_build = True
elif os.environ["REF"].startswith("refs/tags/"):
should_build = True
elif os.environ["EVENT_NAME"] == "push" and os.environ["REF"] == "refs/heads/main":
if before_sha and set(before_sha) != {"0"}:
try:
previous_pyproject = subprocess.check_output(
["git", "show", f"{before_sha}:pyproject.toml"],
text=True,
)
previous_version = tomllib.loads(previous_pyproject)["project"]["version"]
should_build = current_version != previous_version
except subprocess.CalledProcessError:
should_build = True
else:
should_build = True

print(f"current version: {current_version}")
if previous_version is not None:
print(f"previous version: {previous_version}")
print(f"should build: {should_build}")

with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output:
output.write(f"version={current_version}\n")
output.write(f"should_build={str(should_build).lower()}\n")
PY

build_sdist:
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
name: Build SDist
needs: check_version
if: needs.check_version.outputs.should_build == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: true

- name: Build SDist
run: pipx run build --sdist

- name: Check metadata
run: pipx run twine check dist/*

- uses: actions/upload-artifact@v7
with:
name: dist-sdist
path: dist/*.tar.gz


build_wheels:
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
name: Wheels on ${{ matrix.os }}
needs: check_version
if: needs.check_version.outputs.should_build == 'true'
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm, macos-14, windows-latest]

steps:
- uses: actions/checkout@v6
with:
submodules: true

- uses: pypa/cibuildwheel@v3.4

- name: Verify clean directory
run: git diff --exit-code
shell: bash

- name: Upload wheels
uses: actions/upload-artifact@v7
with:
path: wheelhouse/*.whl
name: dist-${{ matrix.os }}

publish-to-testpypi:
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
name: Upload if release
needs: [check_version, build_wheels, build_sdist]
if: >-
github.event_name == 'push' &&
github.ref == 'refs/heads/main' &&
needs.check_version.outputs.should_build == 'true'
runs-on: ubuntu-latest
#if: github.event_name == 'release' && github.event.action == 'published'
environment:
name: testpypi
url: https://test.pypi.org/p/griddyn
permissions:
id-token: write # IMPORTANT: mandatory for trusted publishing
steps:
- uses: actions/setup-python@v6
- uses: actions/download-artifact@v8
with:
pattern: dist-*
merge-multiple: true
path: dist/

- uses: pypa/gh-action-pypi-publish@release/v1
with:
verbose: true
repository-url: https://test.pypi.org/legacy/
publish-to-pypi:
name: >-
Publish Python distribution to PyPI
if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
needs: [build_wheels, build_sdist]
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/griddyn
permissions:
id-token: write # IMPORTANT: mandatory for trusted publishing

steps:
- name: Download all the dists
uses: actions/download-artifact@v8
with:
pattern: dist-*
merge-multiple: true
path: dist/
- name: Publish distribution to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

github-release:
name: >-
Sign the Python distribution with Sigstore
and upload them to GitHub Release
needs:
- publish-to-pypi
runs-on: ubuntu-latest

permissions:
contents: write # IMPORTANT: mandatory for making GitHub Releases
id-token: write # IMPORTANT: mandatory for sigstore

steps:
- name: Download all the dists
uses: actions/download-artifact@v8
with:
pattern: dist-*
merge-multiple: true
path: dist/
- name: Sign the dists with Sigstore
uses: sigstore/gh-action-sigstore-python@v3.3.0
with:
inputs: >-
./dist/*.tar.gz
./dist/*.whl
- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
gh release create
'${{ github.ref_name }}'
--repo '${{ github.repository }}'
--notes ""
- name: Upload artifact signatures to GitHub Release
env:
GITHUB_TOKEN: ${{ github.token }}
# Upload to GitHub Release using the `gh` CLI.
# `dist/` contains the built packages, and the
# sigstore-produced signatures and certificates.
run: >-
gh release upload
'${{ github.ref_name }}' dist/**
--repo '${{ github.repository }}'
51 changes: 48 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,74 @@ build-backend = "scikit_build_core.build"

[project]
name = "griddyn"
version = "0.0.0"
version = "0.11.1"
description = "Python bindings for GridDyn"
readme = "README.md"
requires-python = ">=3.10"
requires-python = ">=3.13"
license = "BSD-3-Clause"
license-files = ["LICENSE", "NOTICE"]
authors = [
{ name = "GridDyn contributors" },
{ name = "Philip Top", email = "top1@llnl.gov" },
]
classifiers = [
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.13",
"Operating System :: OS Independent",
"Topic :: Scientific/Engineering",
"Development Status :: 4 - Beta",
]
keywords = [
"power systems",
"simulation",
"grid dynamics",
"power flow",
"co-simulation",
"science",
"python",
]

[project.urls]
Homepage = "https://github.com/LLNL/GridDyn"
Repository = "https://github.com/LLNL/GridDyn"
Issues = "https://github.com/LLNL/GridDyn/issues"
Changelog = "https://github.com/LLNL/GridDyn/blob/main/CHANGELOG.md"

[project.optional-dependencies]
test = ["pytest"]

[tool.scikit-build]
# Protect the configuration against future changes in scikit-build-core
minimum-version = "build-system.requires"

# Setuptools-style build caching in a local directory
build-dir = "build/{wheel_tag}"

# The build targets to use when building the project. Empty builds the default target.
build.targets = ["griddyn_python_core"]

# The components to install. If empty, all default components are installed.
install.components = ["python"]

# Build stable ABI wheels for CPython 3.13+
wheel.py-api = "cp313"

cmake.version = ">=3.26.1"
cmake.args = [
"-DGRIDDYN_BUILD_PYTHON_LIBRARY=ON",
"-DGRIDDYN_BUILD_TESTS=OFF",
"-DGRIDDYN_ENABLE_FMI=OFF",
"-DGRIDDYN_ENABLE_HELICS_EXECUTABLE=OFF",
]

[tool.cibuildwheel]
# Necessary to see build output from the actual compilation
build-verbosity = 1
skip = "pp311-macosx_arm64"

# Run pytest to ensure that the package was correctly built
test-command = "pytest {project}/python/tests"
test-requires = "pytest"

# Needed for C++23 support and consistency with rtunits macOS wheels.
[tool.cibuildwheel.macos.environment]
MACOSX_DEPLOYMENT_TARGET = "11.0"
4 changes: 2 additions & 2 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
find_package(
Python 3.10 REQUIRED COMPONENTS Interpreter Development.Module
Python 3.13 REQUIRED COMPONENTS Interpreter Development.Module
OPTIONAL_COMPONENTS Development.SABIModule
)

Expand All @@ -18,7 +18,7 @@ endif()

find_package(nanobind CONFIG REQUIRED)

nanobind_add_module(griddyn_python_core NB_STATIC griddyn_python.cpp)
nanobind_add_module(griddyn_python_core NB_STATIC STABLE_ABI griddyn_python.cpp)

set(griddyn_python_warning_options
$<$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>:-Wno-strict-aliasing -Wno-shadow>
Expand Down