Jérôme Decoster

Jérôme Decoster

3x AWS Certified - Architect, Developer, Cloud Practionner

03 Mar 2020

Jenkins + github

The Goal
Install Jenkins with Docker and test a Node.js project hosted on github after each commit.

    architecture.svg

    Install and setup the project

    Get the code from this github repository :

    • The source code for this project is used to run a ready-to-use docker container.
    • The setup.sh script is really simple.
    # download the code
    $ git clone \
        --depth 1 \
        https://github.com/jeromedecoster/note-jenkins-github.git \
        /tmp/note
    
    # cd
    $ cd /tmp/note
    
    # docker pull jenkins
    $ make setup
    

    After the setup, we can now start the install :

    • The install.sh script starts the first steps of the Jenkins installation. The rest will we done manually within the browser.
    • The fully automated installation of Jenkins is a painful experience for me : many strange steps for a result that is never completely satisfactory. And this is clearly what software should avoid doing.
    # create docker image with jenkins + plugins
    $ make install
    

    The docker image store all Jenkins data in a local directory :

    • A volume link is created between /var/jenkins_home and a local directory /var/docker/jenkins-github our your computer.
    docker run \
        --detach \
        --user 0 \
        --publish 8080:8080 \
        --publish 50000:50000 \
        --volume /var/docker/jenkins-github:/var/jenkins_home \
        --name jenkins-github \
        jenkins/jenkins:lts
    

    You can open http://localhost:8080 to paste the password displayed in the terminal :

    install-password.png

    Now we choose to install the suggested plugins :

    install-choose-plugins.png

    Let’s go have a coffee :

    install-download-plugins.png

    We create the admin user :

    install-admin.png

    Let’s validate the Jenkins URL :

    install-url.png

    The basic installation is complete. But we must now install 2 additional plugins from the Plugin Manager area :

    • Search github integration and choose Install without restart.

    plugins-github-integration.png

    • Search nodejs and choose again Install without restart.

    plugins-nodejs.png

    Now we need to configure NodeJS in the http://localhost:8080/configureTools/ area :

    • We choose the LTS version and name the configuration node-v12.
    • We check Install automatically and select a 12.x.x version.

    configure-node.png

    Extra step, we can zip our docker local volume directory to save the current state of Jenkins :

    # get the variables
    $ source settings.sh
    
    # go to our local volume directory
    $ cd /var/docker/
    
    # zip the local volume directory
    $ sudo zip -r9 $NAME.zip $NAME
    

    Configure Jenkins

    Let’s create a new free-style project :

    free-style-project.png

    We will use a simple node project to test Jenkins. You can fork this project and setup the Git repository with your own URL :

    configure-git.png

    Now we configure the lookup with a cron pattern : * * * * * means check every minute if there has been a new commit.

    configure-build.png

    Then we define the NodeJS installation with our node-v12 configuration :

    configure-build-nodejs.png

    Now we can define a shell script to execute :

    configure-build-shell.png

    Simple things to execute :

    npm install
    npm test
    

    The npm test is defined in the package.json file :

    npx mocha './**/*.test.js'
    

    This will execute this simple app.test.js file :

    describe('/add', () => {
    
        it('success', (done) => {
            const a = 2
            const b = 4
            const expected = 6
    
            request(app)
                .post('/add')
                .send({ a, b })
                .set('Accept', 'application/json')
                .end((err, res) => {
    
                    if (err) return done(err)
    
                    const result = res.body.result
                    if (result === expected) return done()
    
                    done(new Error(`receive:${result} expected:${expected}`))
                })
        })
    
        // ...
    

    The configuration is done. We save it. The we launch a build :

    launch-build.png

    In Console Output we see the processing running :

    build-1.png

    Then it’s built with SUCCESS :

    build-2.png

    Let’s modifiate the app.js file directly in github :

    modify.png

    We add an error :

    return res.json({
        result: a + b + 1 // modification done here
    })
    

    We commit the error :

    error-introduced.png

    After a few seconds, a build is automatically started :

    build-running.png

    We choose Console Output from the contextual menu :

    build-go-console-output.png

    The process ends with our expected FAILURE :

    Error: receive: 7 expected: 6
    

    build-console-output.png