diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..0a82a502 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,54 @@ +# AGENTS.md + +Rules for AI agents working in this repository. They add to [CONTRIBUTING.md](CONTRIBUTING.md), +which you must follow. + +## Rules for AI contributions +- Name the model and its version in the PR description, e.g. `Claude Opus 5.5`. PRs that we believe were made with + AI without this statement are rejected entirely. +- Only humans accept and merge PRs (see [Merging Pull Requests](CONTRIBUTING.md#merging-pull-requests)). Leave + approving and merging to the maintainers. +- Keep this file current: if your change makes anything here wrong or incomplete, update `AGENTS.md` in the same PR. + +## Before you start +- Read [CONTRIBUTING.md](CONTRIBUTING.md) and the `README.md` of the repository root and of each package you change. +- If you are blocked, or the specification is ambiguous, stop and ask. In a PR, state the open question instead of + guessing. + +## Monorepo +Each package has its own `pyproject.toml`. Run all commands from the package directory. + +| Package | Source dir | Depends on | +|--------------------|------------------------|------------| +| `sdk/` | `basyx/` | - | +| `server/` | `app/` | `sdk/` | +| `compliance_tool/` | `aas_compliance_tool/` | `sdk/` | + +## Workflow +- Use test-driven development: write a test that fails, implement the change, confirm that the test passes. +- Use `unittest`, not `pytest`. Tests mirror the source layout under `/test/`. +- Before you report a task as done, run the checks from CONTRIBUTING.md for each package you changed. Report + failures with their output. +- Install dependencies with `pip`. Keep `uv.lock` out of commits. +- Stage files by explicit path (`git add `) and commit only the files of the task. + +## Code conventions +Apply these to new code and to code you change for the task. Leave unrelated code as it is. +- Inline a function that is called from one place only, unless it is longer than about 30 lines or needs its own + unit test. +- Avoid needless work, e.g. copying a list you only read, or building a list just to iterate over it once. +- Compute values on demand or pass them as arguments instead of storing them as instance attributes. + +## AAS specification +- The version of each specification part is in the *Specification Compliance* table of the root + [README.md](README.md). +- When in doubt, or when you are asked to do something according to the specification, look it up at + `https://industrialdigitaltwin.io/aas-specifications/{DOC_ID}/{VERSION}/index.html`. Write `{VERSION}` exactly as in the README, e.g. `v3.1`, as `v3.1.0` returns 404. +- `{DOC_ID}`: `IDTA-01001` (Part 1: Metamodel), `IDTA-01002` (Part 2: API), `IDTA-01003-a` / `IDTA-01003-b` + (Part 3a/3b: Data Specifications), `IDTA-01004` (Part 4: Security), `IDTA-01005` (Part 5: AASX). +- The sources of the specification are published as AsciiDoc in the + [admin-shell-io](https://github.com/admin-shell-io) GitHub organization, one repository per part + (e.g. `aas-specs-metamodel`, `aas-specs-api`). +- Back claims about the specification with a link to the exact section (its anchor in the web version). +- Take the JSON and XSD schemas from the release tag of + [aas-specs-metamodel](https://github.com/admin-shell-io/aas-specs-metamodel), never from `master`. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c13dfe45..87af640a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -57,6 +57,10 @@ committing. ### Workflow +The default branch of Eclipse-BaSyx-Python is `develop`. +All contributions go there, so every pull request must target `develop`. +The `main` branch only receives releases. + After this, the workflow to submit contributions to Eclipse-BaSyx-Python is pretty standard, as the picture (based on [this blog-post by Tomas Beuzen](https://www.tomasbeuzen.com/post/git-fork-branch-pull/)) @@ -71,14 +75,15 @@ below shows: git remote add upstream https://github.com/eclipse-basyx/basyx-python-sdk ``` -3. Pull the branch you want to contribute to: +3. Pull the `develop` branch: ```bash -git pull upstream +git pull upstream develop ``` Now, you can create a new local branch in which you can create your changes and actually -do your changes. When you're done with that, continue with: +do your changes. The name of the branch does not matter much. When you're done with that, +continue with: 4. Push the new branch to your fork: @@ -87,18 +92,53 @@ git push origin ``` 5. Create a [Pull Request](https://github.com/eclipse-basyx/basyx-python-sdk/pulls) from - your fork `` to the Eclipse-BaSyx-Python `` + your fork `` to the Eclipse-BaSyx-Python `develop` branch The Eclipse-BaSyx-Python maintainers will then review the pull request and communicate the further steps via the comments. +### Merging Pull Requests + +Only the maintainers accept and merge pull requests. + +We welcome contributions that were written with the help of AI. In that case, name the +model and its version at the end of the pull request description, e.g. `Claude Opus 5.5`. +If we believe that a contribution was made with AI and this is not stated, we reject +the pull request entirely. + +Pull requests are merged with *Squash and merge*: All commits of your branch become +a single commit on `develop`. +The title and description of the pull request become the title and message of this +commit, and GitHub appends the PR number to the title, e.g. `(#123)`. + +The release notes are written from the commit history of `develop`. +Therefore, the title and description of your pull request are very important and must +follow the [guidelines below](#commit-and-pull-request-messages). +The individual commits on your branch are lost in the squash, so their messages matter +less. +The maintainers may edit the title and description before they merge. + +The only exception are releases: The release pull request from `develop` to `main` is +merged with a merge commit. +Afterwards, `main` is merged back into `develop`, so that the release tag is also part +of the history of `develop`. + ## Commit and Pull Request Messages In order to effectively communicate, there are some conventions to respect when writing commit messages and pull requests. -Similarly to when creating an issue, the commit title, as well as the PR title should -be as short as possible, ideally 72 characters or fewer using imperative language. +Commit messages and pull request messages are essentially the same thing: The title and +description of your pull request become the squash commit on `develop` +(see [Merging Pull Requests](#merging-pull-requests)). +If you write a good commit message, GitHub fills it in as the PR title and description +automatically, so you only need to write it once. + +### Title + +The title should be as short as possible, ideally 50 characters or fewer. +Only exceed this if truly necessary. +Use imperative language and no period at the end. If a specific module is affected, please mention it at the beginning of the title. Here are some examples: @@ -109,18 +149,63 @@ compliance_tool: Fix fail to check aasx package without thumbnail adapter.aasx: Fix `Property.value` `0` converted into `NoneType` ``` +### Message + The following guidelines are for the commit or PR message text: -- No imperative, full text, bullet points where necessary -- Max. 72 characters per line -- There should be always 2 things in a Commit/PR message: - - Currently, the situation is this - - Motivate, why is it now different? -- Don't describe what has been done, as this can be looked up in the code -- Write as long as necessary, as short as possible -- Where sensible, reference the specification, ideally - via `https://link/to.pdf#Page=123` -- Optionally, where applicable reference respective issues: `Fixes #123` +- Max. 72 characters per line (except for link definitions, see below) +- No imperative, full sentences, bullet points where helpful +- Every message should convey these three things: + 1. Previous state: What was the situation before this change? + 2. Motivation: Why do we change it now? Sometimes, this is already clear from the + previous state. + 3. What changed: A high-level description of the approach. The details can be + looked up in the code. +- Write as short as possible, while still being complete +- Use backticks for class names, method names, file names, or any other identifiers +- Reference issues and pull requests inline as `#123` +- Where sensible, reference the specification via its HTML version, e.g. + `https://industrialdigitaltwin.io/aas-specifications/IDTA-01001/v3.2/index.html` +- If a URL is too long for a line, use a reference-style link: Write `[some text]` + inline and add the link definition `[some text]: https://...` at the very end +- If applicable, close the respective issues with `Fixes #123` after the message + text and before any link definitions + +Here are two examples: + +``` +Increase `adapter.aasx` test coverage + +Previously the test coverage in the `basyx.aas.adapter.aasx` package +was suboptimal. The `AASXWriter` class was tested end-to-end in +combination with `AASXReader` but special cases, that lead to +exceptions were not covered. Additionally the `load_directory(...)` +method of the `basyx.aas.adapter` package was untested. + +With these changes additional tests are added which cover the code +parts that are mentioned above. + +Fixes #127 +``` + +``` +Revert "[V3] Fix missing literal in `FragmentKeys` (#337)" + +Previously, we thought that we missed the literal `Referable` in +`FragmentKeys`. In #337, we introduced that literal, together with all +the logical problems and paradoxes that come with it. + +However, as it turns out, it was a bug in the specification, rather +than our mistake. Therefore, we revert the changes of commit +f41646aa4baa5807cefeb4c3bb95f7937d001b50 here. + +See [aas-core-works/aas-core3.0-python#37] for the discussion, as it +was discovered there. + +Fixes #322 + +[aas-core-works/aas-core3.0-python#37]: https://github.com/aas-core-works/aas-core3.0-python/issues/37 +``` ## Code Quality @@ -231,9 +316,9 @@ itself. Then you can run the checks via: ```bash ruff check -mypy basyx test +mypy aas_compliance_tool test python -m unittest -coverage run --source basyx --branch -m unittest +coverage run --source aas_compliance_tool --branch -m unittest coverage report -m ```