Skip to content

Prepare Release 2.2.0 - #629

Draft
s-heppner wants to merge 10 commits into
mainfrom
develop
Draft

s-heppner wants to merge 10 commits into
mainfrom
develop

Conversation

@s-heppner

Copy link
Copy Markdown
Member

Release Notes

Version 2.2.0 of the BaSyx-Python SDK is a maintenance release that modernizes the project tooling, CI and packaging. The implemented AAS specification versions are unchanged from 2.1.0.

The minimum supported Python version is now 3.11. Python 3.10 is no longer supported; it reaches end of life in October 2026. All three packages (basyx-python-sdk, basyx-python-server, basyx-compliance-tool) now declare requires-python = ">=3.11".

The codebase is now linted and formatted with ruff, replacing pycodestyle. This reformatted a large part of the SDK without changing its functionality. If you use git blame, configure git to skip the formatting commit via the new .git-blame-ignore-revs file: git config blame.ignoreRevsFile .git-blame-ignore-revs.

Please note a small change in the import behavior of basyx.aas.adapter.json and basyx.aas.adapter.xml. Both packages now define __all__. It lists the public API: the encoder and decoder classes, and the read_* and write_* functions.

Before this release, a star-import such as from basyx.aas.adapter.xml import * also added the submodule names xml_serialization and xml_deserialization to your namespace. The JSON package added json_serialization and json_deserialization in the same way. This does not happen now.

Does your code use a submodule name after a star-import, for example xml_deserialization.AASFromXmlDecoder? Then import the submodule directly instead:

from basyx.aas.adapter.xml import xml_deserialization, xml_serialization

Direct imports and attribute access via the package (e.g. from basyx.aas.adapter import xml followed by xml.xml_deserialization) are unaffected.

Furthermore, the LICENSE file is now included in the sdist and wheel of all packages published to PyPI as well as in the server Docker images, and the package metadata follows PEP 639.

This release implements the following versions of the AAS specification:

Specification Version
Part 1: Metamodel v3.1.2 (01001-3-1-2)
Schemata (JSONSchema, XSD) v3.1.2 (IDTA-01001-3-1-2)
Part 2: API v3.1.1 (01002)
Part 3a: Data Specification IEC 61360 v3.1.1 (01003-a)
Part 5: Package File Format (AASX) v3.1 (01005)

Changelog

Notable:

Improvements:

Bugfixes:

Testing & Internal:

For more details, check out https://projects.eclipse.org/projects/dt.basyx/releases/2.2.0-python

s-heppner and others added 10 commits July 16, 2026 10:44
Following the release, `main` now contains the release commit and
the new version tag. These need to be brought back into `develop` so
the tags are reachable and the branches don't diverge.

This merges `main` into `develop`. No functional changes.
Previously, the project only ran `pycodestyle` in CI for style
checks and had no autoformatter, so formatting and import order were
enforced manually and inconsistently.

This change introduces `ruff` for both formatting and linting,
configured in `ruff.toml`, and replaces `pycodestyle` in CI. The
`CONTRIBUTING.md` is updated to document the new workflow.

The formatter enforces double quotes, space indentation, and
docstring code formatting (line length 120, target py310).

The following lint rule groups are enabled and the codebase was
fixed to comply:

- `E`/`W`: pycodestyle errors and warnings
- `I`: import order (isort)
- `F4`: imports and `__future__` usage
- `F5`: format strings (e.g. unnecessary f-strings)
- `F7`: control flow (`return`/`break`/`continue` placement)
- `F8`: undefined and unused names
- `D201`/`D204`/`D211`/`D300`: basic docstring formatting
- `COM818`: trailing comma enforcement
- `PIE`: small readability improvements
- `RUF100`: unused `noqa` statements

Several rule groups are ignored for now (see the `TODO` in
`ruff.toml`). Rules like `F403`/`F405` are ignored due to high
existing star-import usage, while groups such as `N` (naming), `B`
(bugbear), `S` (security), and `BLE` (blind except) are left for a
later evaluation of whether to promote them to linting.

Fixes #412
After the ruff linter introduction the git blame is mostly cluttered by the resulting changes.
This file is introduced to generally feature commits that should be taken out of the git blame chain and quick setup instructions.
Previously, the `NOTICE` file in the `compliance_tool` package contained 
a reference to third party licenses for files, which are not used 
anymore. 

This cleans this up and removes the `NOTICE` file.

Fixes #596
Previously, all checks lived in a single `ci.yml` that ran on every
push and every pull request, so the same commit was tested twice and
concurrent runs were never cancelled. The three server Docker images
were built by three nearly identical jobs in `release.yml`, while CI
itself only ever built the repository image. All actions were
referenced by mutable tags and no dependency caching was in place.

With these changes, the CI is restructured:

- `ci.yml` is renamed to `pr.yml` and only runs on pull requests and
  on pushes to `develop` and `main`. Concurrent runs of the same ref
  are cancelled and the workflow only requests `contents: read`. The
  references in `CONTRIBUTING.md` are updated accordingly.
- A new `main.yml` runs the expensive `linux/arm64` Docker tests only
  for pull requests targeting `main`.
- The Docker build logic is extracted into the composite action
  `.github/actions/build-server`, which is used by both the Docker
  test jobs and `release.yml`. The three publish jobs in `release.yml`
  collapse into a single matrix job over the server profiles.
- The Docker test job now covers all three server profiles and checks
  liveness by calling the `/description` endpoint, instead of only
  inspecting the container state.
- All actions are pinned to commit hashes and updated, and
  `setup-python` caches the pip downloads.
- Static analysis is done with `ruff` instead of `pycodestyle`, which
  is added as a dev dependency of all three packages. A new
  `helper-scripts-static-analysis` job extends this to `etc/scripts`,
  which was not covered by any linting so far.
- `check_python_versions_coincide.py` gains a `--docker` flag, so that
  the supported Python versions are also checked against the server
  Dockerfiles and `server/pyproject.toml`. It now also enforces the
  upper bound, which was passed but never evaluated before.
- The AAS schema files are fetched from the `aas-specs-metamodel`
  repository and `curl` now fails on HTTP errors.

Fixes #479
Fixes #480
Fixes #518
Fixes #547
Previously, the SDK had no logo in its documentation. The original
PyI40AAS logo was left behind when the project moved to the Eclipse
Foundation, so the README carried no visual identity. This change
restores it for recognition value.

The logo is taken from the archived ACPLT PyI40AAS repository and
added as `etc/logo.svg`, stripped of the Inkscape and sodipodi editor
attributes, including an export path that leaked the original author's
home directory. The CC0 dedication and the attribution to Michael
Thies are kept.

The `README.md` shows the logo centered above the title. GitHub draws
a full-width rule under every `h1`, which would cut straight through a
logo placed beside the heading, so the logo goes above it instead. The
title is written as an `<h1 align="center">` tag rather than as a
Markdown heading, because centering needs the `align` attribute.

A separate dark variant of the logo is not needed, as it stays legible
on both the light and the dark GitHub theme.

Fixes #230
Previously, the `sdk` and `compliance_tool` packages were built in
isolation from their own subdirectories, without access to the root
`LICENSE` file. As a result, the `LICENSE` was missing from both the
sdist and wheel published to PyPI, and from the server Docker images.

This change copies the root `LICENSE` file into each package
directory immediately before `python -m build` in `pr.yml` and
`release.yml`, and adds a `COPY ./LICENSE /LICENSE` step to the
server Dockerfiles. The `sdk`, `compliance_tool`, and `server`
`pyproject.toml` files are updated to PEP 639 license metadata
(`license = "MIT"` with `license-files = ["LICENSE"]`) so `setuptools`
actually packages the copied file into the distributions. The now
redundant `compliance_tool/LICENSE` copy is removed in favor of the
single root `LICENSE`.

Fixes #462
Previously, version pins for Python, `mypy`, `ruff`, and the API/spec
versions lived in multiple places: workflow env blocks, three
`pyproject.toml` files, `ruff.toml`, and the server Dockerfiles. `mypy`
was pinned in the SDK but unpinned in the server and compliance
tool, and `ruff` was not pinned anywhere.

Bumping any of these values required editing several files and was
easy to get wrong.

This change introduces a repo-root `versions.toml` as the single
source of truth. A new `check_global_versions_coincide.py` verifies
that every listed `pyproject.toml`, `config.toml`, and Dockerfile
coincides with it; new entries under `dev_tools` are checked
automatically without further script changes. A composite action
`.github/actions/load-versions` exposes the values to CI jobs as
`X_*` environment variables, so consuming workflows keep their
existing `${{ env.X_* }}` usage.

Runtime server constants (currently only `api_base_path`) live in a
separate `server/app/config.toml`, read by the server directly at
import time.

The old `check_python_versions_coincide.py` is superseded and
removed.

Fixes #548
Previously, the deserialization required values in formates
`xs:dateTime` and `xs:date` to consists of exactly four digits for
the year. However, the XML Schema 1.0, which is defined as reference,
allow for more digits if the leading digit is non-zero.

These changes adapt the regex used for deserialization of both datatypes
to also allow more than four digits for year numbers if no leading
zeros are used. If only four digits are uesd, leading zeros are still
allowed.

We now raise a `NotImplementedError` on out-of-range years,
similar to handling of negative dates in #586

The `GYear` and `GYearMonth` lexical representation follows the
one of the year part of `xs:dateTime`. Therefore the regex needs
to be changed to prohibit leading zeros for 4+ digit year.

The error handling in the `into_date()` method of both classes
for years that exceed Python's `datetime.MAXYEAR` is similar to
the one for negative dates (introduced in #586).

Fixes #616
Previously many code files did not carry the copyright header (see #584).

To resolve this issue first the ruff linter was configured to also 
include `CPY001` to confirm the presence of the copyright header. 
The `/ect/scripts/set_copyright_year.sh` remains to check the year 
being correct. `__init__.py` are ignored using rule specific ignores 
in ruff.

Also all files flagged by ruff now carry a copyright header 
(with the year of the last change according to git history).

Fixes #584
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants