Jenkins and NodeJS
===============================

********************************************************************************
## Jenkins pipelineScript.groovy
********************************************************************************

    /**
     * Represents a stage with a stage label,
     * the label where the stage should be executed,
     * an action to execute and the respective arguments.
     */
    class Stage implements Serializable {

        def stageLabel // label of the stage represented by this object
        def action // action to perform in the stage
        def parameters // required arguments

        Stage(stageLabel, action, parameters) {
            this.stageLabel = stageLabel
            this.action = action
            this.parameters = parameters
        }

        /**
         * Helper function which transforms a list of
         * arguments to var args before passing them
         * to the action.
         */
        private def execute(environment, enabled, Object... args) {
                if (this.stageLabel) {
                    environment.stage(this.stageLabel)
                }

                if (!enabled) {
                    return
                }

                if (this.stageLabel != null) {
                    environment.gitlabCommitStatus(this.stageLabel) {
                        this.action.call(args)
                    }
                } else {
                    this.action.call(args)
                }
        }

        /**
         * Runs the stage
         */
        def run(environment, enabled) {
            execute(environment, enabled, this.parameters)
        }
    }

    def cleanUpWorkspace(workspace) {
        // delete all files in the workspace
        if (fileExists("${workspace}")) {
            sh "rm -rf ${workspace}"
        }
    }

    def checkoutSourceCode(repoUrl) {
        /// Checkouts the source branch from the specified
        /// repository into 'src' directory and merges to target branch
        checkout([
            $class: 'GitSCM',
            branches: [[name: "origin/${sourceBranch}"]],
            browser: [$class: 'GitLab', repoUrl: 'https://gitlab.pathseeker.ir', version: '8.9'],
            doGenerateSubmoduleConfigurations: false,
            extensions: [
            [$class: 'RelativeTargetDirectory', relativeTargetDir: 'src'],
            [$class: 'PreBuildMerge',
                options: [
                fastForwardMode: 'FF',
                mergeRemote: 'origin',
                mergeStrategy: 'default',
                mergeTarget: "${targetBranch}"]
                ],
            [$class: 'SubmoduleOption',
                disableSubmodules: false,
                recursiveSubmodules: true,
                reference: '',
                trackingSubmodules: false]
            ],
            submoduleCfg: [],
            userRemoteConfigs: [
                [credentialsId: 'New Jenkins Password',
                name: 'origin',
                url: "${repoUrl}"]
            ]
        ])
    }

    def cleanUp(targetDir) {
        if (fileExists("${targetDir}")) {
            echo "Cleaning directory ${targetDir}"
            dir("${targetDir}") {
                deleteDir()
            }
        }
    }

    def buildStage(workspace) {
        if (isUnix()) {
                setup_and_run_cmd = "cd ${workspace}/src;date +'%d-%m-%Y-%H:%M:%S' > BuildDate.txt; bash install_node_modules.sh; npm run build:productionPortal;cp -r . /home/jenkins/build/"
                sh(setup_and_run_cmd)

        }
    }



    node('nodeJS') {

        // create all stages
        def repo_url = "git@gitlab.pathseeker.ir:linuxCamp/nodeJS-app.git"
        def allStages = []
        allStages.add(new Stage(null, {cleanUpWorkspace it}, [workspace] as Object[])) /* Windows clean up */
        allStages.add(new Stage("Checkout", {checkoutSourceCode it}, [repo_url] as Object[])) /* Windows checkout */
        allStages.add(new Stage("Build", {buildStage it}, [workspace] as Object[])) /* perform unit tests */


        // enable / disable stages
        def enabledStages = [
            cleanBeforeBuild.toBoolean(),                        // clean up
            true,                                                // checkout
            RunBuild.toBoolean(),                                // run tests
        ]

        for (int i=0; i < allStages.size(); i++) {
            def enabled = enabledStages[i]
            allStages[i].run(this, enabled)
        }
    }

********************************************************************************
## docker-compose.yml
********************************************************************************

    version: '2'
    services:
      nodejs:
        build: ./build
        image: pathseeker/nodejs:1.0
        tty: true
        ports:
        - "22022:22"
        volumes:
        - ./data:/home/jenkins/build 
        depends_on:
          - "local-npm"   
      #https://hub.docker.com/r/orlandohohmeier/local-npm/~/dockerfile/   
      local-npm:
        image: pathseeker/local-npm:latest
        tty: true    
        build: ./build/local-npm
        ports:
        - "5080:5080"
        volumes:
        - ./npm-local:/data
    
********************************************************************************
## local-npm Dockerfile 
********************************************************************************

    FROM node:6.9

    MAINTAINER Orlando Hohmeier <hello@orlandohohmeier.com>

    WORKDIR /local-npm
    ADD . /local-npm/

    RUN groupadd -r local-npm --gid=999 \
        && useradd -r -g local-npm --uid=999 local-npm

    RUN npm set progress=false && npm install --no-color && npm dedupe

    EXPOSE 5080
    EXPOSE 16984

    VOLUME /data

    ENV BASE_URL='http://local-npm:5080'
    ENV DATA_DIRECTORY='/data'
    ENV REMOTE_REGISTRY='https://registry.npmjs.org'
    ENV REMOTE_REGISTRY_SKIMDB='https://skimdb.npmjs.com/registry'

    CMD mkdir -p "$DATA_DIRECTORY" chmod 700 "$DATA_DIRECTORY" \
        && chown -R local-npm "$DATA_DIRECTORY" \
        && npm start -- --remote $REMOTE_REGISTRY \
            --remote-skim $REMOTE_REGISTRY_SKIMDB --directory $DATA_DIRECTORY \
            --url-base $BASE_URL

********************************************************************************
## node Dockerfile 
********************************************************************************

    FROM node:6.9-slim

    MAINTAINER Farid Ahmadian <ahmadian.farid.1988@gmail.com>

    RUN useradd -m jenkins

    # Copy .ssh/known_hosts including the gitlab server's key
    # ATTENTION: Make sure the public key of the gitlab server
    # is contained in the provided `known_hosts` file
    COPY ssh /home/jenkins/.ssh
    # change ownership of the .ssh directory content
    RUN chown -hR jenkins:jenkins /home/jenkins/.ssh
    RUN chmod go-rwx /home/jenkins/.ssh
    RUN chmod 400 /home/jenkins/.ssh/id_rsa

    RUN apt-get update
    RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends apt-utils
    RUN apt-get update && apt-get install -y openssh-server

    # Global install yarn package manager
    RUN apt-get update && apt-get install -y curl apt-transport-https && \
        curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
        echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
        apt-get update && apt-get install -y yarn


    WORKDIR /workspace

    # Copy the script to desire location
    ADD docker-entrypoint.sh /docker-entrypoint.sh
    RUN chmod +x /docker-entrypoint.sh

    ENTRYPOINT [ "sh", "/docker-entrypoint.sh" ]

    RUN echo "jenkins:jenkins" | chpasswd jenkins

    RUN set -ex && \
        echo 'deb http://deb.debian.org/debian jessie-backports main' \
          > /etc/apt/sources.list.d/jessie-backports.list && \

        apt update -y && \
        apt install -t \
          jessie-backports \
          openjdk-8-jre-headless \
    ca-certificates-java -y

    RUN apt-get install -y git
    RUN npm set registry http://local-npm:5080

********************************************************************************
## docker-entrypoint.sh 
********************************************************************************
 
    #!/bin/bash
    /etc/init.d/ssh start
    bash

********************************************************************************
## jenkins_home/jobs/Builder/config.xml
********************************************************************************
 
    <?xml version='1.1' encoding='UTF-8'?>
    <flow-definition plugin="workflow-job@2.14.1">
      <actions/>
      <description></description>
      <keepDependencies>false</keepDependencies>
      <properties>
        <com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty plugin="gitlab-plugin@1.4.8">
          <gitLabConnection>GitLab Server Connection</gitLabConnection>
        </com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty>
        <hudson.model.ParametersDefinitionProperty>
          <parameterDefinitions>
            <hudson.model.BooleanParameterDefinition>
              <name>cleanBeforeBuild</name>
              <description></description>
              <defaultValue>false</defaultValue>
            </hudson.model.BooleanParameterDefinition>
            <hudson.model.BooleanParameterDefinition>
              <name>RunBuild</name>
              <description></description>
              <defaultValue>true</defaultValue>
            </hudson.model.BooleanParameterDefinition>
            <hudson.model.StringParameterDefinition>
              <name>sourceBranch</name>
              <description></description>
              <defaultValue>master</defaultValue>
              <trim>false</trim>
            </hudson.model.StringParameterDefinition>
            <hudson.model.StringParameterDefinition>
              <name>targetBranch</name>
              <description></description>
              <defaultValue>master</defaultValue>
              <trim>false</trim>
            </hudson.model.StringParameterDefinition>
          </parameterDefinitions>
        </hudson.model.ParametersDefinitionProperty>
        <org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty>
          <triggers>
            <com.dabsquared.gitlabjenkins.GitLabPushTrigger plugin="gitlab-plugin@1.4.8">
              <spec></spec>
              <triggerOnPush>true</triggerOnPush>
              <triggerOnMergeRequest>true</triggerOnMergeRequest>
              <triggerOnPipelineEvent>false</triggerOnPipelineEvent>
              <triggerOnAcceptedMergeRequest>false</triggerOnAcceptedMergeRequest>
              <triggerOnClosedMergeRequest>false</triggerOnClosedMergeRequest>
              <triggerOpenMergeRequestOnPush>never</triggerOpenMergeRequestOnPush>
              <triggerOnNoteRequest>true</triggerOnNoteRequest>
              <noteRegex>@jenkins rebuild</noteRegex>
              <ciSkip>true</ciSkip>
              <skipWorkInProgressMergeRequest>true</skipWorkInProgressMergeRequest>
              <setBuildDescription>true</setBuildDescription>
              <branchFilterType>All</branchFilterType>
              <includeBranchesSpec></includeBranchesSpec>
              <excludeBranchesSpec></excludeBranchesSpec>
              <targetBranchRegex></targetBranchRegex>
              <secretToken>{AQAAABAAAAAQ3ZQX7gSjEN5TSx6Qi77xM8AU5at4slVt+odvdtBKFVY=}</secretToken>
            </com.dabsquared.gitlabjenkins.GitLabPushTrigger>
          </triggers>
        </org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty>
      </properties>
      <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps@2.41">
        <script>
        </script>
        <sandbox>true</sandbox>
      </definition>
      <triggers/>
      <disabled>false</disabled>
    </flow-definition>
 
********************************************************************************
_BY: Farid Ahmadian_  
_TAG: Jenkins, NodeJS, Dockerfile, docker_  
_DATE: 2018-06-13 10:36:53_