Jenkinsfile - calling multiple groovy scripts - jenkins

We have our shared libraries on gitlab called mainlibrary and it has a lot of groovy files.
Example in mainlibrary gitlab repo we have the following files.
startup_pipeline.groovy
cleanup_pipeline.groovy
In one of our Jenkins job we need to include multiple groovy files in the Jenkinsfile. Is this possible?
This is how the Jenkinsfile looks like:
#Library('mainlibrary')_
startup_pipeline(email:'example#example.com')
Can I include the second groovy function file into this Jenkinsfile like this?
#Library('mainlibrary')_
startup_pipeline(email:'example#example.com'),
cleanup_pipeline(email:'example#example.com')

Considering the cleanup_pipeline.groovy is located under the vars folder and your code already has a complete declaration inside, your example may work, and the second file can be included. The only modification is the extra comma:
#Library('mainlibrary')_
startup_pipeline(email:'example#example.com')
cleanup_pipeline(email:'example#example.com')
Or can be under src and imported, but I never used this approach.
Usually, I keep the main logic inside vars, and other complex things go to src.
Based on Jenkins documentation, see more in Directory structure and Defining custom steps.
Video step by step building a shared library, you can build and test something similar if you are not sure about the structure.

Related

Sharing map of settings across groovy script files

Currently I am having one jenkinsfile which in process of development has grown to huge size. Mostly it contains some groovy methods used in pipeline, but I would like to place groovy scripts in separate files in other repository and than checkout every time when I need those scripts. Those works on a maps of settings which is commonly used in methods. How can I share those maps in script files? I can't use shared libraries because of security purposes.
An alternative to shared library is the load step, which loads and evaluates the given groovy script file.
settings.groovy:
[
answer: 42,
question: 'tbd'
]
main.groovy:
def settings = load 'settings.groovy'
echo "The answer is: ${settings.answer}"
Output:
The answer is: 42

Is there a way to overwrite a value contained within a config.properties file via Jenkins?

Is there a way to overwrite a value contained within a config.properties file via Jenkins?
I have the following config.properties file contained within my automation framework:
browser=chrome
url=http//www.example.com
If the value of chrome get changed to firefox then all tests will now execute within firefox browser.
I can manually change this value by directly accessing the config.properties file but can the value get altered via jenkins?
I use the Pipeline Utility Steps plugin to read properties files, and it looks like it can write a few other types of files, but not properties files.
It seems to me that you want to make this change in this file so you can run some tests first in one browser, then in another. If this is the case, I think a better way to handle this is to try to get your tests to point to different files. This is a little cleaner, and allows things like parallel execution and when you find that another thing needs to change in the future, you won't be writing so many things to the file in a script, which gets a little error prone.
If you can't make your tests execute against a different properties file, you could have a copy of each file you need, and then copy them to them appropriate filename to execute your tests.
But maybe I made poor assumptions as to your setup here. ;)
Yes.
You can create a build parameter as $browser to accept the value say "firefox" and using sed inside "execute shell", replace the value in config.properties.
Once done, execute your scripts.
This is just overview as you have not posted details about your config.properties file, its location, if you are using Jenkins jobs or jenkinsfile/pipeline etc.

Injecting more than one properties file into a Jenkins job

Right now I'm using EnvInject plugin to insert my environment variables through a properties file into my Jenkins job.
However, now I have a second job which needs the same environment variables as the first job and than some more additional variables which I would like to load via another properties file.
I know, there is a possibility to insert the values via Properties Content Edit field of the EnvInject-plugin, but I would like to keep it in a file, so it can be shared between jobs. But there seems to be no possibility to add a second properties file to EnvInject-plugin.
Is there any way to inject more than one properties file into a job or any other plugin, that could handle my scenario?
There is a simple way to get around the limitation you have.
You should load each file in the Build section, as a build step.
Use the Inject environment variables build step, and load each file you want. You can add multiple files by setting up multiple build steps of this type.
This works well for me on a similar need.
You can use Config File Provider Plugin to config some shell scripts.
You can add multiple files and then execute them.

How to get custom metrics into jelly for email-ext?

Using Jenkins and email-ext, I have copied the "html" template and made it look the way I want for our build mail.
What I'd like to do now is get some custom metrics in the build mail. Specifically, our build jobs call a number of PHP scripts that perform work. One of these scripts creates a bunch of files in a directory. I'd like to have our build mail have an output line like:
The super cool script created 8 files for your enjoyment.
The PHP script knows it created 8 files, of course. How could that script get that number in a place where Jelly could know it and output it? Is there a way to have Jenkins store such things and make them available to the Jelly template?
Use the EnvInject Plugin https://wiki.jenkins-ci.org/display/JENKINS/EnvInject+Plugin
Set the Enviroment variable in your PHP script
Output the Environment Variable in your Email-Ext
If the files are created in a specific directory - so counting the number of files in a folder is good enough -, you could try something like this in your jelly template (note: I didn't test it):
<j:set var="filesCreated" value="${build.getWorkspace().child('path/to/result/dir').list().size()}"/>
The super cool script created ${filesCreated} files for your enjoyment.

aliasing jenkins artifact URLs

Jenkins artifact URLs allow abstracting the "last successful build", so that instead of
http://myjenkins.local/job/MyJob/38/artifact/build/MyJob-v1.0.1.zip
we can say
http://myjenkins.local/job/MyJob/lastSuccessfulBuild/artifact/build/MyJob-v1.0.1.zip
Is it possible to abstract this further? My artifacts have their version number in their filename, which can change from build to build. Ideally I'd like to have a some kind of "alias" URL that looks like this:
http://myjenkins.local/job/MyJob/lastSuccessfulBuild/artifact/build/MyJob-latest.zip
MyJob-latest.zip would then resolve to MyJob-v1.0.1.zip.
If Jenkins itself can't do this, perhaps there's a plugin?
Never seen any such plugin, but Jenkins already has a similar functionality built-in.
You can use /*zip*/filename.zip in your artifact path, where filename is anything you choose. It will take all found artifacts, and download them in a zipfile (you may end up with a zip inside a zip, if your artifact is already a zip file)
In your case, it will be:
http://myjenkins.local/job/MyJob/lastSuccessfulBuild/artifact/build/*zip*/MyJob-latest.zip
This will get you the contents of /artifact/build/ returned in zipped archive with name MyJob-latest.zip. Note that if you have more than just that zip file in that directory, other files will be returned too.
You can use wildcards in the path. A single * for a regular wildcard, a double ** for skipping any number of preceding directories.
For example, to get any file that starts with MyJob, ends with .zip, and to look for it in any artifact directory, you could use:
/lastSuccessfulBuild/artifact/**/MyJob*.zip/*zip*/MyJob-latest.zip
Edit:
You cannot do something like this without some form of a container (a zip in this case). With the container, you are telling the system:
Get any possible [undetermined count] wildcard match and place into this container, then give me the container. This is logical and possible, as there is only one single container, whether it is empty or not.
But you cannot tell the system:
Give me a link to a specific single file, but I don't know which one or how many there are. The system can't guarantee that your wildcards will match one, more than one, or none. This is simply impossible from a logic perspective.
If you need it for some script automation, you can unzip the first level zip and be still left with your desired zipped artifact.
If you need to provide this link to someone else, you need an alternative solution.
Alternative 1:
After your build is complete, execute a post-build step that will take your artifact, and rename it to MyJob-latest.zip, but you are losing versioning in the filename. You can also chose to copy instead of rename, but you end up with double the space used for storing these artifacts.
Alternative 2 (recommended):
As a post-build action, upload the artifact to a central repository. It can be Artifactory, or even plain SVN. When you upload it, it will be renamed MyJob-latest.zip and the previous one would be overwritten. This way you have a static link that will always have the latest artifact from lastSuccessfulBuild
There is actually a plugin to assign aliases to build you've run, and I have found it pretty handy: the Build Alias Setter Plugin.
You can use it for instance to assign an alias in the form of your own version number for a build, instead (or rather in addition) to the internal Jenkins-assigned build number.
I found that it is usually most practical to use it in conjunction with the EnvInject plugin (or your favorite variant): you would export an env variable (e.g. MY_VAR=xyz) with a value to the target version or moniker, and then use the form ${ENV,var="myvar"} in the "Token Macro alias" config that the plugin provides in your job config.
You can also use it to assign aliases in the form of "lastSuccesful" if you have such a need, which allows you to distinguish between different types of successful (or other state) builds.
Wait thee's more! You can also use the /*zip*/ trick in conjunction with the alias setter as well.

Resources