Jenkins pipeline how to change to another folder and run npm tests - jenkins

Currently, I am using Jenkins pipeline script.
For running my tests, I need to access my code which is sitting on the desktop.
I tried this:
pipeline {
agent any
tools {nodejs "node"}
stages {
stage('Tests') {
steps {
sh 'cd users/tests/'
sh 'npm run shopfloor.shopfloor'
}
}
}
}
How I can change to my test folder and then run "npm run test"
I tried the answer below however i am getting this error now:
Running in users/tests/
[Pipeline] {
[Pipeline] sh
shell-init: error retrieving current directory: getcwd: cannot access parent directories: Operation not permitted
+ npm run shopfloor.shopfloor
job-working-directory: error retrieving current directory: getcwd: cannot access parent directories: Operation not permitted
Error: EPERM: operation not permitted, uv_cwd
at process.wrappedCwd (internal/bootstrap/switches/does_own_process_state.js:129:28)
at process.cwd (/Users/.jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/node/lib/node_modules/npm/node_modules/graceful-fs/polyfills.js:10:19)
at Conf.loadPrefix (/Users/.jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/node/lib/node_modules/npm/lib/config/load-prefix.js:46:24)
at load_ (/Users/.jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/node/lib/node_modules/npm/lib/config/core.js:109:8)
at Conf.<anonymous> (/Users/.jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/node/lib/node_modules/npm/lib/config/core.js:96:5)
at Conf.emit (events.js:315:20)
at ConfigChain._resolve (/Users/.jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/node/lib/node_modules/npm/node_modules/config-chain/index.js:281:34)
at ConfigChain.add (/Users/.jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/node/lib/node_modules/npm/node_modules/config-chain/index.js:259:10)
at Conf.add (/Users/.jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/node/lib/node_modules/npm/lib/config/core.js:338:27)
at Conf.<anonymous> (/Users/.jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/node/lib/node_modules/npm/lib/config/core.js:314:25)
internal/bootstrap/switches/does_own_process_state.js:129
cachedCwd = rawMethods.cwd();

Use the dir step to switch the directory and execute the commands in that context:
pipeline {
agent any
tools {nodejs "node"}
stages {
stage('Tests') {
steps {
dir('users/tests/') { // <<------------
sh 'npm run shopfloor.shopfloor'
}
}
}
}
}

Please try once using double quotes.
dir("folder")
in groovy Single quotes are a standard Java String while Double quotes are a templatable String.

Related

SonarQube Access denied in Jenkins Pipeline

I'm trying to set up my Jenkins Pipeline to work along with SonarQube, However at the building stage Im getting the following error message:
/var/jenkins_home/workspace/practica3/node_modules/sonar-scanner/bin/sonar-scanner: exec: line 59: : Permission denied
I have the next Jenkins pipeline file:
pipeline {
agent {
docker {
image 'node:17-alpine3.14'
args '-p 3001:3000'
}
}
stages {
stage('Build') {
steps {
sh 'npm install'
withSonarQubeEnv('SonarQube'){
sh "npm install sonar-scanner"
sh "npm run sonar"
}
}
}
stage('Test') {
steps {
sh 'npm run test'
}
}
}
}
My sonar-project.properties looks like this:
sonar.projectKey=nodejs-app
sonar.projectName=nodejs-app
sonar.projectVersion=1.0
sonar.sourceEncoding=UTF-8
sonar.host.url=http://localhost:9000
sonar.login=MyToken
sonar.javascript.lcov.reportPaths=coverage/lcov.info
Any Ideas? I will appreciate it.

Jenkins parallel stages - enoent ENOENT: no such file or directory

I am having a problem running some stages in parallel across different agents/nodes in Jenkins. I am creating stages dynamically from a list of available agents with the following code:
// Create empty collection to store parallel stages:
def parallelStages = [:]
// Define list of agents to be used for cypress parallel stages:
agents = [
"agent1",
"agent2",
...
]
// Add as many parallel stages as defined in agents list:
agents.eachWithIndex { label, index ->
parallelStages["Parallel Stage ${index + 1}"] = {
stage("Parallel Stage ${index + 1}") {
node(label) {
sh 'npm install --silent'
sh 'npm start & npx wait-on http://localhost:3000'
sh "npm run another_command"
}
}
}
}
Then I'm using these stages in a parallel block:
pipeline {
agent {
node {
label 'agent1'
}
}
stages {
stage('first-non-parallel-stage'){
steps {
sh 'npm install --silent'
sh 'npm run lint'
sh 'npm run build'
sh "npm run storybook:build"
sh 'npm run test -- --watchAll=false'
}
}
stage ('Parallel stuff'){
steps {
script {
parallel parallelStages
}
}
}
}
}
This is working. However, for the stage on agent1, I get the following errors in the Jenkins log:
+ npx wait-on http://localhost:3000
+ npm start
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /home/vine/workspace/tend-multibranch_jenkins-testing#3/package.json
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/home/vine/workspace/tend-multibranch_jenkins-testing#3/package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent
Some details that might be pertinent, but I'm not sure:
Prior to running the parallel stage, you can see I'm running a first-non-parallel-stage, on the agent that is having problems - could that be related? I don't have problems in first-non-parallel-stage, just in the parallel block on that agent. Shouldn't I be able to reuse agent1 in my parallel block after first-non-parallel-stage is done?
I don't get this issue when I use a repetetive verbose parallel block, i.e. instead of creating a function that populates a collection with stage blocks, I write them out by hand, like this:
parallel {
stage { ...stage_code }
stage { ...stage_code }
stage { ...stage_code }
}
But obviously this is verbose and doesn't lend to adding more nodes easily.
Why might this be happening?
The error occurs at the npm side as it is not able to find the file.May be would be a good idea to add npm init which creates the package.json file or delete the package-lock.json file after the non-parallel stage execution is done, so that when you enter the parallel block everything is clean. More details about this is available here : StackOverflow Answer
Thanks to comments from Noam Hemler and Altaf, I figured this out.
The crucial issue was that npm could indeed not find my project. What was being missed in some of the comments is the workspace should be cleaned before or after running the job, but the git repo scm must also be checked out fresh before trying to run any npm commands. I created this setup function:
def setup(){
// clean workspace and do a fresh checkout
deleteDir()
git credentialsId: 'id', url: 'url'
sh 'git checkout ' + env.Branch_Name
}
And now at the start of each stage:
// Add as many parallel stages as defined in agents list:
agents.eachWithIndex { label, index ->
parallelStages["Parallel Stage ${index + 1}"] = {
stage("Parallel Stage ${index + 1}") {
node(label) {
setup()
sh 'npm install --silent'
sh 'npm start & npx wait-on http://localhost:3000'
sh "npm run another_command"
}
}
}
}
And I'm using the setup function before any steps on any other agent too, so when a stage starts, it always cleans the space, pulls a fresh copy of the code, and begins from there. Seems to be working consistently.

jenkins pipeline script to deal module in subdirectory

I have a git url maven project which I want to only deal one of its submodule.
I write in pipeline script :
...
stage("mvn build") {
steps {
script {
sh "mvn package -DskipTests=true"
}
}
}
error arise: The goal you specified requires a project to execute but there is no POM in this directory (/xx/jenkins/workspace/biz-commons_deploy). so I add command :
sh "cd cmiot-services/comm" # subdir of biz-commons_deploy
def PWD = pwd();
echo "##=${PWD} "
sh "mvn package -DskipTests=true"
not work, print ##=/root/.jenkins/workspace/biz-commons_deploy, the error is the same as before .
how can I solve this problem and why the echo and error use different user space?
I make it using sh "mvn -f cmiot-services/comm/pom.xml package -DskipTests=true",still not know where this two user path come from and why sh cd not work.
steps {
sh '''
# list items in current directory to see where is your pom.xml
ls -l
# run job by comment out following two lines, if you don't know the
# relative path of folder where pom.xml insides exactly
cd <folder where pom.xml insides>
mvn package -DskipTests=true
'''
}
As Yong answered, every sh steps are independent, imagine Jenkins is opening a new ssh connection on your slave each time.
For your script, instead of a workaround with sh, why not using build in dir step ?
Something like this should do it :
stage("mvn build") {
steps {
script {
dir('cmiot-services/comm') {
sh "mvn package -DskipTests=true"
}
}
}
}
when you are executing Jenkins Pipline, the current directory is the Jenkins workspace directory.
You can add a step to clone the repo that your code is in (granted that the environment you are running the Jenkins instance is able to connect to your repo and clone).
You can then navigate into the directory that has the pom.xml. And finally execute the maven command.
...
stage("Clone Repo") {
steps {
script {
sh "git clone ssh://git#bitbucket.org:repo/app.git"
}
}
}
stage("mvn build") {
steps {
script {
sh "cd app/"
sh "pwd"
sh "mvn package -DskipTests=true"
}
}
}

filesystem scm load stuck in jenkinfile-runner

I need to run jenkinsfile via the jenkinsdile-runner.
My jenkinsfile contains load shared library via filesystem scm plugin.
pipeline {
agent any
stages {
stage('Load Library') {
steps {
library identifier: 'my#TestCase',
retriever: legacySCM(
filesystem(clearWorkspace: false, copyHidden: false, path: "/workspace/my"))
}
}
stage('Test') {
steps {
my_method_to_run a: "aaaa"
}
}
}
}
Via execution the load shared lib is stuck.
Loading library my#TestCase
FSSCM.checkout /workspace/my_shared_library to /tmp/jenkinsfileRunner.tmp/jfr5221246900865917223.run/workspace/job#libs/my
I can't find any errors.
What can be the problem?
You can see jira ticket
I found WA.
Before I call the library command I manually create the /tmp/jenkinsfileRunner.tmp/jfr408537468992298463.run/workspace/job#libs folder and copy files to there.
After it my jenkinsfile run successfully via docker.
stage('Load Library') {
steps {
sh "echo 'WA - when running via docker the load library stuck, do the preparation manually'"
sh "mkdir -p ${WORKSPACE}/../job#libs/"
sh "rm -rf /workspace/my_shared_library/.git"
sh "cp -r /workspace/my_shared_library ${WORKSPACE}/../job#libs"
library identifier: 'my_shared_library#main',
retriever: legacySCM(
filesystem(clearWorkspace: false, copyHidden: false, path: '/workspace/my_shared_library'))
}
}

Pipeline step having trouble resolving a file path

I am having trouble getting a shell command to complete in a stage I have defined:
stages {
stage('E2E Tests') {
steps {
node('Protractor') {
checkout scm
sh '''
npm install
sh 'protractor test/protractor.conf.js --params.underTestUrl http://192.168.132.30:8091'
'''
}
}
}
}
The shell command issues a protractor call which takes a config file argument, but this file fails to be found when protractor tries to retrieve it.
If I take a look at the workspace directory for where the repo is checked out to from the checkout scm step I can see the test directory is present with the config file present the sh step is referencing.
So I'm unsure why the file cannot be found.
I thought about trying to verify the files that can be seen around the time the protractor command is being issued.
So something like:
stages {
stage('E2E Tests') {
steps {
node('Protractor') {
checkout scm
def files = findFiles(glob: 'test/**/*.conf.js')
sh '''
npm install
sh 'protractor test/protractor.conf.js --params.underTestUrl http://192.168.132.30:8091'
'''
echo """${files[0].name} ${files[0].path} ${files[0].directory} ${files[0].length} ${files[0].lastModified}"""
}
}
}
}
But this doesnt work, I dont think findFiles can be used inside a step?
Can anyone offer any suggestions about what may be going on here?
Thanks
to do the debugging you were attempting (to see if the file is actually there) you could wrap the findFiles in a script (making sure your echo is before the step that fails) or use a basic find in an "sh" step like this:
stages {
stage('E2E Tests') {
steps {
node('Protractor') {
checkout scm
// you could use the unix find command instead of groovy's findFiles
sh 'find test -name *.conf.js'
// if you're using a non-dsl-step (like findFiles), you must wrap it in a script
script {
def files = findFiles(glob: 'test/**/*.conf.js')
echo """${files[0].name} ${files[0].path} ${files[0].directory} ${files[0].length} ${files[0].lastModified}"""
sh '''
npm install
sh 'protractor test/protractor.conf.js --params.underTestUrl http://192.168.132.30:8091'
'''
}
}
}
}
}

Resources