Project Setup Migration
It is highly recommended to read the project setup documenation first before starting the migration.
Introduction
This is a migration guide for projects that have been created in the past and do not use the project-expanders
yet. New projects should use the NS initializer.
The migration is described in two steps which can be implemented as two separate pull requests:
- Modify the structure of the repository into the project setup of the
project-expanders
. - Add the
project-expanders
to the project and configure the model.
Definitions
- bold: directories
@angular
: label indicating that this is for projects using the angular frontend.- software-project-name(kebab-case): kebab-cased version of the software project name
- Code block indication that the
softwareProjectName
should be replaced with thesoftware-project-name
:
// replace the softwareProjectName
software-project-name(kebab-case)
In the code we mention artifact groups like nsapp
or nsapp/software-project-name(kebab-case)
. Just like the softwareProjectName
this is dependent on your project and is extracted from the artifacts. Docker image names and versions are determined as
follows: <service.artifact.group>/<service.artifact.technicalName>:<service.artifact.version or project.version or latest>
This means that if no version is specified the project version is used. This has one exception. If an image is used
without a version in a isLocal (development) environment, then latest
is used.
This should become clear once the model has been defined.
Preparation
- Make sure NSScript is installed and up to date
- Make sure you are on a clean branch from develop. In the unlikely case you don’t use git. Take a backup.
Before you start, make sure that any compose file used on Jenkins does NOT contain ANY volume mounts that are
bind mounts. Mounting a
directory that does not exist will cause Docker to create it - breaking Jenkins. If you absolutely need to add bind mounts
to your Jenkins compose file, they must contain the create_host_path: false
and read_only: true
options.
Section 1: Moving files
├── angular/
├── applications/
├── components/
├── conf/
├── docker/
│ └── ...
│ └── sql/
│ └── V1.0.0__initial_provision.sql `adapt to your base!`
│ └── V2024.01.01.0900__a_previous_database_migration.sql
│ └── V2025.01.01.0900__a_database_migration.sql
├── scripts/
├── settings/
├── Jenkinsfile
├── pom.xml
├── README.md
├── CHANGELOG.md
├── renovate.json
├── .gitignore
- Create a new directory project/software-project-name(kebab-case).
- Move the following files into the project/software-project-name(kebab-case) directory:
- angular/
@angular
- application/
- components/
- conf/
- docker/ -> docker/backend-image/
The directory backend-image/ is for an artifact with the name backendImage
. If you have any other artifacts (e.g. a frontend image or a gateway image)
create directories for those too. Make sure to line up the names for the model in section 2.
- scripts/
- settings/
- Jenkinsfile
- pom.xml
- README.md
- any other softwareProject specific directories or files
Do not move the following files:
- CHANGELOG.md
- renovate.json
- .editorconfig
- .gitignore
- Since the
Jenkinsfile
has been moved into a subfolder within the project, Jenkins will not find it. Create anotherJenkinsfile
on the root level of the project with the following content:
node {
label 'project'
checkout scm
// Replace the softwareProjectName
load 'project/software-project-name(kebab-case)/Jenkinsfile'
}
Your project should now look something like this:
project/
├── software-project-name(kebab-case)/
│ └── angular/
│ └── applications/
│ └── components/
│ └── conf/
│ └── docker/
│ └── backend-image/
│ └── ...
│ └── sql/
│ └── BASE/
│ └── V1.0.0__initial_provision.sql `adapt to your base!`
│ └── MIGRATIONS/
│ └── 1.0.0/
│ └── V2024.01.01.0900__a_previous_database_migration.sql
│ └── PREV/ `to keep historic migration scripts, usually after re-basing`
│ └── .gitkeep
│ └── NEXT/
│ └── V2025.01.01.0900__a_database_migration.sql
│ └── .gitkeep
│ └── scripts/
│ └── settings/
│ └── Jenkinsfile
│ └── pom.xml
│ └── README.md
├── CHANGELOG.md
├── Jenkinsfile
├── README.md
├── renovate.json
├── .gitignore
Make sure the jenkinsfile is adjusted to compensate for the docker folders moving!
If your project used the pom.info in the Jenkinsfile, to make sure your build is successful, make sure you have a pom.xml
on the level jenkins is reading the pom info from and that it matches the information of the software project.
It is a recommended to add a back
button in the README in the software project with [back](../../README.md)
The sql
folder structure is obligatory if you want to use the project.artifact.moveSqlScriptsOnRelease
option.
You'll have to reimport the softwareProject in μRadiant.
- Make a pull request and make sure all builds are successful.
Section 2: Apply the project expanders
Step 1: Add the basic setup
Create the following directories and files in your project:
- .nsproject/
new
- model/
new
- projectSetup.xml
new
- projectSetup.xml
- expansionSettings.xml
new
- model/
- scripts/
- expand_project_setup.nss
new
- harvest_project_setup.nss
new
- expand_project_setup.nss
- project/
- software-project-name/
- docker/
- backend-image/
- in this folder move the prepare.sh -> scripts/ prepare.sh
moved
- in this folder move the prepare.sh -> scripts/ prepare.sh
- backend-image/
- docker/
- software-project-name/
- .gitignore
new
- Jenkinsfile
updated
- pom.xml
new
- README.md
new
File contents
- projectSetup.xml
- expansionSettings.xml
- expand_project_setup.nss
- harvest_project_setup.nss
- Jenkinsfile
- .gitignore
- pom.xml
- README.md
<project xmlns="https://schemas.normalizedsystems.org/xsd/project/2/1/0">
<name>projectSetup</name>
<!-- Replace the projectVersion -->
<version>projectVersion</version>
</project>
<expansionSettings>
<modelDirectory>..</modelDirectory>
<expansionDirectory>../project</expansionDirectory>
<expansions>
<expansion>
<type component="project" name="ProjectSetup"/>
<target>projectSetup</target>
</expansion>
</expansions>
<expansionResources>
<expansionResource name="net.democritus.project:jee-application-project-expanders" version="1.3.0"/>
<expansionResource name="net.democritus.project:jee-application-jenkins-ci-expanders" version="1.0.0"/>
</expansionResources>
</expansionSettings>
#!/usr/bin/env nss
@file:MinVersion("2.1.0")
@file:RootPath("SCRIPT_PATH_PARENT")
ns {
expand {
clean(false)
}
}
#!/usr/bin/env nss
@file:MinVersion("2.1.0")
@file:RootPath("SCRIPT_PATH_PARENT")
ns {
expand {
clean(true)
}
}
node {
label 'project'
checkout scm
ansiColor('xterm') {
sh 'mvn clean expanders:expand'
}
// Replace the softwareProjectName
load 'project/software-project-name(kebab-case)/Jenkinsfile'
}
# IntelliJ
.idea
*.iml
# VSCode
.vscode*
.devcontainer
# Eclipse
.project
.settings
.classpath
# Maven
target
pom.xml.versionsBackup
# NS Initializer
.credentials
# Project Setup
project/.gitignore
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- Replace the groupId -->
<groupId>groupId</groupId>
<!-- Replace the projectName -->
<artifactId>projectName-project</artifactId>
<!-- Replace the projectVersion -->
<version>projectVersion</version>
<properties>
<expanders-maven-plugin.version>2025.3.0</expanders-maven-plugin.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>net.democritus.maven.plugins</groupId>
<artifactId>expanders-maven-plugin</artifactId>
<version>${expanders-maven-plugin.version}</version>
<configuration>
<expansionSettings>.nsproject/expansionSettings.xml</expansionSettings>
</configuration>
</plugin>
</plugins>
</build>
</project>
# Project
## Scripts
- `expand_project_setup.nss` Will expand the project setup
- `harvest_project_setup.nss` Will harvest the project setup
## SoftwareProjects
// Replace the softwareProjectName
- [softwareProjectName](project/software-project-name(kebab-case)/README.md)
Step 2: Removing files
The following files can be removed (if present):
- project/
- software-project-name(kebab-case)/
- conf/
- nsmr.xml
- docker/
- backend-image/
- Dockerfile
- backend-image/
- scripts/
- *.nss
- package.json
- conf/
- software-project-name(kebab-case)/
Any .nss
script that is not generated by the project setup should be self-contained. No more file imports.
Step 3: Creating the project setup model
It is recommended to update the model using the micro radiant.
- Install the
org-normalizedsystems-northstar-project-plugin
plugin if you haven't already. - Import a new project in the micro radiant
- Select the
expansionSettings.xml
from the.nsproject
directory. (On linux, directories starting with.
are often hidden, you can use the checkbox to show hidden files if needed) - Give the project a fitting name. Typically suffixed with
-setup
or-project-setup
to differentiate it from the NS application project in micro radiant. - Open the project in micro radiant.
Artifacts
Neither the artifact name
nor the technicalName
should contain any /
! If there is a group for the docker images they should be added as the group field.
Below we will use the nsapp/software-project-name(kebab-case)
group as an example.
backendImage
- technicalName:
backend
- group:
nsapp/software-project-name(kebab-case)
- type:
jee-application-image
- technicalName:
databaseImage
- technicalName:
postgres
- version:
17.2
(use your current postgres version) - type:
custom
- technicalName:
When using Angular, you'll likely need a frontend and gateway image too.
frontendImage
- technicalName:
frontend
- group:
nsapp/software-project-name(kebab-case)
- type:
angular-frontend-image
- technicalName:
gatewayImage
- technicalName:
gateway
- group:
nsapp/software-project-name(kebab-case)
- type:
gateway-image
- technicalName:
Environments
default
- options:
project.environment.isLocal
- options:
SoftwareProjects
softwareProjectName
- type: jee-application
- artifacts:
projectSetup::backend-image
projectSetup::frontend-image
@angular
projectSetup::gateway-image
@angular
- pipelines
build-pipeline
- stages
validate
- type:
validate
- type:
expand
- type:
expand
- type:
build
- type:
build
- type:
deploy
- type:
deploy
- type:
report
- type:
report
- type:
analyze
- type:
analyze
- type:
- (possible) options:
- project.pipeline.slackChannel:
team-jenkins-slack-channel
- project.pipeline.changelogSlackChannel:
team-release-slack-channel
- project.pipeline.onlyReportChanges
- project.pipeline.noReleasePromotion
- project.pipeline.relaxBranchVersionCheck
- project.pipeline.slackChannel:
- stages
- options:
- project.softwareProject.frontend:
angular-app-name
@angular
- project.softwareProject.frontend:
Services
backend
- artifact:
project::backendImage
- environments
projectSetup::default
- type:
jee-application
- softwareProject:
projectSetup::softwareProject
- artifact:
database
- artifact:
projectSetup::databaseImage
- environments
projectSetup::default
- type:
database
- artifact:
When using Angular, you'll likely need a frontend and gateway service too.
frontend
- artifact:
projectSetup::frontendImage
- environments
projectSetup::default
- type:
angular-frontend
- softwareProject:
projectSetup::softwareProject
- artifact:
gateway
- artifact:
projectSetup::gatewayImage
- environments
projectSetup::default
- type:
gateway
- softwareProject:
projectSetup::softwareProject
- artifact:
Step 4: Expand and run
- In the micro radiant, go to
build
=>script
and run thescripts/expand_project_setup.nss
script. It is also possible to execute this script using a cli. - Configure the necessary environment variables and ports in the override compose files in the environments/overrides/ directory.
- Harvest your custom configuration using the
scripts/harvest_project_setup.nss
script. - Build your application using micro radiant or the NSScripts that have been expanded to your project setup.
- Run
start_default_services.nss
. The local docker containers should be started and you should have an environment deployed on our machine! - To stop deployment, run
stop_default_services.nss
Step 5: Opportunities for improvement
Have questions or need help? Contact the rejuvenation team. Feedback on the documentation and project-expanders are welcome too.