Skip to content

Commit

Permalink
Merge pull request #97 from ballerina-platform/add-docker-builds
Browse files Browse the repository at this point in the history
  • Loading branch information
ThisaruGuruge authored Sep 11, 2023
2 parents ebea780 + 5bdd438 commit 40337b7
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 54 deletions.
58 changes: 51 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,57 @@

## Introduction

The Ballerina Gradle plugin is designed to work
similar to the Java Gradle plugin. This adds ballerina project bundling functionalities along with testing.
The Ballerina Gradle plugin is used to build Ballerina modules using Gradle. This plugin is used in the Ballerina platform to build the Ballerina Libraries. This plugin is needed when there is a Gradle project with a Ballerina submodule. The Ballerina submodule can be built using this plugin.

>**Note:** This plugin is not recommended for building standalone Ballerina packages. It is recommended to use the Ballerina CLI directly in such scenarios.
## Prerequisites

* This plugin is published in the Ballerina platform GitHub packages repository. Therefore, the Ballerina platform GitHub packages repository should be added to the Gradle plugin management repositories. To access the Ballerina platform GitHub packages repository, a GitHub personal access token (PAT) should be provided. The PAT should be provided as an environment variable named `packagePAT`. The username of the GitHub account should be provided as an environment variable named `packageUser`.

## Usage

```groovy
plugins {
id 'io.ballerina.plugin' version '0.0.1'
}
```
* Add the Ballerina Gradle plugin version in the `gradle.properties` file in your project.

```properties
ballerinaGradlePluginVersion=1.0.0
```

* In your `settings.gradle` file, add the Ballerina Gradle Plugin under plugin management. Add the Ballerina platform GitHub packages repository under the repositories.

```groovy
pluginManagement {
plugins {
id "io.ballerina.plugin" version "${ballerinaGradlePluginVersion}"
}
repositories {
gradlePluginPortal() // To resolve the plugins from the Gradle plugin portal.
maven { // To resolve the Ballerina plugin from the Ballerina platform GitHub packages repository.
url = 'https://maven.pkg.github.com/ballerina-platform/*'
credentials {
username System.getenv("packageUser")
password System.getenv("packagePAT")
}
}
}
}
```

* In your `build.gradle` file inside the `ballerina` submodule, apply the Ballerina Gradle plugin.

```groovy
plugins {
id "io.ballerina.plugin"
}
```

* Provide the required inputs for the Ballerina plugin in the above `build.gradle` file.

```groovey
ballerina {
packageOrganization = "ballerina"
module = "io"
testCoverageParam = "--code-coverage --coverage-format=xml"
}
```
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
group=io.ballerina
version=2.0.2-SNAPSHOT
version=2.1.0-SNAPSHOT
119 changes: 73 additions & 46 deletions src/main/groovy/io/ballerina/plugin/BallerinaPlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class BallerinaExtension {

String module
String langVersion
String buildOnDockerImage
String testCoverageParam
String packageOrganization
String customTomlVersion
Expand All @@ -40,7 +41,7 @@ class BallerinaPlugin implements Plugin<Project> {

@Override
void apply(Project project) {
project.extensions.create('ballerina', BallerinaExtension)
def ballerinaExtension = project.extensions.create('ballerina', BallerinaExtension)

def packageOrg = ''
def platform = 'java17'
Expand All @@ -60,11 +61,8 @@ class BallerinaPlugin implements Plugin<Project> {
def needPublishToLocalCentral = false
def skipTests = true
def graalvmFlag = ''
def checkForBreakingChanges = project.hasProperty('buildUsingDocker')
def ballerinaDockerTag = project.findProperty('buildUsingDocker')
if (ballerinaDockerTag == '') {
ballerinaDockerTag = 'nightly'
}
def buildOnDocker = false
def ballerinaDockerTag = ''

if (project.version.matches(project.ext.timestampedVersionRegex)) {
def splitVersion = project.version.split('-')
Expand All @@ -78,6 +76,27 @@ class BallerinaPlugin implements Plugin<Project> {
tomlVersion = project.version.replace("${project.ext.snapshotVersion}", '')
}

project.afterEvaluate {
if (ballerinaExtension.buildOnDockerImage != null) {
buildOnDocker = true
ballerinaDockerTag = ballerinaExtension.buildOnDockerImage
}

if (project.hasProperty('buildUsingDocker')) {
buildOnDocker = true
ballerinaDockerTag = project.findProperty('buildUsingDocker')
}

if (ballerinaDockerTag == '') {
ballerinaDockerTag = 'nightly'
}

if (buildOnDocker) {
println("[Info] project builds on docker: $buildOnDocker")
println("[Info] using the Ballerina docker image tag: $ballerinaDockerTag")
}
}

project.configurations {
jbalTools
}
Expand All @@ -90,15 +109,15 @@ class BallerinaPlugin implements Plugin<Project> {
}

project.dependencies {
if (checkForBreakingChanges) {
println("WARNING! jbalTools dependency skiped; project uses docker to build the module")
if (buildOnDocker) {
println("[Warning] skipping downloading jBallerinaTools dependency: project uses docker to build the module")
} else {
if (project.extensions.ballerina.langVersion == null) {
if (ballerinaExtension.langVersion == null) {
jbalTools("org.ballerinalang:jballerina-tools:${project.ballerinaLangVersion}") {
transitive = false
}
} else {
jbalTools("org.ballerinalang:jballerina-tools:${project.extensions.ballerina.langVersion}") {
jbalTools("org.ballerinalang:jballerina-tools:${ballerinaExtension.langVersion}") {
transitive = false
}
}
Expand All @@ -112,8 +131,8 @@ class BallerinaPlugin implements Plugin<Project> {
}
}

if (checkForBreakingChanges) {
println("WARNING! task unpackJballerinaTools skiped; project uses docker to build the module")
if (buildOnDocker) {
println("[Warning] skipping task 'unpackJballerinaTools': project uses docker to build the module")
} else {
doLast {
project.configurations.jbalTools.resolvedConfiguration.resolvedArtifacts.each { artifact ->
Expand All @@ -138,8 +157,8 @@ class BallerinaPlugin implements Plugin<Project> {

project.tasks.register('unpackStdLibs') {
dependsOn(project.unpackJballerinaTools)
if (checkForBreakingChanges) {
println("WARNING! task unpackStdLibs skiped; project uses docker to build the module")
if (buildOnDocker) {
println("[Warning] skipping task 'unpackStdLibs': project uses docker to build the module")
} else {
doLast {
project.configurations.ballerinaStdLibs.resolvedConfiguration.resolvedArtifacts.each { artifact ->
Expand All @@ -154,8 +173,8 @@ class BallerinaPlugin implements Plugin<Project> {

project.tasks.register('copyStdlibs') {
dependsOn(project.unpackStdLibs)
if (checkForBreakingChanges) {
println("WARNING! task copyStdlibs skiped; project uses docker to build the module")
if (buildOnDocker) {
println("[Warning] skipping task 'copyStdlibs': project uses docker to build the module")
} else {
doLast {
/* Standard Libraries */
Expand Down Expand Up @@ -187,12 +206,12 @@ class BallerinaPlugin implements Plugin<Project> {
}

project.tasks.register('initializeVariables') {
String packageName = project.extensions.ballerina.module
String organisation
if (project.extensions.ballerina.packageOrganization == null) {
organisation = 'ballerina'
String packageName = ballerinaExtension.module
String organization
if (ballerinaExtension.packageOrganization == null) {
organization = 'ballerina'
} else {
organisation = project.extensions.ballerina.packageOrganization
organization = ballerinaExtension.packageOrganization
}
if (project.hasProperty('groups')) {
groupParams = "--groups ${project.findProperty('groups')}"
Expand All @@ -213,26 +232,26 @@ class BallerinaPlugin implements Plugin<Project> {
needPublishToCentral = true
}
if (project.hasProperty('balGraalVMTest')) {
println("WARNING! testing with code-coverage is disabled for ballerina graalvm test")
println("[Warning] disabled code coverage: running GraalVM tests")
graalvmFlag = '--graalvm'
}

project.gradle.taskGraph.whenReady { graph ->
if (!(project.hasProperty('disable') || project.hasProperty('groups')) &&
(graph.hasTask(":${packageName}-ballerina:build") ||
graph.hasTask(":${packageName}-ballerina:publish") ||
graph.hasTask(":${packageName}-ballerina:publishToMavenLocal"))) {
graph.hasTask(":${packageName}-ballerina:publish") ||
graph.hasTask(":${packageName}-ballerina:publishToMavenLocal"))) {
needSeparateTest = false
needBuildWithTest = true
} else {
needSeparateTest = true
}
if (graph.hasTask(":${packageName}-ballerina:test")) {
if (!project.hasProperty('balGraalVMTest')) {
if (project.extensions.ballerina.testCoverageParam == null) {
testCoverageParams = "--code-coverage --coverage-format=xml --includes=io.ballerina.stdlib.${packageName}.*:${organisation}.${packageName}.*"
if (ballerinaExtension.testCoverageParam == null) {
testCoverageParams = "--code-coverage --coverage-format=xml --includes=io.ballerina.stdlib.${packageName}.*:${organization}.${packageName}.*"
} else {
testCoverageParams = project.extensions.ballerina.testCoverageParam
testCoverageParams = ballerinaExtension.testCoverageParam
}
}
skipTests = false;
Expand All @@ -249,30 +268,34 @@ class BallerinaPlugin implements Plugin<Project> {

inputs.dir projectDirectory
doLast {
String distributionBinPath = project.projectDir.absolutePath + "/build/jballerina-tools-${project.extensions.ballerina.langVersion}/bin"
String packageName = project.extensions.ballerina.module
String distributionBinPath = project.projectDir.absolutePath + "/build/jballerina-tools-${ballerinaExtension.langVersion}/bin"
String packageName = ballerinaExtension.module
String balaVersion
if (project.extensions.ballerina.customTomlVersion == null) {
if (ballerinaExtension.customTomlVersion == null) {
balaVersion = tomlVersion
} else {
balaVersion = project.extensions.ballerina.customTomlVersion
balaVersion = ballerinaExtension.customTomlVersion
}

if (project.extensions.ballerina.platform != null) {
platform = project.extensions.ballerina.platform
if (ballerinaExtension.platform != null) {
platform = ballerinaExtension.platform
}

if (project.extensions.ballerina.packageOrganization == null) {
if (ballerinaExtension.packageOrganization == null) {
packageOrg = 'ballerina'
} else {
packageOrg = project.extensions.ballerina.packageOrganization
packageOrg = ballerinaExtension.packageOrganization
}
if (needBuildWithTest) {
// Pack bala first
project.exec {
workingDir project.projectDir
environment 'JAVA_OPTS', '-DBALLERINA_DEV_COMPILE_BALLERINA_ORG=true'
if (checkForBreakingChanges) {
if (buildOnDocker) {
String dockerTag = ballerinaExtension.buildOnDockerImage
if (dockerTag != null && dockerTag != '') {
ballerinaDockerTag = dockerTag
}
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine 'cmd', '/c', "docker run --rm --net=host --user \$(id -u):\$(id -g) -v $project.projectDir/..:/home -v $project.projectDir:/home/ballerina ballerina/ballerina:$ballerinaDockerTag $balJavaDebugParam bal pack --target-dir ${balBuildTarget} ${debugParams}"
} else {
Expand All @@ -289,7 +312,11 @@ class BallerinaPlugin implements Plugin<Project> {
project.exec {
workingDir project.projectDir
environment 'JAVA_OPTS', '-DBALLERINA_DEV_COMPILE_BALLERINA_ORG=true'
if (checkForBreakingChanges) {
if (buildOnDocker) {
String dockerTag = ballerinaExtension.buildOnDockerImage
if (dockerTag != null && dockerTag != '') {
ballerinaDockerTag = dockerTag
}
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine 'cmd', '/c', "docker run --rm --net=host --user \$(id -u):\$(id -g) -v $project.projectDir/..:/home -v $project.projectDir:/home/ballerina ballerina/ballerina:$ballerinaDockerTag $balJavaDebugParam bal test ${graalvmFlag} ${testCoverageParams} ${groupParams} ${disableGroups} ${debugParams}"
} else {
Expand Down Expand Up @@ -317,7 +344,7 @@ class BallerinaPlugin implements Plugin<Project> {
if (needPublishToCentral) {
if (project.version.endsWith('-SNAPSHOT') ||
project.version.matches(project.ext.timestampedVersionRegex)) {
println('The project version is SNAPSHOT or Timestamped SNAPSHOT, not publishing to central.')
println("[Info] skipping publishing to central: project version is SNAPSHOT or Timestamped SNAPSHOT")
return
}
if (ballerinaCentralAccessToken != null) {
Expand All @@ -334,7 +361,7 @@ class BallerinaPlugin implements Plugin<Project> {
throw new InvalidUserDataException('Central Access Token is not present')
}
} else if (needPublishToLocalCentral) {
println('Publishing to the ballerina local central repository..')
println("[Info] Publishing to the ballerina local central repository")
project.exec {
workingDir project.projectDir
environment 'JAVA_OPTS', '-DBALLERINA_DEV_COMPILE_BALLERINA_ORG=true'
Expand Down Expand Up @@ -362,16 +389,16 @@ class BallerinaPlugin implements Plugin<Project> {
finalizedBy(project.commitTomlFiles)
doLast {
if (needSeparateTest) {
String distributionBinPath = project.projectDir.absolutePath + "/build/jballerina-tools-${project.extensions.ballerina.langVersion}/bin"
String distributionBinPath = project.projectDir.absolutePath + "/build/jballerina-tools-${ballerinaExtension.langVersion}/bin"
project.exec {
workingDir project.projectDir
environment 'JAVA_OPTS', '-DBALLERINA_DEV_COMPILE_BALLERINA_ORG=true'
if (checkForBreakingChanges) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine 'cmd', '/c', "docker run --rm --net=host --user \$(id -u):\$(id -g) -v ${project.projectDir}/..:/home -v $project.projectDir:/home/ballerina ballerina/ballerina:$ballerinaDockerTag bal test ${graalvmFlag} ${testCoverageParams} ${groupParams} ${disableGroups} ${debugParams}"
} else {
commandLine 'sh', '-c', "docker run --rm --net=host --user \$(id -u):\$(id -g) -v ${project.projectDir}/..:/home -v $project.projectDir:/home/ballerina ballerina/ballerina:$ballerinaDockerTag bal test ${graalvmFlag} ${testCoverageParams} ${groupParams} ${disableGroups} ${debugParams}"
}
if (buildOnDocker) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine 'cmd', '/c', "docker run --rm --net=host --user \$(id -u):\$(id -g) -v ${project.projectDir}/..:/home -v $project.projectDir:/home/ballerina ballerina/ballerina:$ballerinaDockerTag bal test ${graalvmFlag} ${testCoverageParams} ${groupParams} ${disableGroups} ${debugParams}"
} else {
commandLine 'sh', '-c', "docker run --rm --net=host --user \$(id -u):\$(id -g) -v ${project.projectDir}/..:/home -v $project.projectDir:/home/ballerina ballerina/ballerina:$ballerinaDockerTag bal test ${graalvmFlag} ${testCoverageParams} ${groupParams} ${disableGroups} ${debugParams}"
}
} else if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine 'cmd', '/c', "${balJavaDebugParam} ${distributionBinPath}/bal.bat test --offline ${graalvmFlag} ${testCoverageParams} ${groupParams} ${disableGroups} ${debugParams} && exit %%ERRORLEVEL%%"
} else {
Expand Down

0 comments on commit 40337b7

Please sign in to comment.