Usage
Available commands
Nyx provides the same features in all the available versions but the means to invoke each may change. This table summarizes the available commands and gives the available name for each when using different versions.
Name | Command Line Command | Gradle Task Name |
---|---|---|
Clean | clean |
nyxClean |
Infer | infer |
nyxInfer |
Make | make |
nyxMake |
Mark | mark |
nyxMark |
Publish | publish |
nyxPublish |
Using the command line
Download the binary
You can find the latest binaries for any platform in the latest release assets.
Make sure you store the binary so that it’s available from the PATH
and it has execution permissions.
This guide assumes you rename the executable as nyx
, regardless of the platform (or nyx.exe
on Windows).
This is all you need to use Nyx on the command line.
Synopsis
Nyx comes with a whole lot of arguments that you can pass on the command line to let you control every single aspect of its behavior. You can see them all by running nyx --help
, from which we have an abbreviated output here:
nyx --help
Nyx version: 3.0.0
Usage:
nyx [arguments] [command]
Commands are:
clean reverts the repository to its initial state and removes files created by other commands, if any
infer inspects the commit history and repository status and computes the project version
make produces artifacts (i.e. changelog) as per the configuration
mark commits, tags and pushes, according to the configuration and the repository status
publish publish the new release, if any, to the configured services
Global arguments are:
[...]
Changelog arguments are:
[...]
Commit Message Conventions arguments are:
[...]
Git arguments are:
[...]
Git arguments are:
[...]
Release Type arguments are:
[...]
Services arguments are:
[...]
As you can see you can give as much arguments as you like and one command at the end. Arguments start with a single (-
) or double dash (--
) and are detailed in the full output from nyx --help
and in the configuration reference.
The command needs to appear at the end of the command line with no dash sign. If you don’t specify any command Nyx will run the default one infer
. For an introduction on what every command does see below or How Nyx Works.
Dynamic argument names
One thing that is important to note is that many arguments names are dynamic and this may be confusing at first as it’s different than common arguments on other tools. For example, the --services-<NAME>-type=<TYPE>
argument has a dynamic <NAME>
in the attribute name.
This is to allow users to define the <TYPE>
value for arbitrary services whose name is dynamically configured. When passing this as an actual argument on the command line also the <NAME>
part needs to be replaced so for example --services-gh-type=GITHUB
sets the type GITHUB
for a service instance configured under the name gh
.
This kind of notation implies that the internal configuration model always creates a service configuration named gh
whenever an argument like this is provided. This is somewhat different from configuration files where you need to create a gh
section and then define additional options underneath.
Since argument names are dynamically defined Nyx will not complain in case of unsupported arguments.
Run the command
All you have to do is run the command according to the synopsis above. Remember to run Nyx from the Git project directory or pass the --directory
argument.
Also keep in mind that when no command is given on the command line infer
is executed by default. This will generate and display the latest version for the project but will not change anything in the project directory. To run other commands you can specify them explicitly, as shown below.
Configuration
You have different means to configure the tool. Whichever combination you use, see the configuration reference for a detailed description of each option.
In some cases you might prefer using command line arguments while in others configuration files (or even a combination of) might be the way you pick. In order to support some edge cases, all options can also be passed as environment variables.
Different configuration methods can be combined together with well known priorities of each means over the others so you have complete freedom to create configuration baselines and override values as you need. This might be especially useful for large organizations. See the configuration methods for more on this.
Using command line arguments
With the above said, you can start easy with:
nyx --preset=simple infer
This runs the infer command and uses the simple preset.
Keep in mind that while presets are a handy way to avoid repeating streamlined configurations, you don’t need to use them and you can define your own from scratch by whatever configuration means.
Using configuration files
If you rather prefer to configure Nyx by means of configuration files you can use one of the default configuration files that are looked up automatically or set the configurationFile
global option to look for a file in a custom location.
Nonetheless, you can override configuration options from configuration files with command line arguments.
The Nyx State
You can enable writing the Nyx state file by using the --state-file
argument. You can have it in JSON or YAML, depending on the extension you set. Example:
nyx --state-file=nyx-state.json infer
After this command runs you can read the nyx-state.json
file to inspect its contents and use them for other purposes. Check out the State Reference to know more about the contents and how powerful this can be.
Exit codes
Nyx always returns 0 as the exit code unless some error occured, in which case 1 or other values other than 0 are returned.
Using the Docker image
Many teams prefer using Docker containers for their CI/CD and local development environments. If that’s your case you can use the Docker container that comes out of the box with Nyx.
The Docker images are published onto the two main registries:
- Docker Hub (the default)
- GitHub Container Registry
Nyx’ Docker image has a small footprint (less than 10Mb) and uses Alpine Linux as the base image.
All the examples in this page assume you’re using the latest
image pulling it from Docker Hub. They also assume you’re making an ephemeral use of the container (you run it and dispose it every time). In case you need advanced use cases other than these please refer to the official Docker Documentation.
Requisites
All you need is a recent version of Docker installed and running.
Pull the image
Let’s start by pulling the image from the public registry. Open a shell and run:
$ docker pull mooltiverse/nyx:latest
latest: Pulling from mooltiverse/nyx
ab6db1bc80d0: Pull complete
[...]
Digest: sha256:976f4821d643e02fc55c884cd6c9af5e958011132145150b7dd97e01d71ba055
Status: Downloaded newer image for mooltiverse/latest
mooltiverse/latest
and make sure the new image is there:
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
mooltiverse/nyx latest a14cbc284e81 2 days ago 7.35MB
Run the container
To run the container you simply run a command like:
$ docker run -it --rm -v /local/path/to/project:/project mooltiverse/nyx:latest
A few things to note here:
- there is no explicit command executed within the container because
nyx infer
is executed by default. This will generate and display the latest version for the project but will not change anything in the project directory. To run other commands you can specify them explicitly, as shown below - a local folder (
/local/path/to/project
) is mounted from the host into the container at the default location/project
. You need to change/local/path/to/project
to whatever path is hosting your Git repository, or mount a Docker volume hosting the Git repository in case you already have one (in this case, pass your volume name to the command line likedocker run -it --rm -v project-volume:/project mooltiverse/nyx:latest [...]
, whereproject-volume
has to be changed to your volume name) - Nyx is using the default configuration means (configuration files available in the project directory at standard locations)
When running on Linux or Mac hosts you may also want to map the host user ID to the container user in order to avoid issue with file permissions. You can do this by adding this option to the command line: -u $(id -u):$(id -g)
. See the Docker run reference for more.
Running specific commands
In order to run a specific command you need to pass it on the command line, like:
$ docker run -it --rm -v /local/path/to/project:/project mooltiverse/nyx:latest <COMMAND>
So if you need to run the publish command, run the container as:
$ docker run -it --rm -v /local/path/to/project:/project mooltiverse/nyx:latest publish
Mounting the project volume or folder
You can pass Nyx your project folder as a path on the host or as a Docker volume. What you need to do is:
- replace
/local/path/to/project
with an actual host path when the project directory is shared from the Docker host to the container, or - replace
/local/path/to/project
with a Docker volume name when the project directory is already in a Docker volume
For more on volumes and mounts please see the official Docker documentation.
Passing the configuration to Nyx
Generally speaking, configuring Nyx within a container is just like using it from the command line. This means that if configuration files are available in the project directory at their default locations they will be loaded as usual and if additional options are passed on the command line they will be used.
The one caveat abous passing configuration as environment variables in a Docker container is about setting those variables by means of one or more -e
flags.
Using the Gradle plugin
When using Gradle, the native Nyx plugin is the easiest and most effective way of using Nyx. The plugin can be used with the Groovy or the Kotlin syntax, although this documentation always refers to Groovy unless otherwise specified.
All the examples in this page assume you’re using the plain gradle
command. If you’re using the (recommended) wrapper just change instances of the gradle
command with ./gradlew
.
Some extra information on the Gradle Plugin internals is available here.
Apply the plugin
You can apply the plugin as a project plugin or as a settings plugin. You’re suggested to use the settings plugin to make sure you have properties are evaluated early in the build lifecycle as detailed in this post.
When using Groovy you can use the same plugin DSL in both cases:
plugins {
id "com.mooltiverse.oss.nyx" version "3.0.0"
}
Add the above definition to the settings.gradle
file to deploy the plugin as a settings plugin (suggested) or to the build.gradle
file to deploy the plugin as a project plugin.
If you’re using Kotlin you can use this example for your build.gradle.kts
or settings.gradle.kts
when applying the project plugin or settings plugin, respectively:
plugins {
id("com.mooltiverse.oss.nyx") version "3.0.0"
}
Configure the plugin
You have different means to configure the plugin and in these sections we’ll introduce you to all of them. Whichever combination of configuration means you use, see the configuration reference for a detailed description of each option.
The version
configuration option is not handled like other options because it would overlap Gradle’s standard version
project property. The plugin reads and writes the standard Gradle option to provide a consistent behavior and reduce impact on existing build scripts. See here for more.
You can also mix different configuration means according to the configuration evaluation order in order to use what better suits your needs. Mixed configurations are often used to reuse some parts or entire configurations across projects and organizations or to override some inherited values on a project basis.
Examples of different configuration files are available here.
Using the extension
The easier way to configure Nyx is via a Gradle extension.
When using Groovy the extension is a configuration block named nyx
you add inside your settings.gradle
or build.gradle
script (depending on where and how you applied the plugin, as a settings plugin or project plugin, respectively), like this:
plugins {
id "com.mooltiverse.oss.nyx" version "3.0.0"
}
nyx {
// a few examples
dryRun = false
resume = false
stateFile = '.nyx-state.yml'
verbosity = "INFO"
}
The configuration block shown above is where you can place configuration options defined in the configuration reference using the Gradle syntax.
When using Kotlin you still have a configuration block very similar to the one above but with some differences.
Configuring the project plugin using Kotlin you add something like this to your build.gradle.kts
:
plugins {
id("com.mooltiverse.oss.nyx") version "3.0.0"
}
nyx {
// a few examples
dryRun.set(false)
resume.set(false)
stateFile.set(".nyx-state.yml")
verbosity.set("DEBUG")
}
As you can see Kotlin uses a different way to set values. If, instead, you’re configuring the settings plugin in Kotlin your settings.gradle.kts
file looks like:
plugins {
id("com.mooltiverse.oss.nyx") version "3.0.0"
}
configure<com.mooltiverse.oss.nyx.gradle.NyxExtension> {
// a few examples
dryRun.set(false)
resume.set(false)
stateFile.set(".nyx-state.yml")
verbosity.set("DEBUG")
}
So, when using Kotlin, the difference between configuring the project plugin or settings plugin is in the way the configuration block starts.
Using configuration files
If you rather prefer to configure Nyx by means of configuration files you can use one of the default configuration files that are looked up automatically or set the configurationFile
global option to look for a file in a custom location.
Multi-project builds
If you have a multi-project build and apply the plugin in the settings.gradle
file you can only apply it to the root project as that’s how Gradle restricts the settings.gradle
. On the other hand, if you use the settings.gradle
, the Nyx plugin should be applied to the root project only as it’s supposed to be where the Git repository is located.
Nyx makes no hard checks whether it’s applied to the root project or a subproject so if you know what you’re doing you can apply the plugin to one of the subprojects as well.
To use the project version from subprojects you should use the rootProject.version
property instead of the simple version
or project.version
or you may get the undesired unspecified value in place of the expected version.
If using the project plugin, in order to be sure the version has been set before you use it, add a dependency from the task you read the rootProject.version
to the nyxInfer
task in the root project, like:
tasks.register('myTask') {
dependsOn ':nyxInfer'
doLast {
println rootProject.version
}
}
or
tasks.myTask.dependsOn rootProject.tasks.nyxInfer
This dependency is not needed when using the settings plugin.
You may also propagate the root project version to all sub projects if that’s what you need, and to do so you can add the following block in the root project build script:
subprojects {
version = rootProject.version
}
Core tasks
Once the plugin is applied the following tasks and dependencies are available. All tasks belong to the Release
group.
nyxClean
Runs the clean
command.
This task has no efferent dependecies but if the clean
lifecycle task is defined (like when using the Base plugin) it is attached with a dependency on this task.
nyxInfer
Runs the infer
command.
This task has no efferent dependecies while nyxMake
depends on on this task.
When the plugin is applied as a settings plugin you don’t need to run this task explicitly as it’s implicitly executed in the initialization phase.
Otherwise, when the plugin is applied as a project plugin, since this is the task that actually makes available all the information required for a new release (including the Gradle’s version
property), you should make all tasks that need that information dependent on this, directly or indirectly.
For example:
tasks.myTask.dependsOn rootProject.tasks.nyxInfer
or
tasks.register('myTask') {
dependsOn ':nyxInfer'
doLast {
...
}
}
See this post for more on the early inference of the version
and other properties.
nyxMake
Runs the make
command.
This task depends on the nyxInfer
task while nyxMark
depends on on this task. Moreover, if an assemble
lifecycle tasks is defined (like when using the Base plugin) it is attached with a dependency on this task.
nyxMark
Runs the mark
command.
This task depends on the nyxMake
task while nyxPublish
depends on on this task.
nyxPublish
Runs the publish
command.
This task depends on the nyxMark
task while the release
task is attached to depend on this task.
Lifecycle tasks
The following additional lifecycle tasks are added for convenience.
release
The release
lifecycle task is created if there is no task with the same name already defined. This task provides no actions by itself but is just meant to let you run gradle release
to run the entire release process.
The newly created or existing release
task is attached to depend on the nyxPublish
task.
Accessing the Nyx State extra project property from build scripts
Another nifty feature that may save you a bunch of coding is accessing the Nyx State from within a Gradle script.
The entire State is bound to the project extra properties with the nyxState
property name so, starting from that, you can read any property exported by Nyx.
The nyxState
property is only available after at least one core task has executed. When using the settings plugin this is not an issue as the tasks run automatically in the early phases. Not all State properties are available at the same type (after the same task execution), please check out the reference for each property to know when it’s available.
This way you can have all the Nyx properties handy without even storing the State file on disk. For example, to only run a task if the release scope contains significant changes you can check the project.nyxState.releaseScope.significantCommits
list property while to reuse the same timestamp used by Nyx you can read the project.nyxState.significant
.
Example:
task dumpSomeDiagnostics() {
dependsOn nyxInfer
doLast {
println project.nyxState.bump
println project.nyxState.directory.getAbsolutePath()
println project.nyxState.scheme.toString()
println Long.valueOf(project.nyxState.timestamp).toString()
println project.nyxState.version
}
}
In this example dumpSomeDiagnostics
represents some arbitrary task that depends on nyxInfer
just to make sure the nyxState
is available and is used to print a few attributes from the state.
Using the GitHub Action
When using GitHub Actions, the Nyx Action is the easiest and most effective way of using Nyx.
Please refer to the action page for instructions.