Skip to content

Reorganize repository for unified release - #39

Merged
glopesdev merged 14 commits into
harp-tech:mainfrom
glopesdev:feature/unified-release
Sep 25, 2026
Merged

glopesdev merged 14 commits into
harp-tech:mainfrom
glopesdev:feature/unified-release

Conversation

@glopesdev

@glopesdev glopesdev commented May 6, 2026 •

Copy link
Copy Markdown
Collaborator

Adopt the standardised repository layout described in harp-tech/protocol#145, aligning this repository with the conventions shared by other Harp components and enabling a unified release of firmware, software, and documentation from a single CI pipeline.

Repository layout and build infrastructure

  • Rename top-level folders to the agreed lowercase layout. The Firmware folder becomes firmware, Hardware becomes hardware, and Interface becomes software, which now holds one subfolder per toolchain, software/dotnet and software/python. A new docs/ folder is introduced as the root for repository documentation and assets.
  • Add shared build infrastructure under software/dotnet/build/, including Common.csproj.props, Common.csproj.targets, and Package.props, for consistent project metadata and packaging across software components.
  • Extend the CI workflow with stages for building the firmware, software, and documentation, rendering workflow images, and publishing packages and documentation as part of a single release. Every action moves to the node24 versions used across the organisation.

Generated code is verified

A verify-generated job regenerates every target from device.yml, the ATxmega firmware headers, the C# interface and the Python package, and fails when the committed output differs. It runs first and every build job depends on it, so no artifact is published from a tree whose generated code has drifted.

Bringing the firmware under that check required moving one device feature out of the generated header. The valve mimic had been hand-edited into app_ios_and_regs.h, so a new hand-written mimic.h now wraps the generated pin macros as open_POKEn_VALVE, close_POKEn_VALVE and toggle_POKEn_VALVE, and the call sites use those. The IR half of the same feature was already called from interrupts.c, so both halves now sit outside the generated header. The three headers are now exactly what the generator emits, and the built firmware image is unchanged from a build of the previous revision, so nothing about the device changed.

The harp.toolkit pin moves to 0.4.0, which is what supplies the Python target and the per-language interface subcommands, and the C# interface is regenerated against it.

Python device interface

Publish the generated Python interface as harp-behavior on PyPI, importable as harp.device.behavior, alongside the existing NuGet packages. The module is generated as a package initializer with a py.typed marker, so it resolves under a type checker and can be pinned like any other dependency.

CI builds and tests it on Python 3.11, 3.12 and 3.13, and publishes the distributions to PyPI through trusted publishing on release. The version comes from setuptools-scm, restricted to plain semantic version tags so the firmware tags in this repository are not mistaken for releases.

Cross-platform App packaging

Replace the platform-specific NSIS installer with a cross-platform dotnet tool package for the GUI App, installable on any platform with the .NET SDK and launchable as harp.behavior.

Notes

After merging, contributors will need to run git submodule update --init --recursive and dotnet tool restore when checking out the repository.

Firmware developers should now use the wrappers in mimic.h rather than the raw set_POKEn_VALVE macros, which still exist but no longer mimic. Regenerating with --implementation would also rewrite init_ios(), the one place where a raw call would be reintroduced silently.

glopesdev added 4 commits May 6, 2026 15:31
Remove NSI scripts and move towards dotnet tool deployment.
Brings the repository into compliance with the standardised build
infrastructure.
@banchan86

banchan86 commented May 28, 2026 •

Copy link
Copy Markdown

It would be nice to also generate the register table for the API using harp.schemaprocessor, but right now it only lives on the harp-tech website repository and should probably be moved elsewhere if we want to invoke it. I raised a proposal to bundle it together with harp.toolkit harp-tech/toolkit#31.

Otherwise, the documentation portions of this PR look good to me!

@ChucklesOnGitHub

Copy link
Copy Markdown

Hi @glopesdev! @banchan86 and I are working on having the first few docs sites ready by end of September and are looking forward to having them served on harp-tech.org. I wanted to check what is the timeline for this repo reorganization so we can coordinate. The Sound Card and Timestamp Generator repos are also part of that first doc upload. Thanks for letting us know.

@glopesdev

Copy link
Copy Markdown
Collaborator Author

@ChucklesOnGitHub that sounds very much on target, with the release of the python interface we will be focusing on wrapping this next.

The workflow-images job reads the need-workflow-image-render output
now declared by build-interface. The condition previously named a job
that does not exist, so workflow-images never ran.
The software folder now holds one subfolder per toolchain. The .NET
projects, the solution, the shared build files and the license move
into software/dotnet.
The package is harp-behavior and the module is harp.device.behavior.
The interface is generated with the package option, so the module is
an __init__.py beside a py.typed marker.

The version comes from setuptools-scm, configured to read only plain
semver tags, since the default pattern would resolve to a firmware
tag otherwise. The tests assert that the device identity matches the
metadata and that the register map merges the core and application
registers.
Generation moves into a verify-generated job that regenerates every
target and fails when the committed output differs, so the check runs
once rather than on every leg of the interface matrix. The interface
job becomes build-dotnet, and every build job now waits on the check,
including firmware, so no artifact is published from a tree whose
generated code has drifted.

A build-python job runs the tests and builds the wheel on Python 3.11
to 3.13, and a publish-pypi job attaches the distributions to the
release and publishes them with trusted publishing.
The valve mimic moves out of app_ios_and_regs.h into a hand-written
mimic.h, which wraps every pin macro it needs as open_POKEn_VALVE,
close_POKEn_VALVE and toggle_POKEn_VALVE. The IR half of the same
feature was already called from interrupts.c, so both halves now sit
outside the generated header.

The three headers are now exactly what the generator emits, and
verify-generated regenerates them and fails on any difference. The
raw set, clr and tgl pin macros still exist and no longer mimic, so a
call site must reach for the wrapper.
A .python-version file sets the default interpreter to the oldest
supported version, so local work runs against the floor of
requires-python. Because the file also overrides --python on the sync
step, the CI job now selects the matrix version through UV_PYTHON,
which takes precedence over the file.

@aspaNeuro aspaNeuro left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested with mircoharp converging with this setup and approach

@glopesdev
glopesdev merged commit dc41486 into harp-tech:main Sep 25, 2026
20 checks passed
@glopesdev
glopesdev deleted the feature/unified-release branch September 25, 2026 15:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation feature New planned feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants