Skip to content

Building and Releasing HARP ​

HARP is part of a collaborative research project funded by NSF Award 2222129. All of its code is open source, and we follow issues and pull requests on both the HARP and PyHARP repositories.

There are three ways to contribute:

  • A model for others to use. Deploying Models with PyHARP ends in a hosted app that any user of HARP can open by its path. If you would like to have your model featured on the Home tab, please contact us.
  • A change to the application. This page covers building, debugging, and releasing HARP.
  • Support for a new service. A service with an API of its own is reached through a client class of its own, as Adding an API Provider describes.

Reports of bugs and requests for features are welcome as issues. Attach the log to a bug report, which File > Settings > General > Open Log Folder reveals, and which never contains API keys.

Guidelines ​

  • Developing: coding conventions, error handling, logging, and layout.
  • Reviewing: what a pull request needs, and how to review one. Every pull request needs two approvals.
  • Deployment: the conventions of the models we host.
  • Code Signing: signing and notarizing the release packages.
  • Website: building and editing this site, and administering its hosting and domain.

Code Organization ​

HARP is a JUCE application in C++20, under src/. A request passes through these parts:

  • MainComponent holds the menu bar, the tabs, the media clipboard, and the status area.
  • ModelTabContainer holds the Home tab, which browses the model catalog, and a tab for each open model.
  • ModelTab controls one model, and runs its work on thread pools, so that nothing blocks the interface.
  • Model holds the state of a model, parses its interface, and builds each request.
  • Client and its subclasses translate requests into the API of a provider: GradioClient for any Gradio app, and StabilityClient for Stability AI.
  • media/ displays audio, MIDI, and file tracks, and the labels over them.

Building ​

HARP builds with CMake 3.22 or newer and a C++20 compiler: Xcode on macOS, Visual Studio on Windows, or GCC or Clang on Linux.

The same commands build HARP on macOS, Windows, and Linux:

bash
git clone --recurse-submodules https://github.com/TEAMuP-dev/HARP
cd HARP
cmake -B build -DCMAKE_BUILD_TYPE=Debug .
cmake --build build --config Debug --parallel

The build writes the binary to build/HARP_artefacts/Debug/, as HARP.app on macOS, HARP.exe on Windows, and HARP on Linux. It accepts media files as arguments, and can be invoked from the command line:

bash
./build/HARP_artefacts/Debug/HARP resources/media/test.wav resources/media/test.mid

Two platforms require additional steps. On macOS, -DCMAKE_OSX_ARCHITECTURES set to arm64, x86_64, or "arm64;x86_64" selects the architecture, the last of these producing a universal binary. On Linux, the JUCE dependencies must be installed first. There are no C++ unit tests, so a change is verified by running the application.

Add -G Ninja to the configure command to build with Ninja, and replace Debug with Release for a release build. New source files go in target_sources in CMakeLists.txt, since the build does not glob for them. Format C++ with clang-format, using the .clang-format of the repository.

Debugging ​

In Visual Studio Code, install Microsoft's C/C++ extension, then add a configuration to launch.json pointing at the built binary, uncommenting the line for the platform in use:

json5
{
    "name": "Standalone HARP",
    "type": "cppdbg",
    "request": "launch",
    "program": "${workspaceFolder}/build/HARP_artefacts/Debug/HARP.app", // macOS
    //"program": "${workspaceFolder}/build/HARP_artefacts/Debug/HARP.exe", // Windows
    //"program": "${workspaceFolder}/build/HARP_artefacts/Debug/HARP", // Linux
    "args": ["../resources/media/test.wav", "../resources/media/test.mid"],
    "cwd": "${fileDirname}",
    "MIMode": "lldb" // macOS
}

An alternative configuration using "request": "attach" with "processId": "${command:pickProcess}" attaches to an instance of HARP that is already running, such as one a DAW has launched.

HARP logs every request, every change in the state of a model, and every error to main.log, which explains most failures the interface reports. HARP allows one instance per user (moreThanOneInstanceAllowed in Main.cpp), so a second launch hands its file arguments to the running one, which asks whether to open them in a new window, and then exits. Close any running copy before starting one under the debugger.

Distribution ​

GitHub Actions builds and packages every push. Pushing a tag of the form v* also publishes a release, taking RELEASE.md as its notes.

A macOS build can be packaged locally into a DMG with dmgbuild:

bash
packaging/package.sh build/HARP_artefacts/Release/HARP.app HARP.dmg

Signing and notarizing that DMG in CI requires the MACOS_CERTIFICATE and MACOS_CERTIFICATE_PASSWORD secrets for the signing certificate, and APPLE_ID with APPLE_APP_PASSWORD for notarization. SIGNING.md covers both, along with signing a build on your own machine.

To release a version, update VERSION and RELEASE.md, name the PyHARP it pairs with in the root README.md, which Setting Up PyHARP includes, and push a tag such as v4.0.0. The download page builds its download links from VERSION, so they lead to the packages of the new release once the workflow publishes them. The demo files it links are an asset of the 4.0.0 release. To change them, attach a new HARP-demo-files.zip to the latest release, and point the download page at that release.

Released under the BSD 3-Clause License.