ERROR: Could not find credentials entry with ID 'null' - jenkins

I am unable to pass credentials to Jenkins job when I try to Build with Parameters. I have written a groovy script where it deploys to different environments. Below is a code snippet where I have written in a switch case:
switch (defaults.get('pipelineStrategy')) {
case 'deployToEnv':
if (params.deployToDev) {
deployToDev(defaults, env)
}
else (params.deployToTest) {
deployToTest(defaults, env)
}
break
}
Below is the script for deployToDev.groovy
void call(Map configuration, env) {
environment {
K8S_DEV_NS_TOKEN = "dev-ns-cicd"
}
echo 'Starting deploy only pipeline'
println("executing deployToDev")
pipeline {
agent { label 'docker-kitchensink-slave' }
stages {
stage('Checkout') {
steps{
checkout scm
}
}
stage('Deploy to Dev') {
steps {
withCredentials([string(credentialsId: "$env.K8S_DEV_NS_TOKEN", variable: 'DEV_TOKEN')]) {
kubernetesDeploy(hcEnv: 'dev', hcToken: "${DEV_TOKEN}")
}
}
}
}
}
}
Below are the Jenkins build logs:
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: Could not find credentials entry with ID 'null'
Could not update commit status, please check if your scan credentials belong to a member of the organization or a collaborator of the repository and repo:status scope is selected
GitHub has been notified of this commit’s build result
Finished: FAILURE

The argument env in void call(Map configuration, env) override pipeline reserved global variable: env.
Please remove the argument env from call function.

Related

Jenkins restart a pipeline from a specific stage

I'm executing a declarative pipeline which generates stages dynamically:
pipeline{
stages{
stage("Prepare"){
script {
//logic goes here
pkg = getAllPkgsOrderToBuild()//inconsistent
for(pkg in pkgs){
generateBuildStage("$pkg")//uses stage("build $pkg") inside
generatePublishStage("$pkg")//uses stage("publish $pkg") inside
if(lastIteratation){
testing()
}
}
}
}
}
post{
always{
reportBack to: devMail
}
}
}
And I want to give to Jenkins' users the ability to restart the pipeline from the failed stage.
Any Idea?

Importing map variable to Jenkinsfile environment stage

My project has many common variables for many other projects, so I use Jenkins Shared Library and created a vars/my_vars.groovy file where I defined my variables and return Map of them:
class my_vars {
static Map varMap = [:]
static def loadVars (Map config) {
varMap.var1 = "val1"
varMap.var2 = "val2"
// Many more variables ...
return varMap
}
}
I load the Shared Library in my Jenkinsfile, and call the function in the environment bullet, as I want those variables to be as environment variables .
Jenkinsfile:
pipeline {
environment {
// initialize common vars
common_vars = my_vars.loadVars()
} // environment
stages {
stage('Some Stage') {
// ...
}
}
post {
always {
script {
// Print environment variables
sh "env"
} // script
} // always
} // post
} // pipeline
The thing is that the environment bullet gets KEY=VALUE pairs, thus my common_vars map is loaded like a String value (I can see that on sh "env").
...
vars=[var1:val1, var2:val2]
...
What is the correct way to declare those values as an environment variables?
My target to get this:
...
var1=val1
var2=val2
...
Pipeline's environment variables store only String values. That is why when you assign a map to env.common_vars variables it stores map.toString() equivalent.
If you want to rewrite key-values from a map to the environment variables, you can iterate the variables map and assign each k-v pair to something like env."$k" = v. You can do that by calling a class method inside the environment block - that way you can be sure that the environment variables are assigned no matter which stage your pipeline gets restarted from. Consider the following example:
class MyVars {
private Map config = [
var1: "val1",
var2: "val2"
]
String initializeEnvironmentVariables(final Script script) {
config.each { k,v ->
script.env."$k" = v
}
return "Initialization of env variables completed!"
}
}
pipeline {
agent any
environment {
INITIALIZE_ENV_VARIABLES_FROM_MAP = "${new MyVars().initializeEnvironmentVariables(this)}"
}
stages {
stage("Some stage") {
steps {
echo "env.var1 = ${env.var1}"
}
}
}
post {
always {
script {
sh 'printenv | grep "var[0-9]\\+"'
}
}
}
}
In this example, we use MyVars class to store some global config map (it can be a part of a shared library, here, for simplicity, it is a part of the Jenkinsfile). We use INITIALIZE_ENV_VARIABLES_FROM_MAP environment variable assignment to call MyVars.initializeEnvironmentVariables(this) method that can access env from the script parameter. Calling this method from inside environment block has one significant benefit - it guarantees that environment variables will be initialized even if you restart the pipeline from any stage.
And here is the output of this exemplary pipeline:
Running on Jenkins in /home/wololock/.jenkins/workspace/pipeline-env-map
[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Some stage)
[Pipeline] echo
env.var1 = val1
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Declarative: Post Actions)
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ grep 'var[0-9]\+'
+ printenv
var1=val1
var2=val2
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
As you can see we it sets env.var1 and env.var2 from the map encapsulated in MyVars class. Both variables can be accessed inside the pipeline step, script block or even inside the shell environment variables.
As far as I know there is no easy way to do this in declarative pipeline (e.g. in the environment directive. Instead, what you can do is to setup the environment outside of the declarative definition, like this:
my_vars.loadVars().each { key, value ->
env[key] = value
}
// Followed by your pipelines definition:
pipeline {
stages {
stage('Some Stage') {
// ...
}
}
// ...
} // pipeline
As an full example:
class my_vars {
static Map varMap = [:]
static def loadVars (Map config) {
varMap.var1 = "val1"
varMap.var2 = "val2"
// Many more variables ...
return varMap
}
}
my_vars.loadVars().each { key, value ->
env[key] = value
}
pipeline {
agent any
stages {
stage("Some stage") {
steps {
echo "env.var1 = ${env.var1}"
}
}
}
}
Which outputs the following when built:
Started by user xxx
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on yyy in /zzz
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Some stage)
[Pipeline] echo
env.var1 = val1
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
Edit; If your class (my_vars) is located in a shared library (MySharedLibrary):
library 'MySharedLibrary' // Will load vars/my_vars.groovy
my_vars.loadVars().each { key, value ->
env[key] = value
}
pipeline {
agent any
stages {
stage("Some stage") {
steps {
echo "env.var1 = ${env.var1}"
}
}
}
}
You don't have to return a map of your environment variables from your shared library. You can simply set them in a shared library method, the method will run in the same container as your pipeline.
In you shared library vars/ directory:
def setVars() {
env.var1 = "var1"
env.var2 = "var2"
env.var3 = "var3"
}
In your pipeline:
pipeline {
agent any
stages {
stage("Setup") {
steps {
script {
imported_shared_lib.setVars()
}
}
}
}
}
Others mentioned the need to preserve the environment variables even if you restart the pipeline from a certain stage. In my experiments, the variables are preserved using this method, even if the setVars() method is not called in the environment{} block.

How to pass variable from pipeline to job in Jenkins?

I need to create a unique identifier in a pipeline and then all jobs started from this pipeline should have access to this unique identifier.
I do not want to parameterize those jobs.
I thought that environment variable defined on a pipeline level will be accessible from jobs, but it isn't.
pipeline {
agent any
environment {
TEST_VAR = 'TEST_VAR'
}
stages {
stage('Stage1') {
steps {
build (job: 'job1')
}
}
}
}
You do not really need to parameterize the downstream pipelines but can still pass the variable as a parameter from the upstream and access it in the downstream.
Upstream pipeline
pipeline {
agent any
environment {
TEST_VAR = 'hello_world'
}
stages {
stage('Build-downstream-job') {
steps {
build job: 'downstream-job', parameters: [string(name: 'TEST_VAR', value: env.TEST_VAR)], wait: false
}
}
}
}
Downstream pipeline
pipeline {
agent any
stages {
stage('Get-test-var') {
steps {
println(params.TEST_VAR)
}
}
}
}
Downstream pipeline console output
[Pipeline] stage
[Pipeline] { (Get-test-var)
[Pipeline] echo
hello_world
[Pipeline] }
[Pipeline] // stage
You should try adding a '$' before TEST_VAR:
environment {
TEST_VAR = '$TEST_VAR'
}

How to get Jenkins credentials variable in all stages of my Jenkins Declarative Pipeline

How do I get Jenkins credentials variable i.e "mysqlpassword" accessible to all stages of my Jenkins Declarative Pipeline?
The below code snippet works fine and prints my credentials.
node {
stage('Getting Database Credentials') {
withCredentials([usernamePassword(credentialsId: 'mysql_creds', passwordVariable: 'mysqlpassword', usernameVariable: 'mysqlusername')])
{
creds = "\nUsername: ${mysqlusername}\nPassword: ${mysqlpassword}\n"
}
println creds
}
}
How can I incorporate the above code in my current pipeline so that mysqlusername & mysqlpassword variables are accessible to all stages across the pipeline script i.e globally.
My pipeline script layout looks like below:
pipeline { //indicate the job is written in Declarative Pipeline
agent { label 'Prod_Slave' }
environment {
STAGE_2_EXECUTED = "0"
}
stages {
stage ("First Stage") {
steps {
echo "First called in pipeline"
script {
echo "Inside script of First stage"
}
}
} // end of first stage
stage ("Second Stage") {
steps {
echo "Second stage called in pipeline"
script {
echo "Inside script of Second stage"
}
}
} // end of second stage
} //end of stages
} // end of pipeline
I m on the latest version of Jenkins.
Requesting solutions. Thank you.
You can do something like this. Here, you define you variables under environment { } and use it throughout your stages.
pipeline {
agent any
environment {
// More detail:
// https://jenkins.io/doc/book/pipeline/jenkinsfile/#usernames-and-passwords
MYSQL_CRED = credentials('mysql_creds')
}
stages {
stage('Run Some Command') {
steps{
echo "Running some command"
sh '<some-command> -u $MYSQL_CRED_USR -p $MYSQL_CRED_PSW'
}
}
}
Variables defined under environments are global to all the stages so can be used in the whole jenkinsfile.
More information about credentials() in official documentation.

Equivalent block to environment in scripted pipeline with Jenkins

I have the following pipeline:
pipeline {
agent any
environment {
branch = 'master'
scmUrl = 'ssh://git#myrepo.git'
serverPort = '22'
}
stages {
stage('Stage 1') {
steps {
sh '/var/jenkins_home/contarpalabras.sh'
}
}
}
}
I want to change the pipeline to "scripted pipeline" in order to use try / catch blocks and have better error management. However i did not find how the equivalent to environment block in official documentation.
You can use the withEnv block like:
node {
withEnv(['DISABLE_AUTH=true',
'DB_ENGINE=sqlite']) {
stage('Build') {
sh 'printenv'
}
}
}
This info is also in the official documentation : https://jenkins.io/doc/pipeline/tour/environment/#

Resources