Jenkins NodeJS Plugin fails during install phase with npm ci - node.js

I'm trying to build a npm project ( Angular Project ) on the Jenkins master ( on a Docker ).
Last week I've setup the project and everything worked just fine. Today morning I've made a change on a branch and it kept failing during the first phase which include a node command called with the NodeJS plugin. There's no log on Jenkins so I can't really know what's going on.
Here's the stage code:
stages {
stage('Install') {
steps {
script {
lastRunningStage="Install"
}
nodejs(nodeJSInstallationName: 'node14.16', configId: '320662bf-2907-4c12-87f1-225abaa8d503') {
sh 'npm ci'
}
}
}

Related

Jenkins: Replace running Express-app with the most current Express-app

I have created a Jenkins-file, which first pulls the sources of a Express-app from the GitHub-Repository, then installs the dependencies, then starts the Express-App.
pipeline {
agent any
tools {
nodejs 'NodeJS'
}
stages {
stage('Build') {
steps {
sh 'npm install'
echo "install dependencies."
}
}
stage('Deploying') {
steps {
sh 'node index.js'
echo "run express-app ..."
}
}
}
}
Now I have configured "Scan Repository Triggers" to 15 minutes. So, that Jenkins runs the Jenkins-file every 15 minutes, in case there have been changes in the GitHub-repository.
The problem is, that the previous app is still running and occupying the port, which is defined in the sources.
How can I stop the older, running app and replace it with the updated app? The target is, that the respective most current version of the app is supplied, if one enters the URL.
There are multiple ways to get this done. One way is to use something like nodemon. Another clean way to manage our node server is by using something like forever. Then you can Gracefully manage the server.
forever start app.js
forever restart app.js
If you don't want to rely on additional tools. You can kill the Node server before starting it again. There are multiple ways to do this. One option is to get the process ID by the port and then kill the server. You can refer to this question.

Building React App inside of Node server best practice

Have a react repo and a node repo. The are on the same root directory like so:
--myReactApp
--myNodeServer
I have a script in the React app that builds the React app and places the generated files into the Node server's public directory.
npm run-script build
#Remove the files from the server directory
rm -r ../myNodeServer/public/*
#copy over new files
cp -r ./build/. ../myNodeServer/public
This is all good, but now I am doing CI/CD with Jenkin's pipeline and it pulls the myNodeServer repo that does not have the React app in the public folder. I don't think it is best practice to include generated files in the myNodeServer's public directory, so I don't want to check in the React app into the the Node repo.
What do developer's generally do in the this situation. Is it possible to pull from 2 different repos in a pipeline script.
Right now my script looks like this:
pipeline {
agent any
tools {nodejs "Node8"}
environment {
DBPASSWORD = credentials('DBPASSWORD')
DEPLOYSECRET = credentials('DEPLOYSECRET')
}
stages {
stage('NPM Install') {
steps {
sh 'npm install'
}
}
stage('Unit Test') {
steps {
sh 'env PORT=3090 DBUSER=username DBPASSWORD=$DBPASSWORD DEPLOYSecret=$DEPLOYSECRET ENV=unitTest ./node_modules/mocha/bin/_mocha --timeout 10000 --timeout 0 --ui bdd --recursive ./test'
}
}
}
}

How to change Node.js version on Jenkins?

I have several jobs on Jenkins for launch protractor tests. I'm starting to use async/await at some points and seems that the default version of Node.js that has Jenkins doesn't handle async/await.
I prepared a workaround on another pipeline that uses async/await, but I don't want to use it as a default solution:
nodejs(nodeJSInstallationName: "Node 8.11") {
"npm config ls"
"node -v"
"npm"
}
How can I setup the desired version Node.js, which will be used by Jenkins by default?
Go to: Dashboard → Manage Jenkins → Global Tool Configuration → NodeJS and pick the desired Node.js version from the combobox.
Just use the following two lines in your pipeline
env.NODEJS_HOME = "${tool 'NodeJsv12.16.2'}"
env.PATH="${env.NODEJS_HOME}/bin:${env.PATH}"
See the example bellow
node {
env.NODEJS_HOME = "${tool 'NodeJsv12.16.2'}"
env.PATH="${env.NODEJS_HOME}/bin:${env.PATH}"
sh 'npm --version'
stage('Preparation') {
}
}

How to execute Node .JS APIs test cases using Jenkinsfile

I am new to Jenkins. I have a small Node .JS server and the test cases are written using Mocha(Integration test cases, not unit test cases). I am trying to create a CI Pipeline for this using Jenkins. My Jenkinsfile looks as follows:
#!/usr/bin/env groovy
pipeline {
agent {
docker {
image 'node'
args '-u root'
}
}
stages {
stage('Build') {
steps {
echo 'Installing Dependencies...'
sh 'npm install'
}
}
stage('Run') {
steps {
echo 'Starting application...'
sh 'npm start'
}
}
stage('Test') {
steps {
echo 'Testing...'
sh 'npm test'
}
}
}
}
In the run stage, the server is started using the command node server.js, Once the server is up I want the test cases to be executed against this server. But I notice that, Jenkins never executes the Test stage since the server remains started(this is what i want), and does not exit from it.
How can I have the server started and also have the test stage run against this server?
You should run the tests before running the server. The test should not depend on the running server. Tests should require whatever is required and test, then you should run the server.
https://github.com/jenkinsci/pipeline-examples/tree/master/jenkinsfile-examples/nodejs-build-test-deploy-docker-notify
I have resolved this by creating separated build jobs and then linking them together. In the run stage, I change the directory to the build folder using "cd" command and start the server. In the test stage, I do the same, but, execute the test cases on the server started in run stage.
Thank you everyone for your inputs.

Writing a Jenkins Pipeline Shared Library to publish to Nexus NPM repository

I used to publish my NPM projects to Nexus using a DSL pipeline containing a publish stage with this kind of step :
stage ('Publish') {
nodejs(nodeJSInstallationName: 'Node LTS', configId: '123456ab-1234-abcd-1234-f123d45e6789') {
sh 'npm publish'
}
}
I have a NodeJS installation named "Node LTS" on my Jenkins and a npmrc config file with this configId.
Now I want to export this stage into a groovy SharedLib.
According to Declarative Pipeline documentation and this nodejs-plugin issue, I could write this :
stage('Publish') {
tools {
nodejs 'Node LTS'
}
steps {
sh 'npm publish'
}
}
But this does not set authentification configuration that is currently in my npmrc configuration file :
registry=http://my-nexus/repository/npm-private/
_auth="some=base=64=credential=="
always-auth=true
Any idea to retreive this configuration with declarative syntax and prevent this error message ?
npm ERR! code ENEEDAUTH
npm ERR! need auth auth required for publishing
npm ERR! need auth You need to authorize this machine using `npm adduser`
Taking a look to npm log files and reading documentation, I finally find the best solution was to specify the following publish configuration in my package.json file :
{
"name": "#my-company/my-project",
...
"publishConfig": {
"registry": "http://my-nexus/repository/npm-private/"
},
...
}
I leave the .npmrc configuration :
registry=http://my-nexus/repository/npm-private/
_auth="some=base=64=credential=="
always-auth=true
Note : the always-auth is needed, in my case, for automation script : https://docs.npmjs.com/misc/config
I struggled with having an node package published to nexus 3 from jenkins pipeline and here is what worked for me. It might help someone.
pipeline {
agent any
environment {
registryCredentials = "nexus"
registryPrivate = "http://nexus:8081/repository/your-nexus-repo/" // nexus repository
}
stages {
stage('Publish') {
steps {
script {
nodejs('your-jenkins-nodejs-name') {
sh("rm ~/.npmrc || echo 'trying to remove .npmrc'") // remove .npmrc
// this token is copied from ~/.npmrc file after a interactive npm login
// do a npm login to your nexus npm hosted private repo and get the token
sh 'echo "//nexus:8081/repository/vinsystems-npm/:_authToken=NpmToken.302af6fb-9ad4-38cf-bb71-57133295c7ca" >> ~/.npmrc'
sh("cd ./WebClientWorkspace && yarn install")
sh("cd ..")
sh("yarn publish ./path/to/your/js-library --registry=${registryPrivate} --registry=${registryPrivate} --non-interactive --verbose")
}
}
}
}
}
}

Resources