diff --git a/CHANGELOG.md b/CHANGELOG.md index 5978576ae..892c80821 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased/Snapshot] +## [2.1.0] - 2022-01-05 + ### Added - added `EvcsLocationType` support in `EvcsInput` and `EvcsInputFactory` [#406](https://github.com/ie3-institute/PowerSystemDataModel/issues/406) - Opportunity to close writer in `CsvFileSink` @@ -117,7 +119,8 @@ coordinates or multiple exactly equal coordinates possible - CsvDataSource now stops trying to get an operator for empty operator uuid field in entities - CsvDataSource now parsing multiple geoJson strings correctly -[Unreleased/Snapshot]: https://github.com/ie3-institute/powersystemdatamodel/compare/2.0.1...HEAD +[Unreleased/Snapshot]: https://github.com/ie3-institute/powersystemdatamodel/compare/2.1.0...HEAD +[2.1.0]: https://github.com/ie3-institute/powersystemdatamodel/compare/2.0.1...2.1.0 [2.0.1]: https://github.com/ie3-institute/powersystemdatamodel/compare/2.0.0...2.0.1 [2.0.0]: https://github.com/ie3-institute/powersystemdatamodel/compare/1.1.0...2.0.0 [1.1.0]: https://github.com/ie3-institute/powersystemdatamodel/compare/6a49bc514be8859ebd29a3595cd58cd000498f1e...1.1.0 diff --git a/Jenkinsfile b/Jenkinsfile index 2a241f7ab..69e19dd39 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,11 +1,21 @@ -#!groovy​ +#!groovy + +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ +//////////////////////////////// +// general config values +//////////////////////////////// + /** * configuration parameters */ /* project configuration */ -String javaVersionId = 'jdk-8' // id that matches the java tool with the java version that should be used set as jenkins property +String javaVersionId = 'jdk-17' // id that matches the java tool with the java version that should be used set as jenkins property /* git configuration */ String projectName = 'PowerSystemDataModel' // name of the repository, is case insensitive @@ -32,10 +42,10 @@ String rocketChatChannel = 'jenkins' /* setup pipeline properties */ // dev and main need manual deploy capabilities if (env.BRANCH_NAME == "main" || env.BRANCH_NAME == "dev") { - constantBranchesProps() + constantBranchesProps() } else { - // all other branches need trigger capabilities for PRs - temporaryBranchesProps() + // all other branches need trigger capabilities for PRs + temporaryBranchesProps() } /** @@ -43,191 +53,196 @@ if (env.BRANCH_NAME == "main" || env.BRANCH_NAME == "dev") { */ node { - ansiColor('xterm') { - try { - // set java version - setJavaVersion(javaVersionId) - - // determine branch name that should be checked out - net.sf.json.JSONObject prJsonObj = getPRJsonObj(orgName, projectName, env.CHANGE_ID) - String currentBranchName = prJsonObj == null ? env.BRANCH_NAME : prJsonObj.head.ref - String targetBranchName = prJsonObj == null ? null : prJsonObj.base.ref - - /* prs from forks require a special handling*/ - String headGitCheckoutUrl = prJsonObj == null ? gitCheckoutUrl : prJsonObj.head.repo.ssh_url - - // notify rocket chat - notifyRocketChat(rocketChatChannel, ':jenkins_triggered:', buildStartMsg(currentBranchName, targetBranchName, projectName)) - - // checkout scm - String commitHash = "" - stage('checkout') { - // commit hash from scm checkout - // https://www.theserverside.com/blog/Coffee-Talk-Java-News-Stories-and-Opinions/Complete-Jenkins-Git-environment-variables-list-for-batch-jobs-and-shell-script-builds - commitHash = gitCheckout(projectName, headGitCheckoutUrl, currentBranchName, sshCredentialsId).GIT_COMMIT - } - - // set build display name - String displayNameBranchName = prFromFork() ? prJsonObj.head.repo.full_name : currentBranchName - currentBuild.displayName = determineDisplayName(displayNameBranchName, commitHash, orgName, projectName) - - if (currentBranchName == "main") { - stage('handle dev pr') { - // normally main pipeline is only triggered by merge of release or hotfixes OR manually triggered - // if manually triggered for deploy, no PR should be created - if (params.deploy != "true") { - handleDevPr(sshCredentialsId, orgName, projectName, currentBranchName) - } - } - } - - // version check - stage('version check') { - // version check can only be executed, if target branch is known (derived from a PR) - if (targetBranchName == "main" || targetBranchName == "dev") { - if (checkVersion(currentBranchName, targetBranchName, projectName, projectName, gitCheckoutUrl, headGitCheckoutUrl, sshCredentialsId) != 0) - error "Version check failed! See log for version differences." - } else if (targetBranchName == null) { - // if this branch is the dev branch, we can still do version check to compare if dev and main have the same semnatic version - if (env.BRANCH_NAME == "dev") { - if (checkVersion(currentBranchName, "main", projectName, projectName, gitCheckoutUrl, headGitCheckoutUrl, sshCredentialsId) != 0) - error "Version check failed! See log for version differences." - } else { - println "No PR for branch '$currentBranchName' exists. Cannot check versioning! Please create a PR to enable version check." - } - } else { - error "Target branch name '$targetBranchName' for merging is not supported! Please select either 'dev' or 'main' as " + - "target branch for merging!" - } - } - - // test the project - stage('run tests') { - - sh 'java -version' - - gradle('--refresh-dependencies clean spotlessCheck pmdMain pmdTest spotbugsMain ' + - 'spotbugsTest test jacocoTestReport jacocoTestCoverageVerification', projectName) - - // due to an issue with openjdk-8 we use openjdk-11 for javadocs generation - sh(script: """set +x && cd $projectName""" + ''' set +x; ./gradlew clean javadoc -Dorg.gradle.java.home=/opt/java/openjdk''', returnStdout: true) - } - - // sonarqube analysis - stage('sonarqube analysis') { - String sonarqubeCurrentBranchName = prFromFork() ? prJsonObj.head.repo.full_name : currentBranchName // forks needs to be handled differently - String sonarqubeCmd = determineSonarqubeGradleCmd(sonarqubeProjectKey, sonarqubeCurrentBranchName, targetBranchName, orgName, projectName, projectName) - withSonarQubeEnv() { // will pick the global server connection from jenkins for sonarqube - gradle(sonarqubeCmd, projectName) - } - } - - // sonarqube quality gate - stage("quality gate") { - timeout(time: 1, unit: 'HOURS') { - // just in case something goes wrong, pipeline will be killed after a timeout - def qg = waitForQualityGate() // reuse taskId previously collected by withSonarQubeEnv - if (qg.status != 'OK') { - error "Pipeline aborted due to quality gate failure: ${qg.status}" - } - } - } - - // deploy stage only if branch is main or dev - if (env.BRANCH_NAME == "main" || env.BRANCH_NAME == "dev") { - stage('deploy') { - // determine project version - String projectVersion = sh(returnStdout: true, script: "set +x && cd ${projectName}; ./gradlew -q " + - "${(env.BRANCH_NAME == "dev") ? "devVersion" : "currentVersion"}").toString().trim() - - // get the sonatype credentials stored in the jenkins secure keychain - withCredentials([usernamePassword(credentialsId: mavenCentralCredentialsId, usernameVariable: 'mavencentral_username', passwordVariable: 'mavencentral_password'), - file(credentialsId: mavenCentralSignKeyFileId, variable: 'mavenCentralKeyFile'), - usernamePassword(credentialsId: mavenCentralSignKeyId, passwordVariable: 'signingPassword', usernameVariable: 'signingKeyId')]) { - - /* - * There is a known bug in JavaDoc generation in JDK 8. Therefore generate the JavaDoc with JDK - * 11 first and do the rest of the tasks with JDK 8. IMPORTANT: Do not issue 'clean' in the - * following task - */ - sh( - script: """set +x && cd $projectName""" + - ''' set +x; ./gradlew clean javadoc -Dorg.gradle.java.home=/opt/java/openjdk''', - returnStdout: true - ) - - String deployGradleTasks = "--refresh-dependencies test " + - "publish -Puser=${env.mavencentral_username} " + - "-Ppassword=${env.mavencentral_password} " + - "-Psigning.keyId=${env.signingKeyId} " + - "-Psigning.password=${env.signingPassword} " + - "-Psigning.secretKeyRingFile=${env.mavenCentralKeyFile} " + - "-PdeployVersion='$projectVersion'" - - // see https://docs.gradle.org/6.0.1/release-notes.html "Publication of SHA256 and SHA512 checksums" - def preventSHACheckSums = "-Dorg.gradle.internal.publish.checksums.insecure=true" - gradle("${deployGradleTasks} $preventSHACheckSums", projectName) - } - - if (env.BRANCH_NAME == "main") { - // create tag on main and push it to origin - createAndPushTagOnMain(projectName, sshCredentialsId) - - // todo JH create github release - - // deploy java docs - deployJavaDocs(projectName, sshCredentialsId, gitCheckoutUrl) - } - - // notify rocket chat - String successMsg = "deployment of version $projectVersion from branch '$currentBranchName' to sonatype " + - "successful. If this is a deployment from 'main' pls remember visiting https://oss.sonatype.org to " + - "stag and release artifact!\n" + - "*project:* ${projectName}\n" + - "*branch:* ${currentBranchName}\n" - - notifyRocketChat(rocketChatChannel, ':jenkins_party:', successMsg) - } - } - - // post processing - stage('post processing') { - - // publish reports - publishReports(projectName) - - // call codecov.io - withCredentials([string(credentialsId: codeCovTokenId, variable: 'codeCovToken')]) { - sh "curl -s https://codecov.io/bash | bash -s - -t ${env.codeCovToken} -C ${commitHash}" - } - - // notify Rocket.Chat - String successMsg = buildSuccessMsg(currentBranchName, targetBranchName, projectName) - notifyRocketChat(rocketChatChannel, ':jenkins_party:', successMsg) - } - - } catch (Exception e) { - // set build result to failure - currentBuild.result = 'FAILURE' - - // publish reports even on failure - publishReports(projectName) - - // print exception - Date date = new Date() - println("[ERROR] [${date.format("dd/MM/yyyy")} - ${date.format("HH:mm:ss")}] " + e) - - // notify rocket chat - net.sf.json.JSONObject prJsonObj = getPRJsonObj(orgName, projectName, env.CHANGE_ID) - String branchName = prJsonObj == null ? env.BRANCH_NAME : prJsonObj.head.ref - String errorMsg = "CI failed.\n" + - "*project:* ${projectName}\n" + - "*branch:* ${branchName}\n" + - "*error:* ${e.getMessage()}\n" - notifyRocketChat(rocketChatChannel, ':jenkins_explode:', errorMsg) + ansiColor('xterm') { + try { + // set java version + setJavaVersion(javaVersionId) + + // determine branch name that should be checked out + net.sf.json.JSONObject prJsonObj = getPRJsonObj(orgName, projectName, env.CHANGE_ID) + String currentBranchName = prJsonObj == null ? env.BRANCH_NAME : prJsonObj.head.ref + String targetBranchName = prJsonObj == null ? null : prJsonObj.base.ref + + /* prs from forks require a special handling*/ + String headGitCheckoutUrl = prJsonObj == null ? gitCheckoutUrl : prJsonObj.head.repo.ssh_url + + // notify rocket chat + notifyRocketChat(rocketChatChannel, ':jenkins_triggered:', buildStartMsg(currentBranchName, targetBranchName, projectName)) + + // checkout scm + String commitHash = "" + stage('checkout') { + // commit hash from scm checkout + // https://www.theserverside.com/blog/Coffee-Talk-Java-News-Stories-and-Opinions/Complete-Jenkins-Git-environment-variables-list-for-batch-jobs-and-shell-script-builds + commitHash = gitCheckout(projectName, headGitCheckoutUrl, currentBranchName, sshCredentialsId).GIT_COMMIT + } + + // set build display name + String displayNameBranchName = prFromFork() ? prJsonObj.head.repo.full_name : currentBranchName + currentBuild.displayName = determineDisplayName(displayNameBranchName, commitHash, orgName, projectName) + + if (currentBranchName == "main") { + stage('handle dev pr') { + // normally main pipeline is only triggered by merge of release or hotfixes OR manually triggered + // if manually triggered for deploy, no PR should be created + if (params.deploy != "true") { + handleDevPr(sshCredentialsId, orgName, projectName, currentBranchName) + } + } + } + + // version check + stage('version check') { + // version check can only be executed, if target branch is known (derived from a PR) + if (targetBranchName == "main" || targetBranchName == "dev") { + if (checkVersion(currentBranchName, targetBranchName, projectName, projectName, gitCheckoutUrl, headGitCheckoutUrl, sshCredentialsId) != 0) + error "Version check failed! See log for version differences." + } else if (targetBranchName == null) { + // if this branch is the dev branch, we can still do version check to compare if dev and main have the same semnatic version + if (env.BRANCH_NAME == "dev") { + if (checkVersion(currentBranchName, "main", projectName, projectName, gitCheckoutUrl, headGitCheckoutUrl, sshCredentialsId) != 0) + error "Version check failed! See log for version differences." + } else { + println "No PR for branch '$currentBranchName' exists. Cannot check versioning! Please create a PR to enable version check." + } + } else { + error "Target branch name '$targetBranchName' for merging is not supported! Please select either 'dev' or 'main' as " + + "target branch for merging!" + } + } + + // test the project + stage('run tests') { + + sh 'java -version' + + gradle('--refresh-dependencies clean spotlessCheck pmdMain pmdTest spotbugsMain ' + + 'spotbugsTest test jacocoTestReport jacocoTestCoverageVerification', projectName) + + // due to an issue with openjdk-8 we use openjdk-11 for javadocs generation + sh(script: """set +x && cd $projectName""" + ''' set +x; ./gradlew clean javadoc -Dorg.gradle.java.home=/opt/java/openjdk''', returnStdout: true) + } + + // sonarqube analysis + stage('sonarqube analysis') { + String sonarqubeCurrentBranchName = prFromFork() ? prJsonObj.head.repo.full_name : currentBranchName // forks needs to be handled differently + String sonarqubeCmd = determineSonarqubeGradleCmd(sonarqubeProjectKey, sonarqubeCurrentBranchName, targetBranchName, orgName, projectName, projectName) + withSonarQubeEnv() { + // will pick the global server connection from jenkins for sonarqube + gradle(sonarqubeCmd, projectName) + } + } + + // sonarqube quality gate + stage("quality gate") { + timeout(time: 1, unit: 'HOURS') { + // just in case something goes wrong, pipeline will be killed after a timeout + def qg = waitForQualityGate() // reuse taskId previously collected by withSonarQubeEnv + if (qg.status != 'OK') { + error "Pipeline aborted due to quality gate failure: ${qg.status}" + } + } + } + + // deploy stage only if branch is main or dev + if (env.BRANCH_NAME == "main" || env.BRANCH_NAME == "dev") { + stage('deploy') { + // determine project version + String projectVersion = sh(returnStdout: true, script: "set +x && cd ${projectName}; ./gradlew -q " + + "${(env.BRANCH_NAME == "dev") ? "devVersion" : "currentVersion"}").toString().trim() + + // get the sonatype credentials stored in the jenkins secure keychain + withCredentials([ + usernamePassword(credentialsId: mavenCentralCredentialsId, usernameVariable: 'mavencentral_username', passwordVariable: 'mavencentral_password'), + file(credentialsId: mavenCentralSignKeyFileId, variable: 'mavenCentralKeyFile'), + usernamePassword(credentialsId: mavenCentralSignKeyId, passwordVariable: 'signingPassword', usernameVariable: 'signingKeyId') + ]) { + + /* + * There is a known bug in JavaDoc generation in JDK 8. Therefore generate the JavaDoc with JDK + * 11 first and do the rest of the tasks with JDK 8. IMPORTANT: Do not issue 'clean' in the + * following task + */ + sh( + script: """set +x && cd $projectName""" + + ''' set +x; ./gradlew clean javadoc -Dorg.gradle.java.home=/opt/java/openjdk''', + returnStdout: true + ) + + String deployGradleTasks = "--refresh-dependencies test " + + "publish -Puser=${env.mavencentral_username} " + + "-Ppassword=${env.mavencentral_password} " + + "-Psigning.keyId=${env.signingKeyId} " + + "-Psigning.password=${env.signingPassword} " + + "-Psigning.secretKeyRingFile=${env.mavenCentralKeyFile} " + + "-PdeployVersion='$projectVersion'" + + // see https://docs.gradle.org/6.0.1/release-notes.html "Publication of SHA256 and SHA512 checksums" + def preventSHACheckSums = "-Dorg.gradle.internal.publish.checksums.insecure=true" + gradle("${deployGradleTasks} $preventSHACheckSums", projectName) + } + + if (env.BRANCH_NAME == "main") { + // create tag on main and push it to origin + createAndPushTagOnMain(projectName, sshCredentialsId) + + // todo JH create github release + + // deploy java docs + deployJavaDocs(projectName, sshCredentialsId, gitCheckoutUrl) + } + + // notify rocket chat + String successMsg = "deployment of version $projectVersion from branch '$currentBranchName' to sonatype " + + "successful. If this is a deployment from 'main' pls remember visiting https://oss.sonatype.org to " + + "stag and release artifact!\n" + + "*project:* ${projectName}\n" + + "*branch:* ${currentBranchName}\n" + + notifyRocketChat(rocketChatChannel, ':jenkins_party:', successMsg) + } + } + + // post processing + stage('post processing') { + + // publish reports + publishReports(projectName) + + // call codecov.io + withCredentials([ + string(credentialsId: codeCovTokenId, variable: 'codeCovToken') + ]) { + sh "curl -s https://codecov.io/bash | bash -s - -t ${env.codeCovToken} -C ${commitHash}" } + // notify Rocket.Chat + String successMsg = buildSuccessMsg(currentBranchName, targetBranchName, projectName) + notifyRocketChat(rocketChatChannel, ':jenkins_party:', successMsg) + } + + } catch (Exception e) { + // set build result to failure + currentBuild.result = 'FAILURE' + + // publish reports even on failure + publishReports(projectName) + + // print exception + Date date = new Date() + println("[ERROR] [${date.format("dd/MM/yyyy")} - ${date.format("HH:mm:ss")}] " + e) + + // notify rocket chat + net.sf.json.JSONObject prJsonObj = getPRJsonObj(orgName, projectName, env.CHANGE_ID) + String branchName = prJsonObj == null ? env.BRANCH_NAME : prJsonObj.head.ref + String errorMsg = "CI failed.\n" + + "*project:* ${projectName}\n" + + "*branch:* ${branchName}\n" + + "*error:* ${e.getMessage()}\n" + notifyRocketChat(rocketChatChannel, ':jenkins_explode:', errorMsg) } + + } } @@ -236,246 +251,260 @@ node { */ def setJavaVersion(String javaVersionId) { - env.JAVA_HOME = "${tool javaVersionId}" - env.PATH = "${env.JAVA_HOME}/bin:${env.PATH}" + env.JAVA_HOME = "${tool javaVersionId}" + env.PATH = "${env.JAVA_HOME}/bin:${env.PATH}" } /* git interaction */ def gitCheckout(String relativeTargetDir, String gitCheckoutUrl, String branch, String sshCredentialsId) { - checkout([ - $class : 'GitSCM', - branches : [[name: branch]], - doGenerateSubmoduleConfigurations: false, - extensions : [[$class: 'RelativeTargetDirectory', relativeTargetDir: relativeTargetDir]], - submoduleCfg : [], - userRemoteConfigs : [[credentialsId: sshCredentialsId, url: gitCheckoutUrl]] - ]) + checkout([ + $class : 'GitSCM', + branches : [[name: branch]], + doGenerateSubmoduleConfigurations: false, + extensions : [ + [$class: 'RelativeTargetDirectory', relativeTargetDir: relativeTargetDir] + ], + submoduleCfg : [], + userRemoteConfigs : [ + [credentialsId: sshCredentialsId, url: gitCheckoutUrl] + ] + ]) } def handleDevPr(String sshCredentialsId, String orgName, String projectName, String currentBranchName) { - // get the latest merge string from git to derive latest commit hash + latest merge branch name - String gitLogLatestMergeString = "" - withCredentials([sshUserPrivateKey(credentialsId: sshCredentialsId, keyFileVariable: 'sshKey')]) { - // cleanup to prepare repo - sh(script: - "set +x && cd $projectName && " + - "ssh-agent bash -c \"set +x && ssh-add $sshKey; " + - "git branch | grep -v \"$currentBranchName\" | xargs git branch -D;" + // deletes all local branches except main - "git fetch && git checkout $currentBranchName && git pull\"", returnStdout: false) - - gitLogLatestMergeString = sh(script: "cd $projectName && set +x && git log --merges -n 1", returnStdout: true) - + // get the latest merge string from git to derive latest commit hash + latest merge branch name + String gitLogLatestMergeString = "" + withCredentials([ + sshUserPrivateKey(credentialsId: sshCredentialsId, keyFileVariable: 'sshKey') + ]) { + // cleanup to prepare repo + sh(script: + "set +x && cd $projectName && " + + "ssh-agent bash -c \"set +x && ssh-add $sshKey; " + + "git branch | grep -v \"$currentBranchName\" | xargs git branch -D;" + // deletes all local branches except main + "git fetch && git checkout $currentBranchName && git pull\"", returnStdout: false) + + gitLogLatestMergeString = sh(script: "cd $projectName && set +x && git log --merges -n 1", returnStdout: true) + + } + + // only create pr if the last merge has been a hotfix or a release branch merge + boolean isHotfix = gitLogLatestMergeString.find("Merge pull request .+ from .*hotfix/\\pL{2}/#\\d+.*") ? true : false + boolean isRelease = gitLogLatestMergeString.find("Merge pull request .+ from .*rel/\\pL{2}/#\\d+.*") ? true : false + + if (isHotfix || isRelease) { + + // try to get hotfix first, if this fails try to get release + String latestMergeBranchName = "" + if (isHotfix) { + String hotfixRegex = "hotfix/\\pL{2}/#\\d+.*" + latestMergeBranchName = (gitLogLatestMergeString.find(hotfixRegex).trim() =~ hotfixRegex)[0] + } else { + String relRegex = "rel/\\pL{2}/#\\d+.*" + latestMergeBranchName = (gitLogLatestMergeString.find(relRegex).trim() =~ relRegex)[0] } - // only create pr if the last merge has been a hotfix or a release branch merge - boolean isHotfix = gitLogLatestMergeString.find("Merge pull request .+ from .*hotfix/\\pL{2}/#\\d+.*") ? true : false - boolean isRelease = gitLogLatestMergeString.find("Merge pull request .+ from .*rel/\\pL{2}/#\\d+.*") ? true : false - - if (isHotfix || isRelease) { - - // try to get hotfix first, if this fails try to get release - String latestMergeBranchName = "" - if (isHotfix) { - String hotfixRegex = "hotfix/\\pL{2}/#\\d+.*" - latestMergeBranchName = (gitLogLatestMergeString.find(hotfixRegex).trim() =~ hotfixRegex)[0] - } else { - String relRegex = "rel/\\pL{2}/#\\d+.*" - latestMergeBranchName = (gitLogLatestMergeString.find(relRegex).trim() =~ relRegex)[0] - } + // get the latest merge commit sha + String latestMergeCommitSHA = gitLogLatestMergeString.find("Merge: .* .*\n").trim().split(" ")[2] - // get the latest merge commit sha - String latestMergeCommitSHA = gitLogLatestMergeString.find("Merge: .* .*\n").trim().split(" ")[2] - - // create new branch with same name as before + hand in a pull request for dev branch, - // if the branch already exists catch the exception because then we can just go on for a PR - try { - withCredentials([sshUserPrivateKey(credentialsId: sshCredentialsId, keyFileVariable: 'sshKey')]) { - sh(script: "set +x && cd $projectName && " + - "ssh-agent bash -c \"set +x && ssh-add $sshKey; " + - "git fetch && git checkout $currentBranchName && git pull && " + - "git checkout -b $latestMergeBranchName $latestMergeCommitSHA && " + - "git push --set-upstream origin $latestMergeBranchName\"") - - } - } catch (Exception e) { - println "No need to create a new branch. Can reuse old one." - } - - // create PR on dev branch - withCredentials([string(credentialsId: 'SimServCIDeveloperAccessTokenForWebhooks', variable: 'SimServCIToken')]) { - String issueId = (latestMergeBranchName =~ ".*(#\\d+).*")[0][1] - String prMessage = "CI generated PR for branch `$latestMergeBranchName` after merging it into `main`.\\n" + - "Please review, adapt and merge it into `dev`.\\nResolves $issueId." - String curlCmd = "set +x && " + - "curl -s -X POST -u johanneshiry:$SimServCIToken -H \"Accept: application/vnd.github.v3+json\"" + - " https://api.github.com/repos/$orgName/$projectName/pulls" + - " -d '{ \"title\": \"$latestMergeBranchName for dev\", \"body\": \"$prMessage\", \"head\": \"$latestMergeBranchName\", \"base\": \"dev\"," + - "\"draft\":\"true\"}'" - sh(script: curlCmd, returnStdout: true) - } + // create new branch with same name as before + hand in a pull request for dev branch, + // if the branch already exists catch the exception because then we can just go on for a PR + try { + withCredentials([ + sshUserPrivateKey(credentialsId: sshCredentialsId, keyFileVariable: 'sshKey') + ]) { + sh(script: "set +x && cd $projectName && " + + "ssh-agent bash -c \"set +x && ssh-add $sshKey; " + + "git fetch && git checkout $currentBranchName && git pull && " + + "git checkout -b $latestMergeBranchName $latestMergeCommitSHA && " + + "git push --set-upstream origin $latestMergeBranchName\"") + + } + } catch (Exception e) { + println "No need to create a new branch. Can reuse old one." + } - // switch back to main branch for further processing - sh(script: "set +x && cd $projectName && git checkout $currentBranchName") + // create PR on dev branch + withCredentials([ + string(credentialsId: 'SimServCIDeveloperAccessTokenForWebhooks', variable: 'SimServCIToken') + ]) { + String issueId = (latestMergeBranchName =~ ".*(#\\d+).*")[0][1] + String prMessage = "CI generated PR for branch `$latestMergeBranchName` after merging it into `main`.\\n" + + "Please review, adapt and merge it into `dev`.\\nResolves $issueId." + String curlCmd = "set +x && " + + "curl -s -X POST -u johanneshiry:$SimServCIToken -H \"Accept: application/vnd.github.v3+json\"" + + " https://api.github.com/repos/$orgName/$projectName/pulls" + + " -d '{ \"title\": \"$latestMergeBranchName for dev\", \"body\": \"$prMessage\", \"head\": \"$latestMergeBranchName\", \"base\": \"dev\"," + + "\"draft\":\"true\"}'" + sh(script: curlCmd, returnStdout: true) } + + // switch back to main branch for further processing + sh(script: "set +x && cd $projectName && git checkout $currentBranchName") + } } def createAndPushTagOnMain(String projectName, String sshCredentialsId) { - String tagBranchName = 'main' - - String projectVersion = - sh(returnStdout: true, script: "set +x && cd ${projectName}; ./gradlew -q printVersion").trim() - - try { - withCredentials([sshUserPrivateKey(credentialsId: sshCredentialsId, keyFileVariable: 'sshKey')]) { - // set tagging mail and name in git config - sh(script: "set +x && cd $projectName && " + - "git config user.email 'johannes.hiry@tu-dortmund.de' && " + - "git config user.name 'Johannes Hiry'", returnStdout: false) - - // cleanup repo and tag it afterwards - sh(script: - "set +x && cd $projectName && " + - "ssh-agent bash -c \"set +x && ssh-add $sshKey; " + - "git branch | grep -v \"$tagBranchName\" | xargs git branch -D; " + // deletes all local branches except tagBranchName - "git fetch && git checkout $tagBranchName && git pull && " + - "git tag -m 'Release version $projectVersion.' $projectVersion && " + - "git push origin --tags" + - "\"", returnStdout: false) - } - } catch (Exception e) { - println "Error when creating tag on main branch! Exception: $e" + String tagBranchName = 'main' + + String projectVersion = + sh(returnStdout: true, script: "set +x && cd ${projectName}; ./gradlew -q printVersion").trim() + + try { + withCredentials([ + sshUserPrivateKey(credentialsId: sshCredentialsId, keyFileVariable: 'sshKey') + ]) { + // set tagging mail and name in git config + sh(script: "set +x && cd $projectName && " + + "git config user.email 'johannes.hiry@tu-dortmund.de' && " + + "git config user.name 'Johannes Hiry'", returnStdout: false) + + // cleanup repo and tag it afterwards + sh(script: + "set +x && cd $projectName && " + + "ssh-agent bash -c \"set +x && ssh-add $sshKey; " + + "git branch | grep -v \"$tagBranchName\" | xargs git branch -D; " + // deletes all local branches except tagBranchName + "git fetch && git checkout $tagBranchName && git pull && " + + "git tag -m 'Release version $projectVersion.' $projectVersion && " + + "git push origin --tags" + + "\"", returnStdout: false) } + } catch (Exception e) { + println "Error when creating tag on main branch! Exception: $e" + } } def deployJavaDocs(String projectName, String sshCredentialsId, String gitCheckoutUrl) { - try { - withCredentials([sshUserPrivateKey(credentialsId: sshCredentialsId, keyFileVariable: 'sshKey')]) { - // set mail and name in git config - sh(script: "set +x && cd $projectName && " + - "git config user.email 'johannes.hiry@tu-dortmund.de' && " + - "git config user.name 'Johannes Hiry'", returnStdout: false) - - // create a temporary repo in the javadocs folder and push the updated javadocs to api-docs branch - sh(script: "set +x && cd $projectName && " + - "./gradlew clean && rm -rf tmp-api-docs && mkdir tmp-api-docs && cd tmp-api-docs && " + - "ssh-agent bash -c \"set +x && ssh-add $sshKey; " + - "git init && git remote add origin $gitCheckoutUrl && " + - "git config user.email 'johannes.hiry@tu-dortmund.de' && " + - "git config user.name 'Johannes Hiry' && " + - "git fetch --depth=1 origin api-docs && " + - "git checkout api-docs && " + - "cd .. && ./gradlew clean javadoc -Dorg.gradle.java.home=/opt/java/openjdk && " + - "cp -R build/docs/javadoc/* tmp-api-docs && " + - "cd tmp-api-docs &&" + - "git add --all && git commit -m 'updated api-docs' && git push origin api-docs:api-docs" + - "\"", - returnStdout: false) - } - } catch (Exception e) { - println "Error when deploying javadocs! Exception: $e" + try { + withCredentials([ + sshUserPrivateKey(credentialsId: sshCredentialsId, keyFileVariable: 'sshKey') + ]) { + // set mail and name in git config + sh(script: "set +x && cd $projectName && " + + "git config user.email 'johannes.hiry@tu-dortmund.de' && " + + "git config user.name 'Johannes Hiry'", returnStdout: false) + + // create a temporary repo in the javadocs folder and push the updated javadocs to api-docs branch + sh(script: "set +x && cd $projectName && " + + "./gradlew clean && rm -rf tmp-api-docs && mkdir tmp-api-docs && cd tmp-api-docs && " + + "ssh-agent bash -c \"set +x && ssh-add $sshKey; " + + "git init && git remote add origin $gitCheckoutUrl && " + + "git config user.email 'johannes.hiry@tu-dortmund.de' && " + + "git config user.name 'Johannes Hiry' && " + + "git fetch --depth=1 origin api-docs && " + + "git checkout api-docs && " + + "cd .. && ./gradlew clean javadoc -Dorg.gradle.java.home=/opt/java/openjdk && " + + "cp -R build/docs/javadoc/* tmp-api-docs && " + + "cd tmp-api-docs &&" + + "git add --all && git commit -m 'updated api-docs' && git push origin api-docs:api-docs" + + "\"", + returnStdout: false) } + } catch (Exception e) { + println "Error when deploying javadocs! Exception: $e" + } } /* gradle */ def gradle(String command, String relativeProjectDir) { - env.JENKINS_NODE_COOKIE = 'dontKillMe' // this is necessary for the Gradle daemon to be kept alive + env.JENKINS_NODE_COOKIE = 'dontKillMe' // this is necessary for the Gradle daemon to be kept alive - // switch directory to be able to use gradle wrapper - sh(script: """set +x && cd $relativeProjectDir""" + ''' set +x; ./gradlew ''' + """$command""", returnStdout: true) + // switch directory to be able to use gradle wrapper + sh(script: """set +x && cd $relativeProjectDir""" + ''' set +x; ./gradlew ''' + """$command""", returnStdout: true) } def determineSonarqubeGradleCmd(String sonarqubeProjectKey, String currentBranchName, String targetBranchName, String orgName, String projectName, String relativeGitDir) { - String prBaseBranch = targetBranchName == null ? "dev" : targetBranchName - switch (currentBranchName) { - case "main": - return "sonarqube -Dsonar.branch.name=main -Dsonar.projectKey=$sonarqubeProjectKey" - break - case "dev": - String[] branchVersion = gradle("-q currentVersion", relativeGitDir).toString().split('\\.') - Integer major = branchVersion[0].toInteger() - Integer minor = branchVersion[1].toInteger() - String projectVersion = "${major}.${minor}-SNAPSHOT" - return "sonarqube -Dsonar.projectVersion=${projectVersion} -Dsonar.projectKey=$sonarqubeProjectKey" - break - default: - String gradleCommand = "sonarqube -Dsonar.projectKey=$sonarqubeProjectKey" - // if this branch has a PR, the sonarqube cmd needs to be adapted - if (env.CHANGE_ID == null) { - // no PR exists - return gradleCommand + " -Dsonar.branch.name=${currentBranchName}" - } else { - // PR exists, adapt cmd accordingly - return gradleCommand + " -Dsonar.pullrequest.branch=${currentBranchName} -Dsonar.pullrequest.key=${env.CHANGE_ID} " + - "-Dsonar.pullrequest.base=$prBaseBranch -Dsonar.pullrequest.github.repository=${orgName}/${projectName} " + - "-Dsonar.pullrequest.provider=Github" - } - break - } + String prBaseBranch = targetBranchName == null ? "dev" : targetBranchName + switch (currentBranchName) { + case "main": + return "sonarqube -Dsonar.branch.name=main -Dsonar.projectKey=$sonarqubeProjectKey" + break + case "dev": + String[] branchVersion = gradle("-q currentVersion", relativeGitDir).toString().split('\\.') + Integer major = branchVersion[0].toInteger() + Integer minor = branchVersion[1].toInteger() + String projectVersion = "${major}.${minor}-SNAPSHOT" + return "sonarqube -Dsonar.projectVersion=${projectVersion} -Dsonar.projectKey=$sonarqubeProjectKey" + break + default: + String gradleCommand = "sonarqube -Dsonar.projectKey=$sonarqubeProjectKey" + // if this branch has a PR, the sonarqube cmd needs to be adapted + if (env.CHANGE_ID == null) { + // no PR exists + return gradleCommand + " -Dsonar.branch.name=${currentBranchName}" + } else { + // PR exists, adapt cmd accordingly + return gradleCommand + " -Dsonar.pullrequest.branch=${currentBranchName} -Dsonar.pullrequest.key=${env.CHANGE_ID} " + + "-Dsonar.pullrequest.base=$prBaseBranch -Dsonar.pullrequest.github.repository=${orgName}/${projectName} " + + "-Dsonar.pullrequest.provider=Github" + } + break + } } def determineDisplayName(String currentBranchName, String commitHash, String orgName, String projectName) { - String displayName = "" - if (currentBranchName == "main" || currentBranchName == "dev") { - // main and dev are always merge branches - def jsonObject = getGithubCommitJsonObj(commitHash, orgName, projectName) - displayName = "${jsonObject.commit.message} (${currentBuild.displayName})" - } else { - displayName = currentBranchName + " (" + currentBuild.displayName + ")" - } + String displayName = "" + if (currentBranchName == "main" || currentBranchName == "dev") { + // main and dev are always merge branches + def jsonObject = getGithubCommitJsonObj(commitHash, orgName, projectName) + displayName = "${jsonObject.commit.message} (${currentBuild.displayName})" + } else { + displayName = currentBranchName + " (" + currentBuild.displayName + ")" + } - return displayName + return displayName } def publishReports(String relativeProjectDir) { - // publish test reports - publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, escapeUnderscores: false, keepAll: true, reportDir: relativeProjectDir + '/build/reports/tests/allTests', reportFiles: 'index.html', reportName: "${relativeProjectDir}_java_tests_report", reportTitles: '']) + // publish test reports + publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, escapeUnderscores: false, keepAll: true, reportDir: relativeProjectDir + '/build/reports/tests/allTests', reportFiles: 'index.html', reportName: "${relativeProjectDir}_java_tests_report", reportTitles: '']) - // publish jacoco report for main project only - publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, escapeUnderscores: false, keepAll: true, reportDir: relativeProjectDir + '/build/reports/jacoco', reportFiles: 'index.html', reportName: "${relativeProjectDir}_jacoco_report", reportTitles: '']) + // publish jacoco report for main project only + publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, escapeUnderscores: false, keepAll: true, reportDir: relativeProjectDir + '/build/reports/jacoco', reportFiles: 'index.html', reportName: "${relativeProjectDir}_jacoco_report", reportTitles: '']) - // publish pmd report for main project only - publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, escapeUnderscores: false, keepAll: true, reportDir: relativeProjectDir + '/build/reports/pmd', reportFiles: 'main.html', reportName: "${relativeProjectDir}_pmd_report", reportTitles: '']) + // publish pmd report for main project only + publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, escapeUnderscores: false, keepAll: true, reportDir: relativeProjectDir + '/build/reports/pmd', reportFiles: 'main.html', reportName: "${relativeProjectDir}_pmd_report", reportTitles: '']) - // publish spotbugs report for main project only - publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, escapeUnderscores: false, keepAll: true, reportDir: relativeProjectDir + '/build/reports/spotbugs', reportFiles: 'main.html', reportName: "${relativeProjectDir}_spotbugs_report", reportTitles: '']) + // publish spotbugs report for main project only + publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, escapeUnderscores: false, keepAll: true, reportDir: relativeProjectDir + '/build/reports/spotbugs', reportFiles: 'main.html', reportName: "${relativeProjectDir}_spotbugs_report", reportTitles: '']) } /* Rocket.Chat */ def notifyRocketChat(String rocketChatChannel, String emoji, String message) { - rocketSend channel: rocketChatChannel, emoji: emoji, - message: message - rawMessage: true + rocketSend channel: rocketChatChannel, emoji: emoji, + message: message + rawMessage: true } def buildSuccessMsg(String currentBranchName, String targetBranchName, String projectName) { - String msg = "Build successful!\n" + - "*project:* ${projectName}\n" + - "*branch:* ${currentBranchName}\n" - String targetBranch = targetBranchName != null ? "*target:* ${targetBranchName} \n" : "" + String msg = "Build successful!\n" + + "*project:* ${projectName}\n" + + "*branch:* ${currentBranchName}\n" + String targetBranch = targetBranchName != null ? "*target:* ${targetBranchName} \n" : "" - return msg + targetBranch + return msg + targetBranch } def buildStartMsg(String currentBranchName, String targetBranchName, String projectName) { - String msg = "Build triggered.\n" + - "*project:* ${projectName}\n" + - "*branch:* ${currentBranchName}\n" - String targetBranch = targetBranchName != null ? "*target:* ${targetBranchName} \n" : "" + String msg = "Build triggered.\n" + + "*project:* ${projectName}\n" + + "*branch:* ${currentBranchName}\n" + String targetBranch = targetBranchName != null ? "*target:* ${targetBranchName} \n" : "" - return msg + targetBranch + return msg + targetBranch } def prFromFork() { - return env.CHANGE_FORK != null + return env.CHANGE_FORK != null } /** @@ -485,238 +514,243 @@ def prFromFork() { /* properties */ def constantBranchesProps() { - properties([parameters( - [string(defaultValue: '', description: '', name: 'deploy', trim: true)]), - [$class: 'RebuildSettings', autoRebuild: false, rebuildDisabled: false], - [$class: 'ThrottleJobProperty', categories: [], limitOneJobWithMatchingParams: false, maxConcurrentPerNode: 0, maxConcurrentTotal: 0, paramsToUseForLimit: '', throttleEnabled: true, throttleOption: 'project'] - ]) + properties([ + parameters( + [ + string(defaultValue: '', description: '', name: 'deploy', trim: true) + ]), + [$class: 'RebuildSettings', autoRebuild: false, rebuildDisabled: false], + [$class: 'ThrottleJobProperty', categories: [], limitOneJobWithMatchingParams: false, maxConcurrentPerNode: 0, maxConcurrentTotal: 0, paramsToUseForLimit: '', throttleEnabled: true, throttleOption: 'project'] + ]) } def temporaryBranchesProps() { - properties( - [pipelineTriggers([ - issueCommentTrigger('.*!test.*')]) - ]) + properties( + [ + pipelineTriggers([ + issueCommentTrigger('.*!test.*') + ]) + ]) } /* git interaction */ def getGithubCommitJsonObj(String commit_sha, String orgName, String repoName) { - def jsonObj = readJSON text: curlByCSHA(commit_sha, orgName, repoName) - return jsonObj + def jsonObj = readJSON text: curlByCSHA(commit_sha, orgName, repoName) + return jsonObj } def curlByCSHA(String commit_sha, String orgName, String repoName) { - def curlUrl = "curl -s https://api.github.com/repos/" + orgName + "/" + repoName + "/commits/" + commit_sha - String jsonResponseString = sh(script: curlUrl, returnStdout: true) + def curlUrl = "curl -s https://api.github.com/repos/" + orgName + "/" + repoName + "/commits/" + commit_sha + String jsonResponseString = sh(script: curlUrl, returnStdout: true) - return jsonResponseString + return jsonResponseString } def getGithubPRJsonObj(String prId, String orgName, String repoName) { - def jsonObj = readJSON text: curlByPR(prId, orgName, repoName) - return jsonObj + def jsonObj = readJSON text: curlByPR(prId, orgName, repoName) + return jsonObj } def curlByPR(String prId, String orgName, String repoName) { - def curlUrl = "set +x && curl -s https://api.github.com/repos/" + orgName + "/" + repoName + "/pulls/" + prId - String jsonResponseString = sh(script: curlUrl, returnStdout: true) - return jsonResponseString + def curlUrl = "set +x && curl -s https://api.github.com/repos/" + orgName + "/" + repoName + "/pulls/" + prId + String jsonResponseString = sh(script: curlUrl, returnStdout: true) + return jsonResponseString } def getPRJsonObj(String orgName, String projectName, String changeId) { - if (changeId == null) { - return null - } else { - // PR exists, curl the api and retrieve target branch - return getGithubPRJsonObj(changeId, orgName, projectName) - } + if (changeId == null) { + return null + } else { + // PR exists, curl the api and retrieve target branch + return getGithubPRJsonObj(changeId, orgName, projectName) + } } def checkVersion(String branchName, String targetBranchName, String relativeGitDir, - String projectName, - String baseGitCheckoutUrl, - String headGitCheckoutUrl, - String sshCredentialsId) { - // get current branch type - // if headGitCheckoutUrl is set (= pr from fork), this branch type is always treated as a feature branch - String branchType = prFromFork() ? "feature" : getBranchType(branchName) - if (branchType == null) { - println "Cannot derive branch type from current branch with name '$branchName'." - return -1 - } + String projectName, + String baseGitCheckoutUrl, + String headGitCheckoutUrl, + String sshCredentialsId) { + // get current branch type + // if headGitCheckoutUrl is set (= pr from fork), this branch type is always treated as a feature branch + String branchType = prFromFork() ? "feature" : getBranchType(branchName) + if (branchType == null) { + println "Cannot derive branch type from current branch with name '$branchName'." + return -1 + } + + // compare the version + /// save the current version string + String[] currentVersion = gradle("-q currentVersion", relativeGitDir).toString().split('\\.') + + /// switch to the comparison branch, this is always the base git checkout url + gitCheckout(projectName, baseGitCheckoutUrl, targetBranchName, sshCredentialsId) + String[] targetBranchVersion = gradle("-q currentVersion", relativeGitDir).toString().split('\\.') + + if (compareVersionParts(branchType, currentVersion, getBranchType(targetBranchName), targetBranchVersion) != 0) { + // comparison failed + return -1 + } else { + // switch back to current branch. Select url depending on if this is a fork or not + gitCheckout(projectName, headGitCheckoutUrl, branchName, sshCredentialsId) + return 0 + } +} + +def compareVersionParts(String sourceBranchType, String[] sourceBranchVersion, String targetBranchType, String[] targetBranchVersion) { + + switch (sourceBranchType) { + case "hotfix": + if (targetBranchType == "main") { + boolean major = sourceBranchVersion[0].toInteger() == targetBranchVersion[0].toInteger() + boolean minor = sourceBranchVersion[1].toInteger() == targetBranchVersion[1].toInteger() + boolean patch = (sourceBranchVersion[2].toInteger() == targetBranchVersion[2].toInteger() + 1) + + if (major && minor && patch) { + return 0 + } else { + println "Hotfix branch versioning is invalid in comparison to main branch versioning. " + + "Only mainBranch.patchVersion + 1 is allowed for hotfix branch!\n" + + "hotfixVersion: ${sourceBranchVersion[0]}.${sourceBranchVersion[1]}.${sourceBranchVersion[2]}\n" + + "mainVersion: ${targetBranchVersion[0]}.${targetBranchVersion[1]}.${targetBranchVersion[2]}" + return -1 + } + + } else if (targetBranchType == "dev") { - // compare the version - /// save the current version string - String[] currentVersion = gradle("-q currentVersion", relativeGitDir).toString().split('\\.') + boolean major = sourceBranchVersion[0].toInteger() == targetBranchVersion[0].toInteger() + boolean minor = sourceBranchVersion[1].toInteger() == targetBranchVersion[1].toInteger() + boolean patch = (sourceBranchVersion[2].toInteger() == 0 && targetBranchVersion[2].toInteger() == 0) - /// switch to the comparison branch, this is always the base git checkout url - gitCheckout(projectName, baseGitCheckoutUrl, targetBranchName, sshCredentialsId) - String[] targetBranchVersion = gradle("-q currentVersion", relativeGitDir).toString().split('\\.') + if (major && minor && patch) { + return 0 + } else { + println "Hotfix branch versioning is invalid in comparison to dev branch versioning. " + + "Major and minor version must be equal and patch version must be 0.\n" + + "hotfixVersion: ${sourceBranchVersion[0]}.${sourceBranchVersion[1]}.${sourceBranchVersion[2]}\n" + + "devVersion: ${targetBranchVersion[0]}.${targetBranchVersion[1]}.${targetBranchVersion[2]}" + return -1 + } - if (compareVersionParts(branchType, currentVersion, getBranchType(targetBranchName), targetBranchVersion) != 0) { - // comparison failed + } else { + // invalid branch type for hotfix merge return -1 - } else { - // switch back to current branch. Select url depending on if this is a fork or not - gitCheckout(projectName, headGitCheckoutUrl, branchName, sshCredentialsId) - return 0 - } -} + } + break + case "feature": + if (targetBranchType == "dev") { + // no change in semVer allowed + boolean major = sourceBranchVersion[0].toInteger() == targetBranchVersion[0].toInteger() + boolean minor = sourceBranchVersion[1].toInteger() == targetBranchVersion[1].toInteger() + boolean patch = (sourceBranchVersion[2].toInteger() == 0 && targetBranchVersion[2].toInteger() == 0) + + if (major && minor && patch) { + return 0 + } else { + println "Feature branch versioning differs from dev branch versioning. This is not allowed!\n" + + "featureVersion: ${sourceBranchVersion[0]}.${sourceBranchVersion[1]}.${sourceBranchVersion[2]}\n" + + "devVersion: ${targetBranchVersion[0]}.${targetBranchVersion[1]}.${targetBranchVersion[2]}" + return -1 + } -def compareVersionParts(String sourceBranchType, String[] sourceBranchVersion, String targetBranchType, String[] targetBranchVersion) { + } else { + // invalid branch type for feature merge + println "Invalid target branch type '$targetBranchType' for feature branch. Feature branches can only" + + "be merged into dev branch!" + return -1 + } + break + case "release": + if (targetBranchType == "main" || targetBranchType == "dev") { + Integer targetMajor = targetBranchVersion[0].toInteger() + Integer targetMinor = targetBranchVersion[1].toInteger() - switch (sourceBranchType) { - case "hotfix": - if (targetBranchType == "main") { - boolean major = sourceBranchVersion[0].toInteger() == targetBranchVersion[0].toInteger() - boolean minor = sourceBranchVersion[1].toInteger() == targetBranchVersion[1].toInteger() - boolean patch = (sourceBranchVersion[2].toInteger() == targetBranchVersion[2].toInteger() + 1) - - if (major && minor && patch) { - return 0 - } else { - println "Hotfix branch versioning is invalid in comparison to main branch versioning. " + - "Only mainBranch.patchVersion + 1 is allowed for hotfix branch!\n" + - "hotfixVersion: ${sourceBranchVersion[0]}.${sourceBranchVersion[1]}.${sourceBranchVersion[2]}\n" + - "mainVersion: ${targetBranchVersion[0]}.${targetBranchVersion[1]}.${targetBranchVersion[2]}" - return -1 - } - - } else if (targetBranchType == "dev") { - - boolean major = sourceBranchVersion[0].toInteger() == targetBranchVersion[0].toInteger() - boolean minor = sourceBranchVersion[1].toInteger() == targetBranchVersion[1].toInteger() - boolean patch = (sourceBranchVersion[2].toInteger() == 0 && targetBranchVersion[2].toInteger() == 0) - - if (major && minor && patch) { - return 0 - } else { - println "Hotfix branch versioning is invalid in comparison to dev branch versioning. " + - "Major and minor version must be equal and patch version must be 0.\n" + - "hotfixVersion: ${sourceBranchVersion[0]}.${sourceBranchVersion[1]}.${sourceBranchVersion[2]}\n" + - "devVersion: ${targetBranchVersion[0]}.${targetBranchVersion[1]}.${targetBranchVersion[2]}" - return -1 - } - - } else { - // invalid branch type for hotfix merge - return -1 - } - break - case "feature": - if (targetBranchType == "dev") { - // no change in semVer allowed - boolean major = sourceBranchVersion[0].toInteger() == targetBranchVersion[0].toInteger() - boolean minor = sourceBranchVersion[1].toInteger() == targetBranchVersion[1].toInteger() - boolean patch = (sourceBranchVersion[2].toInteger() == 0 && targetBranchVersion[2].toInteger() == 0) - - if (major && minor && patch) { - return 0 - } else { - println "Feature branch versioning differs from dev branch versioning. This is not allowed!\n" + - "featureVersion: ${sourceBranchVersion[0]}.${sourceBranchVersion[1]}.${sourceBranchVersion[2]}\n" + - "devVersion: ${targetBranchVersion[0]}.${targetBranchVersion[1]}.${targetBranchVersion[2]}" - return -1 - } - - } else { - // invalid branch type for feature merge - println "Invalid target branch type '$targetBranchType' for feature branch. Feature branches can only" + - "be merged into dev branch!" - return -1 - } - break - case "release": - if (targetBranchType == "main" || targetBranchType == "dev") { - Integer targetMajor = targetBranchVersion[0].toInteger() - Integer targetMinor = targetBranchVersion[1].toInteger() - - Integer sourceMajor = sourceBranchVersion[0].toInteger() - Integer sourceMinor = sourceBranchVersion[1].toInteger() - - boolean validCheck1 = targetMajor == sourceMajor && targetMinor + 1 == sourceMinor - boolean validCheck2 = targetMajor + 1 == sourceMajor - - // patch version always needs to be 0 - boolean patchValid = sourceBranchVersion[2].toInteger() == 0 - - if ((validCheck1 || validCheck2) && patchValid) { - return 0 - } else { - println "Release branch versioning does not fit to main branch versioning!\nA release should increase " + - "either major or minor version and reset patch version to 0.\n" + - "releaseVersion: ${sourceBranchVersion[0]}.${sourceBranchVersion[1]}.${sourceBranchVersion[2]}\n" + - "${targetBranchType == "main" ? "mainVersion" : "devVersion"}: ${targetBranchVersion[0]}.${targetBranchVersion[1]}.${targetBranchVersion[2]}" - return -1 - } - } else { - // invalid target branch type for release merge - println "Merging release branch into branch type '$targetBranchType' is not supported! Realease branches" + - "can only be merged into main or dev branch!" - return -1 - } - // major == major OR major == major + 1, minor == minor OR minor == minor + 1, patch == patch == 0 - break - case "dev": - // target branch type can only be main branch - if (targetBranchType == "main") { - // only major and minor version parts need to be checked - Integer targetMajor = targetBranchVersion[0].toInteger() - Integer targetMinor = targetBranchVersion[1].toInteger() - - Integer sourceMajor = sourceBranchVersion[0].toInteger() - Integer sourceMinor = sourceBranchVersion[1].toInteger() - - boolean validCheck1 = targetMajor == sourceMajor && targetMinor + 1 == sourceMinor - boolean validCheck2 = targetMajor + 1 == sourceMajor - - // patch version always needs to be 0 - boolean patchValid = sourceBranchVersion[2].toInteger() == 0 - - if ((validCheck1 || validCheck2) && patchValid) { - return 0 - } else { - println "Dev branch versioning does not fit to main branch versioning! Must increase either major or minor version!\n" + - "devVersion: ${sourceBranchVersion[0]}.${sourceBranchVersion[1]}.${sourceBranchVersion[2]}\n" + - "mainVersion: ${targetBranchVersion[0]}.${targetBranchVersion[1]}.${targetBranchVersion[2]}" - return -1 - } - } else { - // invalid branch type for dev branch version comparison - println "Invalid branch type '$targetBranchType' to be compared with dev branch. Dev branch version " + - "can only be compared with main branch type!" - return -1 - } - break - default: - return -1 - break - } + Integer sourceMajor = sourceBranchVersion[0].toInteger() + Integer sourceMinor = sourceBranchVersion[1].toInteger() + + boolean validCheck1 = targetMajor == sourceMajor && targetMinor + 1 == sourceMinor + boolean validCheck2 = targetMajor + 1 == sourceMajor + + // patch version always needs to be 0 + boolean patchValid = sourceBranchVersion[2].toInteger() == 0 + + if ((validCheck1 || validCheck2) && patchValid) { + return 0 + } else { + println "Release branch versioning does not fit to main branch versioning!\nA release should increase " + + "either major or minor version and reset patch version to 0.\n" + + "releaseVersion: ${sourceBranchVersion[0]}.${sourceBranchVersion[1]}.${sourceBranchVersion[2]}\n" + + "${targetBranchType == "main" ? "mainVersion" : "devVersion"}: ${targetBranchVersion[0]}.${targetBranchVersion[1]}.${targetBranchVersion[2]}" + return -1 + } + } else { + // invalid target branch type for release merge + println "Merging release branch into branch type '$targetBranchType' is not supported! Realease branches" + + "can only be merged into main or dev branch!" + return -1 + } + // major == major OR major == major + 1, minor == minor OR minor == minor + 1, patch == patch == 0 + break + case "dev": + // target branch type can only be main branch + if (targetBranchType == "main") { + // only major and minor version parts need to be checked + Integer targetMajor = targetBranchVersion[0].toInteger() + Integer targetMinor = targetBranchVersion[1].toInteger() + + Integer sourceMajor = sourceBranchVersion[0].toInteger() + Integer sourceMinor = sourceBranchVersion[1].toInteger() + + boolean validCheck1 = targetMajor == sourceMajor && targetMinor + 1 == sourceMinor + boolean validCheck2 = targetMajor + 1 == sourceMajor + + // patch version always needs to be 0 + boolean patchValid = sourceBranchVersion[2].toInteger() == 0 + + if ((validCheck1 || validCheck2) && patchValid) { + return 0 + } else { + println "Dev branch versioning does not fit to main branch versioning! Must increase either major or minor version!\n" + + "devVersion: ${sourceBranchVersion[0]}.${sourceBranchVersion[1]}.${sourceBranchVersion[2]}\n" + + "mainVersion: ${targetBranchVersion[0]}.${targetBranchVersion[1]}.${targetBranchVersion[2]}" + return -1 + } + } else { + // invalid branch type for dev branch version comparison + println "Invalid branch type '$targetBranchType' to be compared with dev branch. Dev branch version " + + "can only be compared with main branch type!" + return -1 + } + break + default: + return -1 + break + } } def getBranchType(String branchName) { - def dev_pattern = "^(developer|develop|dev)\$" - def release_pattern = ".*rel/.*" - def feature_pattern = "^\\pL{2}/#\\d+.*" - def dependabot_pattern = "^dependabot/.*\$" - def hotfix_pattern = ".*hotfix/\\pL{2}/#\\d+.*" - def main_pattern = ".*main" - if (branchName =~ feature_pattern || branchName =~ dependabot_pattern) { - return "feature" - } else if (branchName =~ release_pattern) { - return "release" - } else if (branchName =~ main_pattern) { - return "main" - } else if (branchName.toLowerCase() =~ dev_pattern) { - return "dev" - } else if (branchName =~ hotfix_pattern) { - return "hotfix" - } else { - return null - } + def dev_pattern = "^(developer|develop|dev)\$" + def release_pattern = ".*rel/.*" + def feature_pattern = "^\\pL{2}/#\\d+.*" + def dependabot_pattern = "^dependabot/.*\$" + def hotfix_pattern = ".*hotfix/\\pL{2}/#\\d+.*" + def main_pattern = ".*main" + if (branchName =~ feature_pattern || branchName =~ dependabot_pattern) { + return "feature" + } else if (branchName =~ release_pattern) { + return "release" + } else if (branchName =~ main_pattern) { + return "main" + } else if (branchName.toLowerCase() =~ dev_pattern) { + return "dev" + } else if (branchName =~ hotfix_pattern) { + return "hotfix" + } else { + return null + } } \ No newline at end of file diff --git a/build.gradle b/build.gradle index 3c5e9b2a7..f0b034a13 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ plugins { ext { //version (changing these should be considered thoroughly!) - javaVersion = JavaVersion.VERSION_1_8 + javaVersion = JavaVersion.VERSION_17 tscfgVersion = '0.9.9' testcontainersVersion = '1.16.2' @@ -49,13 +49,24 @@ repositories { } dependencies { + constraints { + implementation( 'junit:junit:4.13.2+'){ + because "CVE-2020-15250 - Temporary folder vulnerability - https://github.com/advisories/GHSA-269g-pwp5-87pp" + } + } + // ie³ power system utils - implementation 'com.github.ie3-institute:PowerSystemUtils:1.5.3' + implementation 'com.github.ie3-institute:PowerSystemUtils:1.6' implementation 'tech.units:indriya:2.1.2' + implementation 'com.github.johanneshiry:OSMonaut:v1.1.1' // tmp pbf parse + // JTS Topology Suite for GeoPositions, License: EPL 1.0 / EDL 1.0 - implementation 'org.locationtech.jts:jts-core:1.18.2' + implementation ('org.locationtech.jts:jts-core:1.18.2'){ + exclude group: 'junit', module: 'junit' + } + implementation 'org.locationtech.jts.io:jts-io-common:1.18.2' // Graphs @@ -63,7 +74,7 @@ dependencies { // testing testImplementation 'org.junit.jupiter:junit-jupiter:5.8.2' - testImplementation 'org.spockframework:spock-core:2.0-groovy-3.0' + testImplementation 'org.spockframework:spock-core:2.1-M2-groovy-3.0' testImplementation 'org.objenesis:objenesis:3.2' // Mock creation with constructor parameters // testcontainers (docker framework for testing) @@ -85,10 +96,8 @@ dependencies { implementation 'commons-io:commons-io:2.11.0' // I/O functionalities implementation 'org.apache.commons:commons-compress:1.21' // I/O functionalities -} + implementation 'org.apache.commons:commons-lang3:3.12.0' -wrapper { - gradleVersion = '6.0.1' } tasks.withType(JavaCompile) { diff --git a/gradle.properties b/gradle.properties index 9ad4f3a5c..9cc4b733b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,17 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=512m + + +# Workaround to make spotless work with java 17 - +# see https://github.com/diffplug/spotless/tree/main/plugin-gradle#google-java-format and +# https://github.com/ie3-institute/PowerSystemDataModel/issues/481 for details +org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=512m \ + --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit diff --git a/gradle/scripts/jacoco.gradle b/gradle/scripts/jacoco.gradle index 2736c423a..63480a89e 100644 --- a/gradle/scripts/jacoco.gradle +++ b/gradle/scripts/jacoco.gradle @@ -3,7 +3,7 @@ // general configuration jacoco { - toolVersion = "0.8.4" + toolVersion = "0.8.7" reportsDir = file("$buildDir/reports/jacoco") } diff --git a/gradle/scripts/spotless.gradle b/gradle/scripts/spotless.gradle index ef95ae764..91a3bc3a2 100644 --- a/gradle/scripts/spotless.gradle +++ b/gradle/scripts/spotless.gradle @@ -10,19 +10,19 @@ spotless { //sets a license header, removes unused imports and formats conforming to the google java format java { removeUnusedImports() // removes any unused imports - googleJavaFormat() + googleJavaFormat('1.13.0') licenseHeader ie3LicHead } /* cf. https://github.com/diffplug/spotless/tree/master/plugin-gradle */ groovy { - licenseHeader ie3LicHead - excludeJava() // excludes all Java sources within the Groovy source dirs from formatting - + target '**.groovy', 'Jenkinsfile' + licenseHeader "#!groovy\n\n" + ie3LicHead, "////////////////////////////////" // the Groovy Eclipse formatter extends the Java Eclipse formatter, // so it formats Java files by default (unless `excludeJava` is used). greclipse() + indentWithSpaces 2 } groovyGradle { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a029b784d..7711ccd1a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ #Mon Dec 02 10:39:11 CET 2019 -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStorePath=wrapper/dists diff --git a/src/main/java/edu/ie3/datamodel/io/connectors/CsvFileConnector.java b/src/main/java/edu/ie3/datamodel/io/connectors/CsvFileConnector.java index 793a1c478..7dfe48f07 100644 --- a/src/main/java/edu/ie3/datamodel/io/connectors/CsvFileConnector.java +++ b/src/main/java/edu/ie3/datamodel/io/connectors/CsvFileConnector.java @@ -235,8 +235,7 @@ public Optional getIndividualTimeSeriesMeta */ private Map buildIndividualTimeSeriesMetaInformation() { - return getIndividualTimeSeriesFilePaths() - .parallelStream() + return getIndividualTimeSeriesFilePaths().parallelStream() .map( filePath -> { /* Extract meta information from file path and enhance it with the file path itself */ @@ -260,8 +259,7 @@ public Optional getIndividualTimeSeriesMeta */ public Map> getCsvIndividualTimeSeriesMetaInformation(ColumnScheme... columnSchemes) { - return getIndividualTimeSeriesFilePaths() - .parallelStream() + return getIndividualTimeSeriesFilePaths().parallelStream() .map( pathString -> { String filePathWithoutEnding = removeFileEnding(pathString); diff --git a/src/main/java/edu/ie3/datamodel/io/processor/timeseries/TimeSeriesProcessor.java b/src/main/java/edu/ie3/datamodel/io/processor/timeseries/TimeSeriesProcessor.java index af29f3dca..0a2bf66b3 100644 --- a/src/main/java/edu/ie3/datamodel/io/processor/timeseries/TimeSeriesProcessor.java +++ b/src/main/java/edu/ie3/datamodel/io/processor/timeseries/TimeSeriesProcessor.java @@ -106,7 +106,8 @@ private SortedMap buildFieldToSource( Class timeSeriesClass, Class entryClass, Class valueClass) { /* Get the mapping from field name to getter method ignoring the getter for returning all entries */ Map timeSeriesMapping = - mapFieldNameToGetter(timeSeriesClass, Arrays.asList("entries", "uuid", "type")).entrySet() + mapFieldNameToGetter(timeSeriesClass, Arrays.asList("entries", "uuid", "type")) + .entrySet() .stream() .collect( Collectors.toMap( @@ -136,7 +137,8 @@ private SortedMap buildFieldToSource( mapFieldNameToGetter( valueClass, Arrays.asList("solarIrradiance", "temperature", "wind")) - .entrySet().stream() + .entrySet() + .stream() .map( entry -> new AbstractMap.SimpleEntry<>( diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvDataSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvDataSource.java index 9f02b4b79..6a3869c44 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvDataSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvDataSource.java @@ -393,10 +393,7 @@ protected Stream> buildStreamWithFieldsToAttributesMap( Collection> allRows = csvRowFieldValueMapping(reader, headline); return distinctRowsWithLog( - allRows, - fieldToValues -> fieldToValues.get("uuid"), - entityClass.getSimpleName(), - "UUID") + allRows, fieldToValues -> fieldToValues.get("uuid"), entityClass.getSimpleName(), "UUID") .parallelStream(); } catch (IOException e) { log.warn( @@ -455,8 +452,7 @@ protected Set> distinctRowsWithLog( /* Check for rows with the same key based on the provided key extractor function */ Set> distinctIdSet = - allRowsSet - .parallelStream() + allRowsSet.parallelStream() .filter(ValidationUtils.distinctByKey(keyExtractor)) .collect(Collectors.toSet()); if (distinctIdSet.size() != allRowsSet.size()) { diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvIdCoordinateSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvIdCoordinateSource.java index 6a9abf4cc..822dae3bb 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvIdCoordinateSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvIdCoordinateSource.java @@ -123,7 +123,7 @@ protected Stream> buildStreamWithFieldsToAttributesMap() { .get(factory.getLatField()) .concat(fieldToValues.get(factory.getLonField())); return distinctRowsWithLog( - withDistinctCoordinateId, coordinateExtractor, "coordinate id mapping", "coordinate") + withDistinctCoordinateId, coordinateExtractor, "coordinate id mapping", "coordinate") .parallelStream(); } catch (IOException e) { log.error("Cannot read the file for coordinate id to coordinate mapping.", e); diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvWeatherSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvWeatherSource.java index 69d322f6c..6a3e2bdda 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvWeatherSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvWeatherSource.java @@ -253,7 +253,7 @@ protected Stream> buildStreamWithFieldsToAttributesMap( .get(weatherFactory.getTimeFieldString()) .concat(fieldToValues.get(weatherFactory.getCoordinateIdFieldString())); return distinctRowsWithLog( - allRows, timeCoordinateIdExtractor, entityClass.getSimpleName(), "UUID") + allRows, timeCoordinateIdExtractor, entityClass.getSimpleName(), "UUID") .parallelStream(); } catch (IOException e) { diff --git a/src/main/java/edu/ie3/datamodel/models/input/container/GraphicElements.java b/src/main/java/edu/ie3/datamodel/models/input/container/GraphicElements.java index af0d4d9fd..60434f9a8 100644 --- a/src/main/java/edu/ie3/datamodel/models/input/container/GraphicElements.java +++ b/src/main/java/edu/ie3/datamodel/models/input/container/GraphicElements.java @@ -48,14 +48,12 @@ public GraphicElements(List graphics) { /* init sets */ this.nodeGraphics = - graphics - .parallelStream() + graphics.parallelStream() .filter(graphic -> graphic instanceof NodeGraphicInput) .map(graphic -> (NodeGraphicInput) graphic) .collect(Collectors.toSet()); this.lineGraphics = - graphics - .parallelStream() + graphics.parallelStream() .filter(graphic -> graphic instanceof LineGraphicInput) .map(graphic -> (LineGraphicInput) graphic) .collect(Collectors.toSet()); diff --git a/src/main/java/edu/ie3/datamodel/models/input/container/RawGridElements.java b/src/main/java/edu/ie3/datamodel/models/input/container/RawGridElements.java index 4f0abc3e9..b8806a63d 100644 --- a/src/main/java/edu/ie3/datamodel/models/input/container/RawGridElements.java +++ b/src/main/java/edu/ie3/datamodel/models/input/container/RawGridElements.java @@ -84,38 +84,32 @@ public RawGridElements(List rawGridElements) { /* init sets */ this.nodes = - rawGridElements - .parallelStream() + rawGridElements.parallelStream() .filter(gridElement -> gridElement instanceof NodeInput) .map(nodeInput -> (NodeInput) nodeInput) .collect(Collectors.toSet()); this.lines = - rawGridElements - .parallelStream() + rawGridElements.parallelStream() .filter(gridElement -> gridElement instanceof LineInput) .map(lineInput -> (LineInput) lineInput) .collect(Collectors.toSet()); this.transformer2Ws = - rawGridElements - .parallelStream() + rawGridElements.parallelStream() .filter(gridElement -> gridElement instanceof Transformer2WInput) .map(trafo2wInput -> (Transformer2WInput) trafo2wInput) .collect(Collectors.toSet()); this.transformer3Ws = - rawGridElements - .parallelStream() + rawGridElements.parallelStream() .filter(gridElement -> gridElement instanceof Transformer3WInput) .map(trafo3wInput -> (Transformer3WInput) trafo3wInput) .collect(Collectors.toSet()); this.switches = - rawGridElements - .parallelStream() + rawGridElements.parallelStream() .filter(gridElement -> gridElement instanceof SwitchInput) .map(switchInput -> (SwitchInput) switchInput) .collect(Collectors.toSet()); this.measurementUnits = - rawGridElements - .parallelStream() + rawGridElements.parallelStream() .filter(gridElement -> gridElement instanceof MeasurementUnitInput) .map(measurementUnitInput -> (MeasurementUnitInput) measurementUnitInput) .collect(Collectors.toSet()); diff --git a/src/main/java/edu/ie3/datamodel/models/input/container/SystemParticipants.java b/src/main/java/edu/ie3/datamodel/models/input/container/SystemParticipants.java index 8a47b4995..28550d86a 100644 --- a/src/main/java/edu/ie3/datamodel/models/input/container/SystemParticipants.java +++ b/src/main/java/edu/ie3/datamodel/models/input/container/SystemParticipants.java @@ -106,62 +106,52 @@ public SystemParticipants(List systemParticipants) { /* init sets */ this.bmPlants = - systemParticipants - .parallelStream() + systemParticipants.parallelStream() .filter(gridElement -> gridElement instanceof BmInput) .map(bmInput -> (BmInput) bmInput) .collect(Collectors.toSet()); this.chpPlants = - systemParticipants - .parallelStream() + systemParticipants.parallelStream() .filter(gridElement -> gridElement instanceof ChpInput) .map(chpInput -> (ChpInput) chpInput) .collect(Collectors.toSet()); this.evCS = - systemParticipants - .parallelStream() + systemParticipants.parallelStream() .filter(gridElement -> gridElement instanceof EvcsInput) .map(evcsInput -> (EvcsInput) evcsInput) .collect(Collectors.toSet()); this.evs = - systemParticipants - .parallelStream() + systemParticipants.parallelStream() .filter(gridElement -> gridElement instanceof EvInput) .map(evInput -> (EvInput) evInput) .collect(Collectors.toSet()); this.fixedFeedIns = - systemParticipants - .parallelStream() + systemParticipants.parallelStream() .filter(gridElement -> gridElement instanceof FixedFeedInInput) .map(fixedFeedInInpu -> (FixedFeedInInput) fixedFeedInInpu) .collect(Collectors.toSet()); this.heatPumps = - systemParticipants - .parallelStream() + systemParticipants.parallelStream() .filter(gridElement -> gridElement instanceof HpInput) .map(hpInput -> (HpInput) hpInput) .collect(Collectors.toSet()); this.loads = - systemParticipants - .parallelStream() + systemParticipants.parallelStream() .filter(gridElement -> gridElement instanceof LoadInput) .map(loadInput -> (LoadInput) loadInput) .collect(Collectors.toSet()); this.pvPlants = - systemParticipants - .parallelStream() + systemParticipants.parallelStream() .filter(gridElement -> gridElement instanceof PvInput) .map(pvInput -> (PvInput) pvInput) .collect(Collectors.toSet()); this.storages = - systemParticipants - .parallelStream() + systemParticipants.parallelStream() .filter(gridElement -> gridElement instanceof StorageInput) .map(storageInput -> (StorageInput) storageInput) .collect(Collectors.toSet()); this.wecPlants = - systemParticipants - .parallelStream() + systemParticipants.parallelStream() .filter(gridElement -> gridElement instanceof WecInput) .map(wecInput -> (WecInput) wecInput) .collect(Collectors.toSet()); diff --git a/src/main/java/edu/ie3/datamodel/models/input/system/type/chargingpoint/ChargingPointTypeUtils.java b/src/main/java/edu/ie3/datamodel/models/input/system/type/chargingpoint/ChargingPointTypeUtils.java index 6825a3c0f..e72de1aba 100644 --- a/src/main/java/edu/ie3/datamodel/models/input/system/type/chargingpoint/ChargingPointTypeUtils.java +++ b/src/main/java/edu/ie3/datamodel/models/input/system/type/chargingpoint/ChargingPointTypeUtils.java @@ -142,7 +142,8 @@ private ChargingPointTypeUtils() { Stream.concat( Stream.of(type.getId().toLowerCase()), type.getSynonymousIds().stream().map(String::toLowerCase)) - .collect(Collectors.toMap(Function.identity(), v -> type)).entrySet() + .collect(Collectors.toMap(Function.identity(), v -> type)) + .entrySet() .stream()) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); diff --git a/src/main/java/edu/ie3/datamodel/utils/ContainerNodeUpdateUtil.java b/src/main/java/edu/ie3/datamodel/utils/ContainerNodeUpdateUtil.java index 5286f78af..f641adccf 100644 --- a/src/main/java/edu/ie3/datamodel/utils/ContainerNodeUpdateUtil.java +++ b/src/main/java/edu/ie3/datamodel/utils/ContainerNodeUpdateUtil.java @@ -207,9 +207,7 @@ private static SystemParticipants updateSystemParticipantsWithNodes( SystemParticipants systemParticipants, Map oldToNewNodes) { List sysParts = - systemParticipants - .allEntitiesAsList() - .parallelStream() + systemParticipants.allEntitiesAsList().parallelStream() .map( sysPart -> { if (oldToNewNodes.containsKey(sysPart.getNode())) { diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTestDataMeta.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTestDataMeta.groovy index d00551d13..b51356c0a 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTestDataMeta.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTestDataMeta.groovy @@ -12,8 +12,8 @@ import edu.ie3.datamodel.io.naming.FileNamingStrategy */ trait CsvTestDataMeta { - static String testParticipantsBaseFolderPath = new File(getClass().getResource('/testGridFiles').toURI()).absolutePath - static String testTimeSeriesBaseFolderPath = new File(getClass().getResource('/testTimeSeriesFiles').toURI()).absolutePath + static String testParticipantsBaseFolderPath = new File(CsvTestDataMeta.getResource('/testGridFiles').toURI()).absolutePath + static String testTimeSeriesBaseFolderPath = new File(CsvTestDataMeta.getResource('/testTimeSeriesFiles').toURI()).absolutePath static String graphicsFolderPath = testParticipantsBaseFolderPath.concat(File.separator).concat("graphics") static String typeFolderPath = testParticipantsBaseFolderPath.concat(File.separator).concat("types") static String gridFolderPath = testParticipantsBaseFolderPath.concat(File.separator).concat("grid") diff --git a/version.properties b/version.properties index 7bd19cc05..dcf9d3086 100644 --- a/version.properties +++ b/version.properties @@ -1,8 +1,8 @@ #Generated by the Semver Plugin for Gradle -#Fri May 21 09:47:39 CEST 2021 +#Wed Jan 05 11:45:20 CET 2022 version.buildmeta= -version.major=2 -version.minor=1 +version.major=3 +version.minor=0 version.patch=0 version.prerelease= -version.semver=2.1.0 +version.semver=3.0.0