-
Notifications
You must be signed in to change notification settings - Fork 2
Build Guide
There are two build systems used in SolarNetwork, one for SolarNode and one for SolarNet.
For SolarNode, which is merely collections of OSGi bundles (otherwise known as "plugins"), building any one application involves building the individual bundles that application requires and then deploying them into the appropriate OSGi container environment. This guide will detail how individual bundles are built, along with some details on specific SolarNetwork applications.
In order to build SolarNode bundles you need Ant and Java (Java 8 minimum). These can be installed on macOS using Homebrew:
# macOS install using Homebrew
brew install ant openjdk@8
Linux distributions provide similar packages.
To build the SolarNode bundles you must clone the solarnetwork-build, solarnetwork-common, solarnetwork-external, and solarnetwork-node repositories. You must adhere to the following filesystem directory structure for the various Git repositories, i.e. clone all the repositories into a common parent directory and keep the repository directory named exactly as named on GitHub:
<SolarNode build home>/
├── solarnetwork-build/
├── solarnetwork-common/
├── solarnetwork-external/
└── solarnetwork-node/
⚠️ Note that thesolarnetwork-build
repository requires Git LFS support. On macOS this can be installed using Homebrew withbrew install git-lfs
. On Linux most distributions provide agit-lfs
package you can install.
For example, these commands create a new build home directory and clone the Git repositories:
mkdir solarentwork-dev
cd solarnetwork-dev
git clone [email protected]:SolarNetwork/solarnetwork-build.git
git clone [email protected]:SolarNetwork/solarnetwork-common.git
git clone [email protected]:SolarNetwork/solarnetwork-external.git
git clone [email protected]:SolarNetwork/solarnetwork-node.git
Within each of the Git repositories will be a set of directories, each representing a single OSGi
bundle project. For example the solarnetwork-common
repository looks like this:
solarnetwork-common
├── LICENSE
├── net.solarnetwork.common/
├── net.solarnetwork.common.expr.spel/
├── net.solarnetwork.common.expr.spel.test/
├── net.solarnetwork.common.internal.test/
├── net.solarnetwork.common.jdbc.pool.hikari/
├── net.solarnetwork.common.jdbc.pool.hikari.test/
├── net.solarnetwork.common.jdt/
├── net.solarnetwork.common.jdt.test/
├── net.solarnetwork.common.log4j2/
...
To build a bundle JAR, cd
into that bundle's project directory and execute
ant jar
For example, to build the net.solarnetwork.common bundle, you'd do the following:
$ cd solarnetwork-common/net.solarnetwork.common
$ ant jar
Buildfile: build.xml
...
jar.classes:
[echo] [====> Building JAR target/net.solarnetwork.common-1.10.0.jar <====]
jar.no.classes:
jar:
BUILD SUCCESSFUL
Total time: 1 second
From the build output, you can see the target/net.solarnetwork.common-1.10.0.jar bundle JAR was built.
Most bundle projects have a companion unit test project that is configured as an OSGi fragment on
the bundle being tested. Generally the unit test projects have the same name as the main project,
with .test
added to the end. For example, the net.solarnetwork.common.web project has a unit
test project named net.solarnetwork.common.web.test. The MANIFEST.MF
for the unit test project
declares it as a fragment on the net.solarnetwork.common.web bundle:
Bundle-Name: SolarNetwork Common Web Test
Bundle-SymbolicName: net.solarnetwork.common.web.test
Bundle-Version: 1.3.1
Bundle-Vendor: SolarNetwork
Fragment-Host: net.solarnetwork.common.web;bundle-version="1.14.1"
Configuring the unit tests in fragment bundles like this has the advantages of keeping the unit test code outside the host bundles and allows the unit tests to have full access to the imported classpath of the host bundle.
Unit tests can be run inside Eclipse by simply right-clicking on any test or test project and
choosing Run As > JUnit Test. They can be run on the command line via the test
Ant target
(after running the jar
target). For example:
$ cd net.solarnetwork.common.web.test
$ ant jar test
Buildfile: build.xml
...
test.run:
[mkdir] Created dir: target/reports
jacoco.init:
test.run.coverage:
test:
BUILD SUCCESSFUL
Total time: 2 seconds
You can run all available unit tests from all the Git repositories by running the
test-all-clean
Ant task in the solarnetwork-build/solarnetwork-osgi-lib/test.xml
build script
(i.e. from the solarnetwork-build repository). Ant needs a fair bit of memory for the tests to
complete successfully, so you can pass ANT_OPTS=-Xmx4g
to give Ant more memory:
$ cd solarnetwork-build/solarnetwork-osgi-lib
$ ANT_OPTS=-Xmx4g ant -f test.xml test-all-clean
Once the tests have completed a HTML report of the results will be available at
reports/unittest/index.html
. Be aware that running all tests in this way can take a while to
complete!
You can also run a subset of all OSGi bundle unit tests by providing a test.buildfiles
property
to your execution. For example to run only the solarentwork-common
repository tests you could
define test.buildfiles=solarnetwork-common/\*.test/build.xml
, like this:
$ cd solarnetwork-build/solarnetwork-osgi-lib
$ ANT_OPTS=-Xmx4g ant -f test.xml -Dtest.buildfiles=solarnetwork-common/\*.test/build.xml test-all-clean
To publish SolarNetwork plugins to Maven Central, run the stage
task, which will publish to a
Sonatype staging area. You can then use the Sonatype UI to release the staged
artifacts.
The Sonatype credentials (which are your Sonatype JIRA credentials) are configured in
~/.m2/settings.xml
:
<server>
<id>ossrh</id>
<username>USERNAME</username>
<password>PASSWORD</password>
</server>
GPG must be configured in ~/.m2/settings.xml
for signing the artifacts:
<profile>
<id>gpg</id>
<properties>
<gpg.keyname>4BC94956</gpg.keyname>
<gpg.passphrase>{GAHTJ...PHR6}</gpg.passphrase>
</properties>
</profile>
The gpg.passphrase
value must be the encrypted password for the GPG private key, which you
encrypt via
mvn --encrypt-password
See the Maven Docs for more information.
SolarNet uses Gradle for its build system.
In order to build SolarNet you need Java (Java 21 minimum). This can be installed on macOS using Homebrew:
# macOS install using Homebrew
brew install ant openjdk@21
Linux distributions provide a similar package.
To build SolarNet you must clone the solarnetwork-central repository.
mkdir solarentwork-dev
cd solarnetwork-dev
git clone [email protected]:SolarNetwork/solarnetwork-central.git
The repository structure contains a solarnet
directory for the SolarNet application code and a
solarnet-db-setup
directory for the Postgres database setup scripts. The solarnet
directory
contains many subdirectories which are all compontents that make up the SolarNet platform. The
main SolarNet applications — SolarIn, SolarJobs, SolarQuery, and SolarUser — are all located in
similarly named directories solarin
, solarjobs
, solarquery
, and solaruser
.
The solarnet
directory strcuture looks like this (some folders have been omitted for brevity):
solarnetwork-central/
├── LICENSE
├── README.md
├── solarnet/
│ ├── LICENSE
│ ├── README.md
│ ├── application.yml
│ ├── build.gradle
│ ├── common/
│ ├── common-test/
│ ├── config/
│ ├── datum/
│ ├── gradle/
│ ├── gradle.properties
│ ├── gradlew*
│ ├── gradlew.bat
│ ├── solarin/ # the SolarIn application
│ ├── solarjobs/ # the SolarJobs application
│ ├── solarquery/ # the SolarQuery application
│ ├── solaruser/ # the SolarUser application
│ └── user/
└── solarnet-db-setup/
├── README.md
└── postgres/
The solarnet-db-setup
directory contains one main postgres
sub-directory. Within that are all
the SQL setup files along with a bin/setup-db.sh
script for creating, or re-creating, the Postgres
database. The directory strcture looks like this (some items have been omitted for brevity):
solarnetwork-central/solarnet-db-setup/
├── README.md
└── postgres/
├── README.md
├── bin/
│ └── setup-db.sh* # script to (re)create the database
├── migrations/ # migration scripts for changes to existing databases
├── postgres-create.sql
├── postgres-disable-triggers.sql
├── postgres-enable-triggers.sql
├── postgres-init-common-schema.sql
├── postgres-init-common.sql
├── postgres-init-core-schema.sql
├── postgres-init-core.sql
├── postgres-init-users.sql
├── postgres-init.sql
└── updates/ # update SQL for changes to existing databases
See the SolarNet Development Guide for information on creating the database.
To build SolarNet run the build -x test
Gradle task in the solarentwork-central/solarnet
directory. For example:
# on POSIX platforms
cd solarnetwork-central/solarnet
./gradlew build -x test
# on Windows
.\gradlew.bat build -x test
To run the SolarNet unit tests, execute the test
task in Gradle:
./gradlew test
# or run tests implicitly with the build task by omitting the '-x test' arguments
./gradlew build
solarnetwork_unittest
using
credentials solartest/solartest
. Once Postgres is installed with all SolarNet's required
extensions you can create a unit test database like:
cd solarnetwork-centrl/solarnet-db-setup
./bin/setup-db.sh -rv -u solartest -d solarnetwork_unittest
See the SolarNet Development Guide for more information.