diff --git a/angular/package.json b/angular/package.json index db02f4e48..6f79d4dc6 100644 --- a/angular/package.json +++ b/angular/package.json @@ -12,7 +12,7 @@ "start:electron": "npm run postinstall:electron && npm-run-all -p serve electron:serve", "compodoc": "compodoc -p src/tsconfig.app.json -s", "test": "ng test --browsers Chrome", - "test:ci": "ng test --browsers ChromeHeadless --watch=false", + "test:ci": "npm run postinstall:web && ng test --browsers ChromeHeadless --watch=false", "test:firefox": "ng test --browsers Firefox", "test:ci:firefox": "ng test --browsers FirefoxHeadless --watch=false", "test:firefox-dev": "ng test --browsers FirefoxDeveloper", @@ -32,7 +32,7 @@ "build": "ng build", "build:pwa": "npm run postinstall:web && ng build --configuration=pwa --prod --build-optimizer && npm run ngsw-config && npm run ngsw-copy", "build:prod": "npm run postinstall:web && ng build --prod --build-optimizer", - "build:prodcompose": "npm run postinstall:web && ng build --configuration=prodcompose --prod --build-optimizer", + "build:prodcompose": "npm run postinstall:web && ng build --configuration=prodcompose ", "build:electron": "npm run postinstall:electron && npm run electron:serve-tsc && ng build --base-href ./", "build:electron:dev": "npm run build:electron -- -c dev", "build:electron:prod": "npm run build:electron -- -c production", diff --git a/java/mtsj/pom.xml b/java/mtsj/pom.xml index f5f24e094..271a440bf 100644 --- a/java/mtsj/pom.xml +++ b/java/mtsj/pom.xml @@ -1,6 +1,6 @@ - + 4.0.0 mtsj @@ -12,7 +12,7 @@ 2.0.4.RELEASE - 3.0.0 + 3.0.0 1.8 81 ${devon.port.range}81 @@ -220,12 +220,12 @@ devon.releases devon Releases - https://devon.s2-eu.capgemini.com/nexus/content/repositories/releases/ + http://nexus3-core:8081/nexus/content/repositories/releases/ devon.snapshots devon Snapshots - https://devon.s2-eu.capgemini.com/nexus/content/repositories/snapshots/ + http://nexus3-core:8081/nexus3/repository/snapshots \ No newline at end of file diff --git a/jenkins/README.md b/jenkins/README.md index 64401aa5f..ed63ea684 100644 --- a/jenkins/README.md +++ b/jenkins/README.md @@ -2,6 +2,173 @@ In this folder 2 Jenkinsfile(s) are provided to execute some CI/CD process for different parts of the **My Thai Star** project. One for the **Angular client** and another one for the **Java server**. Both are intended to be executed in an already configured **Production Line instance**. This configuration is required to be **used by Devonfw projects**, and a guide can be found in the [**Devonfw Shop Floor** incubator's wiki](https://github.com/devonfw/devonfw-shop-floor/wiki/devonfw-shop-floor-4-production-line-environment). +## Installed plugins + +In order to run all pipelines, we have installed the following plugins (maybe not all are required): + +- **Pipeline Utility Steps (pipeline-utility-steps)** +- OWASP Markup Formatter Plugin (antisamy-markup-formatter) +- Office 365 Connector (Office-365-Connector) +- JavaScript GUI Lib: ACE Editor bundle plugin (ace-editor) +- Ant Plugin (ant) +- Apache HttpComponents Client 4.x API Plugin (apache-httpcomponents-client-4-api) +- Authentication Tokens API Plugin (authentication-tokens) +- Autofavorite for Blue Ocean (blueocean-autofavorite) +- Bitbucket Pipeline for Blue Ocean (blueocean-bitbucket-pipeline) +- Common API for Blue Ocean (blueocean-commons) +- Config API for Blue Ocean (blueocean-config) +- Blue Ocean Core JS (blueocean-core-js) +- Display URL for Blue Ocean (blueocean-display-url) +- Events API for Blue Ocean (blueocean-events) +- Git Pipeline for Blue Ocean (blueocean-git-pipeline) +- GitHub Pipeline for Blue Ocean (blueocean-github-pipeline) +- i18n for Blue Ocean (blueocean-i18n) +- JIRA Integration for Blue Ocean (blueocean-jira) +- JWT for Blue Ocean (blueocean-jwt) +- Personalization for Blue Ocean (blueocean-personalization) +- Pipeline implementation for Blue Ocean (blueocean-pipeline-api-impl) +- Blue Ocean Pipeline Editor (blueocean-pipeline-editor) +- Pipeline SCM API for Blue Ocean (blueocean-pipeline-scm-api) +- REST Implementation for Blue Ocean (blueocean-rest-impl) +- REST API for Blue Ocean (blueocean-rest) +- Web for Blue Ocean (blueocean-web) +- Blue Ocean (blueocean) +- bouncycastle API Plugin (bouncycastle-api) +- Branch API Plugin (branch-api) +- build-env-propagator (build-env-propagator) +- Build Timeout (build-timeout) +- Bitbucket Branch Source Plugin (cloudbees-bitbucket-branch-source) +- Folders Plugin (cloudbees-folder) +- Command Agent Launcher Plugin (command-launcher) +- Config File Provider Plugin (config-file-provider) +- Credentials Binding Plugin (credentials-binding) +- Credentials Plugin (credentials) +- **Custom Tools Plugin (custom-tools-plugin)** +- Deploy to container Plugin (deploy) +- disk-usage plugin (disk-usage) +- Display URL API (display-url-api) +- Docker Commons Plugin (docker-commons) +- Docker API Plugin (docker-java-api) +- Docker plugin (docker-plugin) +- Docker Pipeline (docker-workflow) +- Durable Task Plugin (durable-task) +- Email Extension Plugin (email-ext) +- EnvInject API Plugin (envinject-api) +- Environment Injector Plugin (envinject) +- Extended Choice Parameter Plug-In (extended-choice-parameter) +- External Monitor Job Type Plugin (external-monitor-job) +- Favorite (favorite) +- Gerrit Trigger (gerrit-trigger) +- GitHub Pull Request Builder (ghprb) +- Git client plugin (git-client) +- GIT server Plugin (git-server) +- Git plugin (git) +- GitHub API Plugin (github-api) +- GitHub Branch Source Plugin (github-branch-source) +- GitHub Integration Plugin (github-pullrequest) +- GitHub plugin (github) +- Gradle Plugin (gradle) +- JavaScript GUI Lib: Handlebars bundle plugin (handlebars) +- Handy Uri Templates 2.x API Plugin (handy-uri-templates-2-api) +- HTML Publisher plugin (htmlpublisher) +- Icon Shim Plugin (icon-shim) +- Jackson 2 API Plugin (jackson2-api) +- Javadoc Plugin (javadoc) +- Design Language (jenkins-design-language) +- JIRA plugin (jira) +- JavaScript GUI Lib: jQuery bundles (jQuery and jQuery UI) plugin (jquery-detached) +- jQuery UI plugin (jquery-ui) +- jQuery plugin (jquery) +- JSch dependency plugin (jsch) +- JUnit Plugin (junit) +- LDAP Plugin (ldap) +- Lockable Resources plugin (lockable-resources) +- Mailer Plugin (mailer) +- MapDB API Plugin (mapdb-api) +- Matrix Authorization Strategy Plugin (matrix-auth) +- Matrix Project Plugin (matrix-project) +- **Maven Integration plugin (maven-plugin)** +- Mercurial plugin (mercurial) +- JavaScript GUI Lib: Moment.js bundle plugin (momentjs) +- Multiple SCMs plugin (multiple-scms) +- **NodeJS Plugin (nodejs)** +- PAM Authentication plugin (pam-auth) +- Pipeline: Build Step (pipeline-build-step) +- Pipeline: GitHub (pipeline-github) +- Pipeline GitHub Notify Step Plugin (pipeline-githubnotify-step) +- Pipeline Graph Analysis Plugin (pipeline-graph-analysis) +- Pipeline: Input Step (pipeline-input-step) +- Pipeline Maven Integration Plugin (pipeline-maven) +- Pipeline: Milestone Step (pipeline-milestone-step) +- Pipeline: Model API (pipeline-model-api) +- Pipeline: Declarative Agent API (pipeline-model-declarative-agent) +- Pipeline: Declarative (pipeline-model-definition) +- Pipeline: Declarative Extension Points API (pipeline-model-extensions) +- Pipeline: REST API Plugin (pipeline-rest-api) +- Pipeline: Stage Step (pipeline-stage-step) +- Pipeline: Stage Tags Metadata (pipeline-stage-tags-metadata) +- Pipeline: Stage View Plugin (pipeline-stage-view) +- Plain Credentials Plugin (plain-credentials) +- pom2config (pom2config) +- Publish Over SSH (publish-over-ssh) +- Infrastructure plugin for Publish Over X (publish-over) +- Pub-Sub "light" Bus (pubsub-light) +- Purge Job History Plugin (purge-job-history) +- Resource Disposer Plugin (resource-disposer) +- Reverse Proxy Auth Plugin (reverse-proxy-auth-plugin) +- SCM API Plugin (scm-api) +- Selenium Plugin (selenium) +- SeleniumRC plugin (seleniumrc-plugin) +- **SonarQube Scanner for Jenkins (sonar)** +- Server Sent Events (SSE) Gateway Plugin (sse-gateway) +- SSH Agent Plugin (ssh-agent) +- SSH Credentials Plugin (ssh-credentials) +- SSH Slaves plugin (ssh-slaves) +- Structs Plugin (structs) +- Subversion Plug-in (subversion) +- Self-Organizing Swarm Plug-in Modules (swarm) +- Terminal Plugin (terminal) +- Timestamper (timestamper) +- Token Macro Plugin (token-macro) +- Variant Plugin (variant) +- VncRecorder Plugin (vncrecorder) +- Windows Slaves Plugin (windows-slaves) +- Pipeline (workflow-aggregator) +- Pipeline: API (workflow-api) +- Pipeline: Basic Steps (workflow-basic-steps) +- Pipeline: Shared Groovy Libraries (workflow-cps-global-lib) +- Pipeline: Groovy (workflow-cps) +- Pipeline: Nodes and Processes (workflow-durable-task-step) +- Pipeline: Job (workflow-job) +- Pipeline: Multibranch (workflow-multibranch) +- Pipeline: SCM Step (workflow-scm-step) +- Pipeline: Step API (workflow-step-api) +- Pipeline: Supporting APIs (workflow-support) +- Workspace Cleanup Plugin (ws-cleanup) +- Xvnc plugin (xvnc) +- Dashboard for Blue Ocean (blueocean-dashboard) +- Script Security Plugin (script-security) + +Most of them come pre-installed with the production line instance. The ones we need are the ones related to the pipeline and the ones in bold. + +## Tools + +- Java 8u192 JDK \ + ![java8jdk](./java8-jdk.png) +- Google Chrome Stable \ + ![googlechromestable](./google-chrome-stable.png) +- SonarQube Scanner 3.2.0.1227 \ + ![sonarscanner](./sonar-scanner.png) +- Maven 3.6.0 + ![maven](./maven.png) +- NodeJS 10.14.0 + yarn + ![nodejs](./nodejs.png) + +## How to create the pipelines + +You only need to create a new pipeline and modify the configuration following the image: +![](./pipeline-config.png) + **TIP**: All environment variables used on both Jenkinsfiles should be declared in the correspondant Jenkins Pipeline configuration more or less like this: -![](./jenkins-pipelines-params.png) \ No newline at end of file +![](./jenkins-pipelines-params.png) diff --git a/jenkins/angular/Jenkinsfile b/jenkins/angular/Jenkinsfile deleted file mode 100644 index 60da35766..000000000 --- a/jenkins/angular/Jenkinsfile +++ /dev/null @@ -1,60 +0,0 @@ -node { - stage('Checking out MyThaiStar') { - deleteDir() - git branch: 'develop', credentialsId: 'github-devonfw-ci', url: 'https://github.com/oasp/my-thai-star/' - } - - stage('Loading Custom Tools') { - def node = tool name: 'Node 8.9 LTS', type: 'jenkins.plugins.nodejs.tools.NodeJSInstallation' - env.PATH = "${node}/bin:${env.PATH}" - sh "npm i -g yarn" - tool 'Chrome-stable' - } - - stage('Fresh Dependency Installation') { - sh """ - cd angular - #find . -name "node_modules" -exec rm -rf '{}' + - yarn - """ - } - - stage('Code Linting') { - sh """ - cd angular - yarn lint - """ - } - - stage('Execute Angular tests') { - sh """ - cd angular - ng test --browsers ChromeHeadless --single-run - """ - } - - stage('Build Application') { - sh """ - cd angular - ng build --prod --build-optimizer - """ - } - - stage('Deployment') { - sshagent (credentials: ['3d0fa2a4-5cf0-4cf5-a3fd-23655eb33c11']) { - def CONTAINER_PORT = 8090 - sh """ - cd angular - # Copy resulting "dist" folder from workspace to deployment server - scp -o StrictHostKeyChecking=no -r dist root@${params.EXTERNAL_SERVER_IP}:/root/mythaistar/angular/ - - # Launch application in Docker container - ssh -o StrictHostKeyChecking=no root@${params.EXTERNAL_SERVER_IP} docker rm -f mts-angular - ssh -o StrictHostKeyChecking=no root@${params.EXTERNAL_SERVER_IP} docker run -itd --name=mts-angular -p ${CONTAINER_PORT}:80 cbelda/nginx-try-files - ssh -o StrictHostKeyChecking=no root@${params.EXTERNAL_SERVER_IP} docker exec mts-angular bash -c \\"rm /usr/share/nginx/html/*\\" - ssh -o StrictHostKeyChecking=no root@${params.EXTERNAL_SERVER_IP} docker cp mythaistar/angular/dist/. mts-angular:/usr/share/nginx/html/ - """ - echo "Your app is available in http://${params.EXTERNAL_SERVER_IP}:${CONTAINER_PORT}" - } - } -} \ No newline at end of file diff --git a/jenkins/angular/cicd/Jenkinsfile b/jenkins/angular/cicd/Jenkinsfile new file mode 100644 index 000000000..d2ccc3694 --- /dev/null +++ b/jenkins/angular/cicd/Jenkinsfile @@ -0,0 +1,142 @@ +pipeline{ + agent any + + options { + buildDiscarder(logRotator(artifactDaysToKeepStr: '1', artifactNumToKeepStr: '1', daysToKeepStr: '5', numToKeepStr: '50')) + // Disable concurrent builds. It will wait until the pipeline finish before start a new one + disableConcurrentBuilds() + } + + tools { + nodejs "NodeJS 10.14.0" + } + + environment { + // Script for build the application. Defined at package.json + buildScript = 'build:prodcompose' + // Script for lint the application. Defined at package.json + lintScript = 'lint' + // Script for test the application. Defined at package.json + testScript = 'test:ci' + // Angular directory + angularDir = 'angular' + // SRC folder. It will be angularDir/srcDir + srcDir = 'src' + // Name of the custom tool for chrome stable + chrome = 'Chrome-stable' + + // sonarQube + // Name of the sonarQube tool + sonarTool = 'SonarQube-scanner' + // Name of the sonarQube environment + sonarEnv = "SonarQube" + + // Nexus + // Artifact groupId + groupId = 'com.devonfw.mythaistar' + // Nexus repository ID + repositoryId = 'devon.snapshots' + // Nexus internal URL + repositoryUrl = 'http://nexus3-core:8081/nexus3/repository/snapshots' + // Maven global settings ID + mavenGlobalSettings = '9d437f6e-46e7-4a11-a8d1-2f0055f14033' + // JavaJDK tool id + javaJdk = 'Java8' + // Maven tool id + mavenInstallation = 'Maven3' + } + + stages { + stage ('Loading Custom Tools') { + steps { + tool chrome + + } + } + + stage ('Fresh Dependency Installation') { + steps { + dir(angularDir){ + sh "yarn" + } + } + } + + stage ('Code Linting') { + steps { + dir(angularDir) { + sh """yarn ${lintScript}""" + } + } + } + + stage ('Execute Angular tests') { + steps { + dir(angularDir) { + sh """yarn ${testScript}""" + } + } + } + + stage ('SonarQube code analysis') { + steps { + script { + dir(angularDir) { + def scannerHome = tool sonarTool + def props = readJSON file: 'package.json' + withSonarQubeEnv(sonarEnv) { + sh """ + ${scannerHome}/bin/sonar-scanner \ + -Dsonar.projectKey=${props.name} \ + -Dsonar.projectName=${props.name} \ + -Dsonar.projectVersion=${props.version} \ + -Dsonar.sources=${srcDir} + """ + } + def qg = waitForQualityGate() + if (qg.status != 'OK') { + error "Pipeline aborted due to quality gate failure: ${qg.status}" + } + } + } + } + } + + stage ('Build Application') { + steps { + dir(angularDir) { + sh """yarn ${buildScript}""" + } + } + } + + stage ('Deliver application into Nexus') { + steps { + script { + dir(angularDir) { + def props = readJSON file: 'package.json' + zip dir: 'dist/', zipFile: """${props.name}.zip""" + withMaven(globalMavenSettingsConfig: mavenGlobalSettings, jdk: javaJdk, maven: mavenInstallation) { + sh """ + mvn deploy:deploy-file \ + -DgroupId=${groupId} \ + -DartifactId=${props.name} \ + -Dversion=${props.version}-SNAPSHOT \ + -Dpackaging=zip \ + -Dfile=${props.name}.zip \ + -DrepositoryId=${repositoryId} \ + -Durl=${repositoryUrl} + """ + } + } + } + } + } + } + + post { + always { + cleanWs() + } + } +} \ No newline at end of file diff --git a/jenkins/google-chrome-stable.png b/jenkins/google-chrome-stable.png new file mode 100644 index 000000000..f5c0b4c76 Binary files /dev/null and b/jenkins/google-chrome-stable.png differ diff --git a/jenkins/java/Jenkinsfile b/jenkins/java/Jenkinsfile deleted file mode 100644 index 5fa9e166a..000000000 --- a/jenkins/java/Jenkinsfile +++ /dev/null @@ -1,56 +0,0 @@ -node { - stage('Checking out MyThaiStar') { - deleteDir() - git branch: 'develop', credentialsId: 'github-devonfw-ci', url: 'https://github.com/devonfw/my-thai-star/' - } - stage('Load tools') { - tool name: 'Maven 3.3.9', type: 'maven' - env.JAVA_HOME="${tool 'OpenJDK 1.8'}" - env.PATH="${env.JAVA_HOME}/bin:${env.PATH}" - } - - // JACOCO and SONAR SCRIPT are REQUIRED. See: - // https://github.com/cbeldacap/my-thai-star/blob/develop/java/mtsj/pom.xml#L21-L61 - // https://github.com/cbeldacap/my-thai-star/blob/develop/java/mtsj/pom.xml#L185-L194 - // https://github.com/cbeldacap/my-thai-star/blob/develop/java/mtsj/pom.xml#L211-L282 - // stage('SonarQube analysis') { - // withMaven(globalMavenSettingsConfig: '9d437f6e-46e7-4a11-a8d1-2f0055f14033', jdk: 'OpenJDK 1.8', maven: 'Maven 3.3.9') { - // sh "cd java/mtsj && mvn sonar:sonar -X -Dsonar.login=${SONARQUBE_USERNAME} -Dsonar.password=${SONARQUBE_PASSWORD}" - // } - // } - - stage('Install dependencies') { - withMaven(globalMavenSettingsConfig: '9d437f6e-46e7-4a11-a8d1-2f0055f14033', jdk: 'OpenJDK 1.8', maven: 'Maven 3.3.9') { - sh "cd java/mtsj && mvn clean install -Dmaven.test.skip=true" - } - } - - stage('Execute tests') { - withMaven(globalMavenSettingsConfig: '9d437f6e-46e7-4a11-a8d1-2f0055f14033', jdk: 'OpenJDK 1.8', maven: 'Maven 3.3.9') { - sh "cd java/mtsj && mvn test" - } - } - - stage('Build and store in Nexus') { - withMaven(globalMavenSettingsConfig: '9d437f6e-46e7-4a11-a8d1-2f0055f14033', jdk: 'OpenJDK 1.8', maven: 'Maven 3.3.9') { - sh "cd java/mtsj && mvn clean deploy -Dmaven.test.skip=true" - } - } - - stage('Deployment') { - sshagent (credentials: ['3d0fa2a4-5cf0-4cf5-a3fd-23655eb33c11']) { - def CONTAINER_PORT = 9090 - sh """ - cd java/mtsj - # Copy resulting ".war" file from workspace to deployment server - scp -o StrictHostKeyChecking=no -r server/target/mythaistar.war root@${params.EXTERNAL_SERVER_IP}:/root/mythaistar/java/ - - # Launch application in Docker container - ssh -o StrictHostKeyChecking=no root@${params.EXTERNAL_SERVER_IP} docker rm -f mts-java - ssh -o StrictHostKeyChecking=no root@${params.EXTERNAL_SERVER_IP} docker run -itd --name=mts-java -p ${CONTAINER_PORT}:8080 tomcat:latest - ssh -o StrictHostKeyChecking=no root@${params.EXTERNAL_SERVER_IP} docker cp mythaistar/java/mythaistar.war mts-java:/usr/local/tomcat/webapps/ - """ - } - sh 'echo \\"Server available at http://de-mucdevondepl01:9090/mythaistar\\"' - } -} \ No newline at end of file diff --git a/jenkins/java/cicd/Jenkinsfile b/jenkins/java/cicd/Jenkinsfile new file mode 100644 index 000000000..d6fc226ee --- /dev/null +++ b/jenkins/java/cicd/Jenkinsfile @@ -0,0 +1,71 @@ +pipeline{ + agent any + + options { + buildDiscarder(logRotator(artifactDaysToKeepStr: '1', artifactNumToKeepStr: '1', daysToKeepStr: '5', numToKeepStr: '50')) + // Disable concurrent builds. It will wait until the pipeline finish before start a new one + // disableConcurrentBuilds() + } + + tools { + maven 'Maven3' + jdk 'Java8' + } + + environment { + // Directory with java project + javaDir = 'java/mtsj' + // Maven global settings ID + mavenGlobalSettings = '9d437f6e-46e7-4a11-a8d1-2f0055f14033' + + // sonarQube + // Name of the sonarQube environment + sonarEnv = "SonarQube" + } + + stages { + stage ('Unit Tests') { + steps { + dir(javaDir) { + withMaven(globalMavenSettingsConfig: mavenGlobalSettings){ + sh "mvn clean test" + } + } + } + } + + stage ('SonarQube code analysis') { + steps { + script { + dir(javaDir) { + withMaven(globalMavenSettingsConfig: mavenGlobalSettings){ + withSonarQubeEnv(sonarEnv) { + sh "mvn sonar:sonar" + } + def qg = waitForQualityGate() + if (qg.status != 'OK') { + error "Pipeline aborted due to quality gate failure: ${qg.status}" + } + } + } + } + } + } + + stage ('Deliver application into Nexus') { + steps { + dir(javaDir) { + withMaven(globalMavenSettingsConfig: mavenGlobalSettings){ + sh "mvn deploy -Dmaven.test.skip=true" + } + } + } + } + } + + post { + always { + cleanWs() + } + } +} \ No newline at end of file diff --git a/jenkins/java8-jdk.png b/jenkins/java8-jdk.png new file mode 100644 index 000000000..9fd72a0d1 Binary files /dev/null and b/jenkins/java8-jdk.png differ diff --git a/jenkins/maven.png b/jenkins/maven.png new file mode 100644 index 000000000..14d9250e5 Binary files /dev/null and b/jenkins/maven.png differ diff --git a/jenkins/node/cicd/Jenkinsfile b/jenkins/node/cicd/Jenkinsfile new file mode 100644 index 000000000..3931107f5 --- /dev/null +++ b/jenkins/node/cicd/Jenkinsfile @@ -0,0 +1,121 @@ +pipeline{ + agent any + + options { + buildDiscarder(logRotator(artifactDaysToKeepStr: '1', artifactNumToKeepStr: '1', daysToKeepStr: '5', numToKeepStr: '50')) + // Disable concurrent builds. It will wait until the pipeline finish before start a new one + // disableConcurrentBuilds() + } + + tools { + nodejs "NodeJS 10.14.0" + } + + environment { + buildScript = "compile" + lintScript = "lint" + testScript = "test" + nodeDir = "node" + + // sonarQube + sonarTool = 'SonarQube-scanner' + sonarEnv = "SonarQube" + + // Nexus + artifactId = 'my-thai-star' + groupId = 'com.devonfw.mythaistar' + repositoryId = 'devon.snapshots' + repositoryUrl = 'http://nexus3-core:8081/nexus3/repository/snapshots' + mavenGlobalSettings = '9d437f6e-46e7-4a11-a8d1-2f0055f14033' + javaJdk = 'Java8' + mavenInstallation = 'Maven3' + } + + stages { + + stage ('Fresh Dependency Installation') { + steps { + dir(nodeDir){ + sh "npm i" + } + } + } + + stage ('Code Linting') { + steps { + dir(nodeDir) { + sh """npm run ${lintScript}""" + } + } + } + + stage ('Execute tests') { + steps { + dir(nodeDir) { + sh """npm run ${testScript}""" + } + } + } + + stage ('SonarQube code analysis') { + steps { + script { + dir(nodeDir) { + def scannerHome = tool sonarTool + def props = readJSON file: 'package.json' + withSonarQubeEnv(sonarEnv) { + sh """ + ${scannerHome}/bin/sonar-scanner \ + -Dsonar.projectKey=${props.name} \ + -Dsonar.projectName=${props.name} \ + -Dsonar.projectVersion=${props.version} \ + -Dsonar.sources=src + """ + } + def qg = waitForQualityGate() + if (qg.status != 'OK') { + error "Pipeline aborted due to quality gate failure: ${qg.status}" + } + } + } + } + } + + stage ('Build Application') { + steps { + dir(nodeDir) { + sh """npm run ${buildScript}""" + } + } + } + + stage ('Deliver application into Nexus') { + steps { + script { + dir(nodeDir) { + def props = readJSON file: 'package.json' + zip dir: 'dist/', zipFile: """${props.name}.zip""" + withMaven(globalMavenSettingsConfig: mavenGlobalSettings, jdk: javaJdk, maven: mavenInstallation) { + sh """ + mvn deploy:deploy-file \ + -DgroupId=${groupId} \ + -DartifactId=${props.name} \ + -Dversion=${props.version}-SNAPSHOT \ + -Dpackaging=zip \ + -Dfile=${props.name}.zip \ + -DrepositoryId=${repositoryId} \ + -Durl=${repositoryUrl} + """ + } + } + } + } + } + } + + post { + always { + cleanWs() + } + } +} \ No newline at end of file diff --git a/jenkins/nodejs.png b/jenkins/nodejs.png new file mode 100644 index 000000000..ef3eacf57 Binary files /dev/null and b/jenkins/nodejs.png differ diff --git a/jenkins/pipeline-config.png b/jenkins/pipeline-config.png new file mode 100644 index 000000000..41c2e972c Binary files /dev/null and b/jenkins/pipeline-config.png differ diff --git a/jenkins/sonar-scanner.png b/jenkins/sonar-scanner.png new file mode 100644 index 000000000..10d4ae15d Binary files /dev/null and b/jenkins/sonar-scanner.png differ diff --git a/node/package-lock.json b/node/package-lock.json index 2c20213dc..b2d40135a 100644 --- a/node/package-lock.json +++ b/node/package-lock.json @@ -3824,12 +3824,6 @@ "resolved": "http://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz", "integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow==" }, - "duplexer": { - "version": "0.1.1", - "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", - "dev": true - }, "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -4214,22 +4208,6 @@ "es5-ext": "~0.10.14" } }, - "event-stream": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.6.tgz", - "integrity": "sha512-dGXNg4F/FgVzlApjzItL+7naHutA3fDqbV/zAZqDDlXTjiMnQmZKu+prImWKszeBM5UQeGvAl3u1wBiKeDh61g==", - "dev": true, - "requires": { - "duplexer": "^0.1.1", - "flatmap-stream": "^0.1.0", - "from": "^0.1.7", - "map-stream": "0.0.7", - "pause-stream": "^0.0.11", - "split": "^1.0.1", - "stream-combiner": "^0.2.2", - "through": "^2.3.8" - } - }, "events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", @@ -5007,12 +4985,6 @@ } } }, - "flatmap-stream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/flatmap-stream/-/flatmap-stream-0.1.2.tgz", - "integrity": "sha512-ucyr6WkLXjyMuHPtOUq4l+nSAxgWi7v4QO508eQ9resnGj+lSup26oIsUI5aH8k4Qfpjsxa8dDf9UCKkS2KHzQ==", - "dev": true - }, "flow-parser": { "version": "0.81.0", "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.81.0.tgz", @@ -5139,12 +5111,6 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", - "dev": true - }, "from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", @@ -8258,12 +8224,6 @@ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, - "map-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", - "integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=", - "dev": true - }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", @@ -8945,16 +8905,16 @@ } }, "nodemon": { - "version": "1.18.6", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.18.6.tgz", - "integrity": "sha512-4pHQNYEZun+IkIC2jCaXEhkZnfA7rQe73i8RkdRyDJls/K+WxR7IpI5uNUsAvQ0zWvYcCDNGD+XVtw2ZG86/uQ==", + "version": "1.18.7", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.18.7.tgz", + "integrity": "sha512-xuC1V0F5EcEyKQ1VhHYD13owznQbUw29JKvZ8bVH7TmuvVNHvvbp9pLgE4PjTMRJVe0pJ8fGRvwR2nMiosIsPQ==", "dev": true, "requires": { "chokidar": "^2.0.4", "debug": "^3.1.0", "ignore-by-default": "^1.0.1", "minimatch": "^3.0.4", - "pstree.remy": "^1.1.0", + "pstree.remy": "^1.1.2", "semver": "^5.5.0", "supports-color": "^5.2.0", "touch": "^3.1.0", @@ -12294,15 +12254,6 @@ "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" }, - "pause-stream": { - "version": "0.0.11", - "resolved": "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", - "dev": true, - "requires": { - "through": "~2.3" - } - }, "pbkdf2": { "version": "3.0.17", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", @@ -12473,15 +12424,6 @@ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, - "ps-tree": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz", - "integrity": "sha1-tCGyQUDWID8e08dplrRCewjowBQ=", - "dev": true, - "requires": { - "event-stream": "~3.3.0" - } - }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -12493,13 +12435,10 @@ "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" }, "pstree.remy": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.0.tgz", - "integrity": "sha512-q5I5vLRMVtdWa8n/3UEzZX7Lfghzrg9eG2IKk2ENLSofKRCXVqMvMUHxCKgXNaqH/8ebhBxrqftHWnyTFweJ5Q==", - "dev": true, - "requires": { - "ps-tree": "^1.1.0" - } + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.2.tgz", + "integrity": "sha512-vL6NLxNHzkNTjGJUpMm5PLC+94/0tTlC1vkP9bdU0pOHih+EujMjgMTwfZopZvHWRFbqJ5Y73OMoau50PewDDA==", + "dev": true }, "public-encrypt": { "version": "4.0.2", @@ -14217,15 +14156,6 @@ "integrity": "sha512-TfOfPcYGBB5sDuPn3deByxPhmfegAhpDYKSOXZQN81Oyrrif8ZCodOLzK3AesELnCx03kikhyDwh0pfvvQvF8w==", "dev": true }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dev": true, - "requires": { - "through": "2" - } - }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -14375,16 +14305,6 @@ } } }, - "stream-combiner": { - "version": "0.2.2", - "resolved": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", - "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=", - "dev": true, - "requires": { - "duplexer": "~0.1.1", - "through": "~2.3.4" - } - }, "stream-each": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", diff --git a/node/package.json b/node/package.json index d917c6da4..3ff2b397c 100644 --- a/node/package.json +++ b/node/package.json @@ -19,7 +19,8 @@ "test:cov": "jest --coverage", "test:e2e": "jest --config ./test/jest-e2e.json", "webpack": "webpack --config webpack.config.js", - "compile": "tsc" + "compile": "tsc", + "lint": "tslint --project ." }, "dependencies": { "@nestjs/common": "^5.4.0", @@ -58,7 +59,7 @@ "@types/supertest": "^2.0.4", "husky": "^1.1.4", "jest": "^23.5.0", - "nodemon": "^1.18.6", + "nodemon": "^1.18.7", "prettier": "^1.15.2", "supertest": "^3.0.0", "ts-jest": "^23.1.3",