Building and Releasing

This guide explains the build system of OpenRocket (Gradle), and how to release a new version of OpenRocket.


Gradle

Gradle is the build system for OpenRocket. It is used to compile the source code, run tests, and create the JAR file. Key features of Gradle are:

  • Incremental builds: Gradle only rebuilds what is necessary, which makes the build process faster.

  • Dependency management: Gradle has a robust dependency management system capable of handling project and third-party libraries.

  • Performance: Gradle uses techniques like build caching and parallel execution to improve performance of the build process.

The root directory of the OpenRocket repository contains several Gradle files:

  • build.gradle: This is the main build script file where you define your project configuration and tasks such as compile and run tasks, dependency management, plugins usage, and more.

  • settings.gradle: Used for multi-project build configurations to include which sub-projects should be part of the build. For OpenRocket, this file is used to identify the core and swing sub-projects.

  • gradle.properties: Contains project-wide properties that can be accessed from the build script. For example, the version number of OpenRocket can be defined here.

  • gradlew and gradlew.bat: These are Gradle Wrapper scripts for Unix-based and Windows systems respectively. It allows users to run Gradle builds without requiring Gradle to be installed on the system.

The core and swing sub-projects contain their own build.gradle and gradle.properties files that define the tasks specific to those sub-projects.

Gradle in IntelliJ

If you use IntelliJ IDEA, you can access the Gradle tasks within the IDE. First, open the Gradle tool window by going to View ‣ Tool Windows ‣ Gradle or by clicking on the Gradle icon in the right-hand side of the window:

Opening the Gradle tool window in IntelliJ IDEA.

Opening the Gradle tool window in IntelliJ IDEA.

This shows the following window:

The Gradle tool window in IntelliJ IDEA.

The Gradle tool window in IntelliJ IDEA.

Here’s a breakdown of the Gradle tasks:

  • info.openrocket: the root project
    • Tasks: Gradle tasks specific to the root project.
      • application: Contains tasks related to running or debugging your application from within the IDE.

      • build: Includes tasks for building the entire project.

      • build setup: Tasks for initializing a new Gradle build, such as creating new Gradle files.

      • distribution: Tasks for assembling the application distribution, like creating zips or tarballs of the build outputs.

      • documentation: Tasks for generating documentation, typically using tools like Javadoc.

      • help: Provides tasks that list other tasks or project properties.

      • info.openrocket: Custom tasks specific to the ‘info.openrocket’ module.

      • other: Any other tasks that do not fit into the predefined categories.

      • shadow: Related to the Shadow plugin, which packages the project’s artifacts along with its dependencies into a single “fat” JAR.

      • verification: Tasks for testing and verifying the project, such as running unit tests.

    • Dependencies: Lists the dependencies of the project.

    • Run Configurations: Gradle run configurations that can be used in IntelliJ.

  • core: the core module
    • Tasks: Gradle tasks specific to the ‘core’ module.

    • Dependencies: Lists the dependencies of the ‘core’ module.

  • swing: the swing module
    • Tasks: Gradle tasks specific to the ‘swing’ module.

    • Dependencies: Lists the dependencies of the ‘swing’ module.

Most Important Gradle Tasks

Here are some of the most important Gradle tasks for OpenRocket:

Most Important Gradle Tasks

Module

Task

Description

root (info.openrocket)

clean

Deletes the build directory and all its contents (basically cleans up the project).

root (info.openrocket)

run

Runs the OpenRocket application.

root (info.openrocket)

check

Runs the unit tests and checks the code quality using the Checkstyle static analysis tool.

root (info.openrocket)

build

Compiles the source code, runs the unit tests, and creates the JAR file for the core and swing module.

root (info.openrocket)

dist

Creates a distributable JAR file of OpenRocket (a combination of the core and swing JAR) at openrocket/build/libs/OpenRocket-<build-version>.jar.

core

serializeEngines

Fetch the latest thrust curves from ThrustCurve.org and serialize them to the OpenRocket format. The resulting serialized file is saved in the src dir so it can be used for a build.

core

serializeEnginesDist

Same as serializeEngines, but loads the serialized file to the distribution directory (openrocket/build) so it can be used in the final build.

core

submoduleUpdate

Updates the submodule dependencies of the core module.

You can run these tasks from the command line using the Gradle Wrapper scripts. For example for the task run, run the following command in the root directory of the OpenRocket repository:

# On macOS and Linux:
./gradlew run

# On Windows:
gradlew.bat run

install4j

install4j is used to create the packaged installers for OpenRocket from the JAR file. install4j generously provides a free license for open source projects, including OpenRocket. Currently, only the OpenRocket administrators have access to the install4j license.

Code Signing

An important part of generating the installers is code signing. This is done to ensure that the installer is not tampered with between the time it is created and the time it is run by the user. Once the OpenRocket installer has been code signed, users will receive no more (or the minimum amount of) warnings from their operating system that the installer is from an unknown source and may contain malware. More information on how to do code signing in install4j can be found here.

Only the OpenRocket administrators have access to the code signing certificates.

Code signing for Windows is done using a digital certificate from Sectigo. More information on the code signing procedure, including whitelisting OpenRocket by Microsoft, see the README file on GitHub.

For macOS, the code signing is done using an Apple Developer ID. Besides code signing, the OpenRocket app also needs to be notarized. Luckily, install4j takes care of this. More information on the code signing procedure for macOS can be found in the README file on GitHub.

Linux does not require code signing.

Creating the Installers

First you need to build the project using Gradle (see above). This will create the JAR file that will be used to create the installers.

Then, open install4j (requires a license) and load the project file openrocket/install4j/<build-version>/openrocket-<build-version>.install4j from the repository. Go to the Build tab and click on the Start Build button. This will create the installers in the openrocket/install4j/<build-version>/media/ directory.

Building the installers in install4j.

Building the installers in install4j.

If you do not have access to the code signing certificates, you can create the installers without code signing by enabling the checkboxes Disable code signing and Disable notarization in the Build tab.

Release Procedure

The release procedure for OpenRocket is as follows:

  1. Update the ReleaseNotes.md with the changes that are part of the new release. This includes new features, bug fixes, and other changes that are part of the release. Make sure to include the version number and the release date. Take a look at the previous release notes to see how it should be formatted.

  2. Update the component database and thrustcurves by running the gradle tasks subModuleUpdate and serializeEnginesDist respectively.

  3. Update the version number in openrocket/core/src/main/resources/build.properties to the correct version number.

    For official releases, the version number should use the format YY.MM (year.month). For example, if the software is released in September 2023, the version number should be 23.09. If there are multiple releases in the same month, add an incremental number to the version number, e.g. 23.09.01.

    If a new release contains significant changes, it may be necessary to release alpha or beta versions first. In that case, the version number should be appended with .alpha. or .beta. plus an incremental number. For example, if the software is in beta stage in September 2023, the version number should be 23.09.beta.01. In general, alpha releases are not necessary. This is only for very rough releases. Beta releases are only necessary if there are significant changes that need to be tested by the community before the final release.

    One final option is to release a release candidate (RC) version. This is a version that is considered to be the final version, but needs to be tested by the community before the final release. The version number should be appended with .RC. plus an incremental number. For example, if the software is in RC stage in September 2023, the version number should be 23.09.RC.01.

    The official release that comes after the beta release should have the same version number as the beta release, but without the .beta. part. For instance, if the beta testing started in September 2023 with version number 23.09.beta.01, the final release should have version number 23.09, even if the final release is in November 2023. This is to ensure consistency in the version numbering and to link the beta release(s) to the final release.

  4. Build the project JAR file using Gradle (see above).

  5. Test the JAR file to ensure that it works correctly and that the new version number is applied to the splash screen and under Help ‣ About.

  6. Create the packaged installers using install4j (see above).

    Warning

    Make sure to enable code signing for the installers.

    Make sure that DS_Store for the macOS installer is updated. Instructions can be found here.

  7. Test the installers to ensure that they work correctly.

  8. Prepare the website (for official releases only, not for alpha, beta, or release candidate releases).

    The source code for the website needs to be updated to point to the new release. Follow these steps:

    • Add the release to downloads_config.json.

    • Update the current_version in _config.

    • Add a new entry to _whats_new for the new release. Create a wn-<version number>.md file with the changes that are part of the new release. Please take a close look to the previous entries to see how it should be formatted.

    • Update the release notes (which is a link to the What’s new file that you just created). Again, take a close look at the previous entries to see how it should be formatted.

    Warning

    Make sure to update the website on the development branch. The master branch is the branch that is live on the website. First update the development branch and test the changes on the website. In a later step, the changes will be merged to the master branch.

  9. Publish the release on GitHub.

    Go to the releases page. Click Draft a new release. Select Choose a tag and enter a new tag name, following the format release-<version number>, e.g. release-23.09. The title should follow the format OpenRocket <version number> (<release date as YYYY-MM-DD>), e.g. OpenRocket 23.09 (2023-11-16).

    Fill in the release text, following the ReleaseNotes.md. If you want to credit the developers who contributed to the release, you can tag them anywhere in the release text using the @username syntax. They will then be automatically displayed in the contributors list on the release page.

    Finally, upload all the packaged installers and the JAR file to the release. The source code (zip and tar.gz) is automatically appended to each release, you do not need to upload it manually.

    If this is an alpha, beta, or release candidate release, tick the Set as a pre-release checkbox.

    Click Publish release.

  10. Push the changes to the website

First, build the development branch locally to verify that the changes that you made in step 8 are correct. If everything is working (test the download links, the release notes, and the What’s new page), create a new PR that merges the changes from the development branch to the master branch.

  1. Send out the release announcement.

    Send out the release announcement to the OpenRocket mailing list, the TRF forum, and the OpenRocket social media channels (Discord, Facebook…).

    The announcement should include the new features, bug fixes, and other changes that are part of the new release. Make sure to include the download links to the new release. Here is an example announcement.

  2. Merge the unstable` branch to the master` branch.

    After the release is published, merge the changes from the unstable branch to the master branch.

  3. Upload the new release to SourceForge.

The downloads page on SourceForge is still very actively used, so be sure to upload the new release there as well.

  1. Update package managers (e.g. snap, Chocolatey, Homebrew) with the new release.