# Gradle Plugin for 4APPs

This gradle plugin is used to build the 4APP packages used by the 4ALLPORTAL.

# Installation

Add the plugin to the plugins-closure in your build.gradle.kts or build.gradle file:

plugins {
    id("com.cm4ap.4app") version "1.0.0-SNAPSHOT"
}

You also have to add the 4ALLPORTAL repository to your settings.gradle.kts or settings.gradle, to allow the downloading of the plugin from there:

pluginManagement {
    repositories {
        gradlePluginPortal()
        maven {
            setUrl("https://nexus.4allportal.net/repository/maven")
        }
    }
}

For local testing use the following:

pluginManagement {
    repositories {
        gradlePluginPortal()
        mavenLocal()
        setUrl("https://nexus.4allportal.net/repository/maven") // this is optional
    }
}

Gradle Wrapper: The plugin updates your local wrapper to the currently used version. Therefore, there is no need to update or change the version manually, especially since the plugin would overwrite the version.

# Configuration

Add all the required projects to the settings.gradle.kts or settings.gradle:

include("$backend")
include("$frontend")
include("$docs") // "docs" per convention

For each project, create it's build.gradle.kts or build.gradle if you need to change the defaults:

It's not needed to create gradle build files for the subprojects, but if you need to change their defaults you can;

  • Backend:

    dependencies {
       // deps
    }
    app {
        // these are the defaults
        backend {
            include = true
            junitCoverageTarget = 0
            pmdRulesMinimumPriority = nil
            dependencyJarsPath = "application/libs"
            libraryJarPath = "application/libs"
    
            // will be calculated if the corresponding src/{main,test} folders exist
            setupKotlin = nil
            setupJava = nil
        }
    }
    
  • Frontend and docs don't have configuration

Define the project version in the gradle.properties file if you don't want to use GitFlow, otherwise don't specify a version anywhere

version=1.0.0-SNAPSHOT

To print the current version execute the following:

gradle printVersion

There are some global configurations:

// import is optional
import org.gradle.api.JavaVersion

app {
    backend {
        targetJavaVersion = JavaVersion.VERSION_11
    }
}

Additionally, the projects have various configuration options;

app {
    backend {
        include = true
        junitCoverageTarget = 0
        pmdRulesMinimumPriority = nil
        dependencyJarsPath = "application/libs"
        libraryJarPath = "application/libs"

        // will be calculated, if the corresponding src/main folders exist
        setupKotlin = nil
        setupJava = nil
    }
}

# Usage

# Building a 4App

To build a 4App just execute the assemble task inside the build group. This builds your backend, potential frontend projects and packages the config files.

# Building the frontend/backend

For each $frontend project, there is a build task in the build group inside the $frontend project. This task builds the frontend project. The individual projects can be build via gradle :$frontend:build.

# Building the documentation

To build the documentation, run the task build in the build group of the docs project: gradle :$docs:build.

You can also run the dev task of vuepress with :$docs:dev.

PS: Also you might need to use the correct version of vuepress in your package.json.

To contribute to documentation take a look at our documentation guidelines (opens new window).

# Dependency management

Make sure that all already existing dependencies in the 4ALLPORTAL, i.e. in your gradle build file in the $backend, are set as compileOnly:

dependencies {
    compileOnly(enforcedPlatform("com.cm4ap:4allportal-core"))
    compileOnly(enforcedPlatform("com.cm4ap:4allportal-dam"))
    compileOnly("com.cm4ap:cmlib-core-engine-vos")
    compileOnly("com.cm4ap:cmlib-core-engine")
    compileOnly("com.cm4ap:cmlib-core-module-file")
    compileOnly("com.cm4ap:cmlib-shared")
    compileOnly("com.cm4ap:cmlib-vos")
}

All required 4APPs shall be defined in the main gradle build file (see below) and then referenced in the individual subprojects (see above);

dependencies {
    constraints {
        api("com.cm4ap:4allportal-core:3.9.0")
        api("com.cm4ap:4allportal-dam:3.9.0")
    }
}

Other required dependencies are to be added using api in the main gradle file and using implementation in the individual suprojects' file.

Note: The plugin configures gradle to include compileOnly dependencies into the testImplementation scope. Therefore, you do not need to duplicate your compileOnly dependencies.

# Task issues

  • If you've got exception with founding your classes: Check if all already existing dependencies in the 4ALLPORTAL are set to compileOnly.

  • If you're missing tasks in your project or something else isn't working right: Make sure you have the latest plugin version:

     gradle --refresh-dependencies
    

# Analysis and testing

# Code Coverage

Code Coverage is provided by the jacoco Plugin. To generate it, just run the test task. The resulting report is in the corresponding $backend/build/reports/jacoco folder.

# Code Analysis

The plugin provides code analysis using PMD, Checkstyle and ESLint. To generate all reports, run gradle check --continue.

You can find the resulting reports in the corresponding projects:

  • for backend projects in build/reports/*
  • for frontend projects in dest/eslint.html

# JUnit Tests

The plugin provides the backend projects with the JUnit dependencies. They don't need to be defined in the build.gradle files, and shouldn't be, as this would cause problems.

# Gradle Wrapper

The plugin updates your local wrapper to the currently used version, therefore there is no need to update / change the version manually, especially since the plugin overwrites the version.

# Debug locally with Docker

To be able to use debug locally, make sure you copy the 4app file to your apps and run it in your Dockerfile:

FROM registry.4allportal.net/4allportal:SNAPSHOT
COPY --chown=1000 --from=Backend build/build/4allportal-NAME.4app /4allportal/data/apps/

Define your bind ports in the configuration section of your Dockerfile. For debugging, set your remote configuration:

Host: localhost             Port: 8001

Define your bind ports in the configuration section of your Dockerfile.

8181:8181                   for your 4app's configuration
8001:8001                   for debugging

Configure the environment section in your Dockerfile like this:

environment:
  DEBUG: "true"
  DATABASE_TYPE: mariadb
  DATABASE_HOST: *DB
  DATABASE_USER: root
  DATABASE_PASSWORD: *DB_PW
  GENERAL_EXTERNAL_URL: localhost:8181
  GENERAL_ADMIN_USER_NAME: *USERNAME
  GENERAL_ADMIN_PASSWORD: *PASSWORD
  GENERAL_ADMIN_EMAIL: *NAME@4allportal.com
  GENERAL_DEFAULT_LANGUAGE: en_US
  MAIL_HOST: mail.4allportal.cloud
  MAIL_SYSTEM_FROM_EMAIL: *NAME@4allportal.com
  MAIL_SYSTEM_FROM_NAME: 4ALLPORTAL
  APPS_INSTALL:
    4allportal-essentials:SNAPSHOT,
    4allportal-dam:SNAPSHOT

# Releases

To create a release, switch to the corresponding release/ branch, create a tag and push it;

git tag 3.0.0
git push origin 3.0.0

To create a release for the current version run the following command:

git tag $(gradle printVersion --quiet); git push origin --tags

Because of a conflict with the version in master, tags are not being build right now.

You have to go to the tags pipeline and click the play button

# Migration

After each migration, adjust the 4appConfigurationVersion accordingly.

# Version 0 to 1

Define the 4appConfigurationVersion in the gradle.properties file:

4appConfigurationVersion=1
Request missing documentation