



























In rare cases, project build may require different configuration depending on operating system that runs the build.
In Maven, it can be done with Maven Profiles.
maven-enforcer-pluginYou can define profile for each supported operating system and provide different configuration, which includes dependencies, build plugins or just setting different OS specific property value.
xml
<profiles>
<profile>
<id>windows</id>
<properties>
<my.property>running.on.windows</my.property>
</properties>
</profile>
<profile>
<id>mac</id>
<properties>
<my.property>running.on.mac</my.property>
</properties>
</profile>
<profile>
<id>unix</id>
<properties>
<my.property>running.on.linux</my.property>
</properties>
</profile>
</profiles>Profiles can be activated manually by setting -P flag to Maven command:
bash
$ mvn package -PwindowsLikely, you would like to avoid the need for user to set this profile. Maven can figure it out by checking the operating system the build is running on and activating a profile for this OS:
xml
<profile>
<id>windows</id>
<activation>
<os>
<family>windows</family>
</os>
</activation>
<properties>
<my.property>running.on.windows</my.property>
</properties>
</profile>Activation can be narrowed to specific operating system name, architecture or even exact version. To not end up with dozens of profiles, assuming we are running builds only on x86 64bit architectures we can use family to let Maven activate the profile.
Family may have one of the following values:
If you look closely, you may have noticed that there is no family for Linux. There is one for unix, but Mac is unix too.
When we use following profiles' config:
xml
<profiles>
<profile>
<id>windows</id>
<activation>
<os>
<family>windows</family>
</os>
</activation>
<properties>
<my.property>running.on.windows</my.property>
</properties>
</profile>
<profile>
<id>mac</id>
<activation>
<os>
<family>mac</family>
</os>
</activation>
<properties>
<my.property>running.on.mac</my.property>
</properties>
</profile>
<profile>
<id>linux</id>
<activation>
<os>
<family>unix</family>
</os>
</activation>
<properties>
<my.property>running.on.linux</my.property>
</properties>
</profile>
</profiles>Build will run as expected on Windows and Linux, but on Mac both mac and unix profile will be active.
To properly narrow it down to activate linux profile only when running on Linux, and mac profile only when running on Mac, the Linux profile must be activated by operating system name:
xml
<profiles>
<profile>
<id>windows</id>
<activation>
<os>
<family>windows</family>
</os>
</activation>
<properties>
<my.property>running.on.windows</my.property>
</properties>
</profile>
<profile>
<id>mac</id>
<activation>
<os>
<family>mac</family>
</os>
</activation>
<properties>
<my.property>running.on.mac</my.property>
</properties>
</profile>
<profile>
<id>linux</id>
<activation>
<os>
<name>Linux</name>
</os>
</activation>
<properties>
<my.property>running.on.linux</my.property>
</properties>
</profile>
</profiles>With such configuration, when build runs on the OS that does not match any of the activations, simply no profile will be active and likely build fails in unexpected way due to a missing whatever-you-defined-in-profile-configuration.
To avoid it, you can use maven-enforcer-plugin to ensure that one of the profiles is active:
xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>enforce-os-profile</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireActiveProfile>
<profiles>windows,mac,linux</profiles>
<all>false</all>
</requireActiveProfile>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>If your build depends on the operating system, it is worth to run it on the CI server against each of the supported OS.
GitHub Actions supports running jobs on Ubuntu, Windows and Mac OS. A sample action that runs Maven build on each of these is:
yml
name: Build
on: [push]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
cache: maven
- run: ./mvnw packageUnfortunately at this stage there is no out-of-the-box support for running jobs on runners with ARM processors, such as Apple M1. If that's what you need, you must use a self hosted runner on GitHub and one of the providers that offer M1 - but it is not free.
Let's stay in touch and follow me on Twitter: @maciejwalkowiak
Subscribe to RSS feed ![]()
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。