To learn how to manipulate Docker images from within Jenkins, I am reading this link.
What is a "rule to make a target" in Docker? The simple example below is failing because there is "no rule to make a target". What does this mean in Docker?
The Error And The Code That Triggers The Error
The sh 'make test' line of code in a Jenkinsfile from the link above is throwing an error when run inside the following block:
testImage.inside {
sh "whoami"
sh 'make test'
}
The actual error that Jenkins throws when trying to interpret the sh 'make test' line of code is:
make test— Shell Script<1s
[ple-dockere-containered-app-WWNVRTE6XFKMI4JPEVK2F2U3HOGDZICATW6XBFM2IQUW5PAG5FWA] Running shell script
+ make test
make: *** No rule to make target 'test'. Stop.
The complete Jenkinsfile is:
node {
// Clean workspace before doing anything
deleteDir()
try {
stage ('Clone') {
checkout scm
}
stage ('Build') {
def testImage = docker.build("test-image", "./app")
testImage.inside {
sh "whoami"
sh 'make test'
}
}
} catch (err) {
currentBuild.result = 'FAILED'
throw err
}
}
Note that the make test command is being run inside the container.
Related
I created a Jenkins pipeline that runs dockerize the frontend app, build it and run playwrite test cases.
My problem is that, the running tests stage doesn't move to the next step after running all tests.
Jenkins file:
#!groovy
pipeline {
agent any
stages {
stage('Checkout') {
steps {
echo 'Clean workspace'
cleanWs()
echo 'Checking out the PR'
checkout scm
}
}
stage('Build') {
steps {
echo 'Destroy Old Build'
echo 'Building'
sh 'make upbuild_d'
}
}
stage('Lint') {
steps {
echo 'Checking Lint'
sh 'make lint'
}
}
stage('Test') {
steps {
echo 'Running Tests ...'
sh 'make test-e2e'
}
}
}
// [StagePost] Clean after finishing
post {
always {
echo '## BEGIN ALWAYS BLOCK ##'
echo 'Destroy Build'
sh 'make destroy'
cleanWs()
echo '## END ALWAYS BLOCK ##'
}
}
}
Here is the make test-e2e in Makefile
test-e2e:
docker exec my-container bash -c 'npm run test:e2e'
And this is the test:e2e script npx playwright test --project=chromium
How can Jenkins detect that all tests are already run to execute the post steps?
This issue occurred because of this line in playwright.config.js reporter: 'html'.
This results in trying to open the test report in a browser that requires a GUI which isn't found inside the container, so the process hangs. It is fixed by updating the reporter config as reporter: [['html', { open: 'never' }]]
I would like to install maven and npm via docker agent using Jenkins declarative pipeline. But When I would like to use below script Jenkins throws an error as below. It might be using agent none but how can I use node with docker agent via declarative pipeline jenkins.
ERROR: Attempted to execute a step that requires a node context while
‘agent none’ was specified. Be sure to specify your own ‘node { ... }’
blocks when using ‘agent none’.
I try to set agent any but this time I received an error "Still waiting to schedule task
Waiting for next available executor"
pipeline {
agent none
// environment{
proxy = https://
// stable_revision = sh(script: 'curl -H "Authorization: Basic $base64encoded"
// }
stages {
stage('Build') {
agent {
docker { image 'maven:3-alpine'}
}
steps {
sh 'mvn --version'
echo "$apigeeUsername"
echo "Stable Revision: ${env.stable_revision}"
}
}
stage('Test') {
agent { docker { image 'maven:3-alpine' image 'node:8.12.0' } }
environment {
HOME = '.'
}
steps {
script{
try{
sh 'npm install'
sh 'node --version'
//sh 'npm test/unit/*.js'
}catch(e){
throw e
}
}
}
}
// stage('Policy-Code Analysis') {
// steps{
// sh "npm install -g apigeelint"
// sh "apigelint -s wiservice_api_v1/apiproxy/ -f codeframe.js"
// }
// }
stage('Promotion'){
steps{
timeout(time: 2, unit: 'DAYS') {
input 'Do you want to Approve?'
}
}
}
stage('Deployment'){
steps{
sh "mvn -f wiservice_api_v1/pom.xml install -Ptest -Dusername=${apigeeUsername} -Dpassword=${apigeePassword} -Dapigee.config.options=update"
//sh "mvn apigee-enterprise:install -Ptest -Dusername=${apigeeUsername} -Dpassword=${apigeePassword} "
}
}
}
}
Basically your error message tells you everything you need to know:
ERROR: Attempted to execute a step that requires a node context while
‘agent none’ was specified. Be sure to specify your own ‘node { ... }’
blocks when using ‘agent none’.
so what is the issue here? You use agent none for your pipeline which means you do not specify a specific agent for all stages. An agent executes a specific stage. If a stage has no agent it can't be executed and this is your issue here.
The following 2 stage have no agent which means no docker-container / server or whatever where it can be executed.
stage('Promotion'){
steps{
timeout(time: 2, unit: 'DAYS') {
input 'Do you want to Approve?'
}
}
}
stage('Deployment'){
steps{
sh "mvn -f wiservice_api_v1/pom.xml install -Ptest -Dusername=${apigeeUsername} -Dpassword=${apigeePassword} -Dapigee.config.options=update"
//sh "mvn apigee-enterprise:install -Ptest -Dusername=${apigeeUsername} -Dpassword=${apigeePassword} "
}
}
so you have to add agent { ... } to both stage seperately or use a global agent like following and remove the agent from your stages:
pipeline {
agent {
docker { image 'maven:3-alpine'}
} ...
For further information see guide to set up master and agent machines or distributed jenkins builds or the official documentation.
I think you meant to add agent any instead of agent none, because each stage requires at least one agent (either declared at the top for the pipeline or per stage).
Also, I see some more issues.
Your Test stage specifies two images for the same stage.
agent { docker { image 'maven:3-alpine' image 'node:8.12.0' } } although, your stage is executing only npm commands. I believe only one of the image will be downloaded.
To clarify bit more on mkemmerz answer, your Promotion stage is designed correctly. If you plan to have an input step in the pipeline, do not add an agent for the pipeline because input steps block the executor context. See this link https://jenkins.io/blog/2018/04/09/whats-in-declarative/
I would like to know how to continue with a build only when a file contains specific text?
I want the build to fail if the text is incorrect, otherwise continue with build.
update your script to return a nonzero exit status when the file doesn't contain the text. run your shell script via an sh step like this:
sh '/path/to/your/script_that_checks_another_file_for_certain_text.sh'
full pipeline:
pipeline {
agent { label 'docker' }
stages {
stage('build') {
steps {
sh '/path/to/your/script_that_checks_another_file_for_certain_text.sh'
echo 'this will not happen if the above script returns a bad exit status'
}
}
}
}
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'
'''
}
}
}
}
}
When our browser based tests fail, we take a screenshot of the browser window to better illustrate the problem. However, I don't understand how to archive them in my pipeline, because the pipeline stops after the failure. Same for the junit.xml, I'd also like to use it in error cases.
I've checked, the screenshots are generated and stored correctly.
My definition looks like this (irrelevant things mostly trimmed):
node {
stage('Build docker container') {
checkout([$class: 'GitSCM', ...])
sh "docker build -t webapp ."
}
stage('test build') {
sh "mkdir -p rspec screenshots"
sh "docker run -v /var/jenkins_home/workspace/webapp/rspec/junit.xml:/myapp/junit.xml -v /var/jenkins_home/workspace/webapp/screenshots:/myapp/tmp/capybara -v webapp bundle exec rspec"
}
stage('Results') {
junit 'rspec/junit*.xml'
archive 'screenshots/*'
}
}
You can use simple Java try/catch to avoid pipeline failure on test failure, or Jenkins catchError like this :
node {
catchError {
// Tests that might fail...
}
// Archive your tests artifacts
}
From here, you can use the post section in your pipeline:
pipeline {
agent any
stages {
stage('Build') {
...
}
stage('Test') {
...
}
}
post {
always {
archive 'build/libs/**/*.jar'
}
}
}