Access variable in Jenkins Pipeline Post Action - node.js

When I start a job and run a command
npm run e2e_test,
it successfully executed. I set a variable let say REPORT_URL using process.env.REPORT_URL . Now in Jenkins post action I would like to access this variable REPORT_URL.
This url is construed at runtime so it cannot be set before the job. Once the job completed all the stages, it reaches in post section and here if I mention like
echo "${REPORT_URL}" or echo "${env.REPORT_URL}"
I get an exception MissingProperty-: NO such property: REPORT_URL for class WorkflowScript.
I tried to create a variable in .env file with same name but didn't get success.
So I can access a variable in post build in Jenkins pipeline which set in code using process.env.XXXX?

Answer is based on: Share variables between Jenkins pipeline stages
Create a global Jenkins variable and initialize it with a dummy value like null.
Pass any value to the variable
Access the global variable in your post stage.

Related

Jmeter ${__setProperty()} Not working across multiple threads in the same thread group

I am trying to do setproperty across multiple threads in the same threadgroup, the postprocessor set new variable using setproperty, so that It can be accessed across multiple threads.
In Beanshell preprocessor, I'm having below line of code.
${__setProperty("url", "youtube")};
Under thread Group I'm having Beanshell post processor, having below one line in postprocessor.
${__setProperty("url", "google")};
under thread group, I have Http Sampler, in hostname field I have given ${__property(url)}.com
The Aim is, when it executes first time, the URL will be google.com and when first threads complete than
the URL becomes youtube.com
But the setProperty only set google, and the second one in postprocessor was not working.
Refer the below Image for details, it shows how I created the element in Jmeter.
enter image description here
Note: This was just a sample use case, but I have complex example, but answering to this question will help me to add the logic in complex script.
Thanks
So is the goal that the very first thread to complete will change the URL for all subsequently created threads?
My understanding of the documentation is that you can't change the value of a property inside the thread-group:
Properties can be referenced in test plans - see Functions - read a property - but cannot be used for thread-specific values.
(see http://jmeter.apache.org/usermanual/test_plan.html#properties)
My assumption is that each thread in a thread-group gets a copy of the properties. If you change the value of the property inside the thread group, then you are actually changing the copy for that particular thread. Since you are changing it in the post-processor, the thread is very likely just about to be disposed, resulting in your change being lost. After disposal a new thread is created but with the original value of the property.
So what you need to do is figure out how to change the value outside of the thread-group.
I have done something similar in my own tests whereby I am changing the value of a property in the middle of the test, and the value is picked up immediately by all of the active thread-groups, resulting in each new thread created from that point forward getting the new value. I am doing this by using the Beanshell Server: https://jmeter.apache.org/usermanual/best-practices.html#beanshell_server
In my specific case I use jenkins job that calls a shell-script which connects to the beanshell-service running on the local-host:
java -jar ${jmeter_home}/apache-jmeter-5.0/lib/bshclient.jar localhost 9000 ${test_plan_home}/update_Prop.bsh "${property}" "${value}"
where my update_prop.bash file is simply:
import org.apache.jmeter.util.JMeterUtils;
JMeterUtils.getJMeterProperties().setProperty(args[0],args[1]);
You would not need to use Jenkins or anything like that, though - if you setup your JMeter Process to include the Beanshell-server (see the link above) then you can simply replace the code in your post-processor:
${__setProperty("url", "google")};
with the code to connect to the beanshell server and execute that command there instead:
exec("./updateprop.bash url google");
JMeter properties are global therefore once you set the property it is available for all threads
Each JMeter thread (virtual user) executes Samplers. Pre and Post processors are obeying JMeter Scoping Rules Looking into your test plan the execution order is following:
Beanshell PreProcessor
HTTP Request Sampler
Beanshell PostProcessor
therefore HTTP Request sampler will never hit youtube (unless you run into a race condition due to concurrency) because PreProcessor will set the URL back to google
It is recommended to use JSR223 Test Elements and Groovy language for scripting since JMeter 3.1
It is NOT recommended to inline JMeter Functions and/or variables into scripts, you need to either use "Parameters" section or go for code-based equivalents instead so you need to replace this line:
${__setProperty("url", "youtube")};
with this one:
props.put("url", "youtube");

Read webhook payload in Gitlab CI

I have a project (PROJECT_A) that is triggered through a webhook, and expects the variable $PRODUCT to be set. Its value is used to trigger a certain path in the build. The job in the .gitlab-ci.yml file looks like this:
deploy:
stage: publish
script:
- ./generate_doc.sh $PRODUCT
A webhook call looks like this:
http://<GITLAB_URL>/api/v4/projects/710/ref/master/trigger/pipeline?token=<TOKEN>&variables[PRODUCT]=<PRODUCT>
I call this trigger through a webhook from other projects, including PROJECT_B.
So I manually filled in the desired value in the respective webhooks, e.g. for PROJECT_B:
http://<GITLAB_URL>/api/v4/projects/710/ref/master/trigger/pipeline?token=<TOKEN>&variables[PRODUCT]=PROJECT_B
When the pipeline in PROJECT_A is triggered, $PRODUCT has the value PROJECT_B, as expected.
I would like to parameterize the pipeline further and take, among others, the commit message into account. All the information I need is apparently provided in the webhook payload.
Is there a built-in way to read this payload in a pipeline? Or alternatively, put contents of the payload into a variable in the webhook like this:
http://<GITLAB_URL>/api/v4/projects/710/ref/master/trigger/pipeline?token=<TOKEN>&variables[COMMIT_REF]=???
I have found discussions about doing parameterized Jenkins builds using the webhook payload, including this related question. There is also a similar question in the Gitlab forum, without any answer.
Is there a way to do access that payload in a Gitlab CI pipeline? I could probably extract the provided values with a jq call, but how can I get the Json in the first place?
If you run compgen -v to show the environment variables when triggering the pipeline in the UI (without JSON payload) you get 3 fewer lines in your job log than when POSTing a JSON payload.
The additional variables are:
CI_BUILD_TRIGGERED
CI_PIPELINE_TRIGGERED
TRIGGER_PAYLOAD
If you print their values out and re-run the pipeline:
echo CI_BUILD_TRIGGERED=$CI_BUILD_TRIGGERED
echo CI_PIPELINE_TRIGGERED=$CI_PIPELINE_TRIGGERED
echo TRIGGER_PAYLOAD=$TRIGGER_PAYLOAD
You get (for username YOUR_USER_NAME and repo name YOUR_REPO_NAME)
CI_BUILD_TRIGGERED=true
CI_PIPELINE_TRIGGERED=true
TRIGGER_PAYLOAD=/builds/YOUR_USER_NAME/YOUR_REPO_NAME.tmp/TRIGGER_PAYLOAD
So as you can see the payload is stored as TRIGGER_PAYLOAD in a temporary directory suffixed .tmp, which re-running the pipeline and printing it out (cat) shows it contains the payload, in my case that’s JSON.

Azure Data Factory v2: Activity execute pipeline output

Is there a way to reference the output of an executed pipeline in the activity "Execute pipeline"?
I.e.: master pipeline executes 2 pipelines in sequence. The first pipeline generates an own created run_id that needs to be forwarded as a parameter to the second pipeline.
I've read the documentation and checked that the master pipeline log the output of the first pipeline, but it looks like that this is not directly possible?
We've used until now only 2 pipelines without a master pipeline, but we want to re-use the logic more. Currently we have 1 pipeline that calls the next pipeline and forwards the run_id.
ExecutePipline currently cannot pass anything from its insides to its output. You can only get the runID or name.
For some weird reason, the output of ExecutePipeline is returned not as a JSON object but as a string. So if you try to select a property of output like this #activity('ExecutePipelineActivityName').output.something then you get this error:
Property selection is not supported on values of type 'String'
I found that I had to use the following to get the run ID:
#json(activity('ExecutePipelineActivityName').output).pipelineRunId
The execute pipeline activity is just another activity with outputs that can be captured by other activities. https://learn.microsoft.com/en-us/azure/data-factory/control-flow-execute-pipeline-activity#type-properties
If you want to use the runId of the pipeline executed previosly, it would look like this:
#activity('ExecutePipelineActivityName').output.pipeline.runId
Hope this helped!

Hybris -> how to create cronjob with execute beanshell script?

I have a beanshell script and I would like it to automate.
I need to create cronjob and add my beanshell code to it.
Maybe someone do that think?
Is anyone know how to do this?
or how to match my script with cronjob?
The answer is actually given in Cronjob scripting documentation.
In a nutshell, you will use dynamic scripting to create the cronjob instead of using the slow old-fashioned way.
Concept
There are three new objects used (quoted from doc):
Script - the item type where the script content is stored (a separate deployment table)
ScriptingJob - a new ServicelayerJob item, which contains additionally the scriptURI (consequently, the stored script can be
found at runtime from different locations (classpath, db, etc..)
ScriptingJobPerformable - the spring bean assigned to every ScriptingJob instance; it implements the usual perform() method (like
for any other cronjob). This is where the "scripted" cronjob logic is
executed
How to use Cronjob scripting
First step - save your Script instance in the database. For this example I've used a code from http://www.beanshell.org/manual/quickstart.html
Note: you can create script with Groovy, BeanShell ad JavaScript
INSERT_UPDATE Script; code[unique=true];content;scriptType(code)
;myBshScript;"foo = ""Foo"";
four = (2 + 2)*2/2;
print( foo + "" = "" + four ); // print() is a BeanShell command
// Do a loop
for (i=0; i<5; i++)
print(i);
// Pop up a frame with a button in it
button = new JButton( ""My Button"" );
frame = new JFrame( ""My Frame"" );
frame.getContentPane().add( button, ""Center"" );
frame.pack();
frame.setVisible(true);";BEANSHELL
Don't forget to escape " in the script with an other " (Impex restriction).
Second step - create a ScriptingJob that use the previously created Script
INSERT_UPDATE ScriptingJob; code[unique=true];scriptURI
;myBshDynamicJob;model://myBshScript
model://myBshScript is used to retrieve a Script stored in the DB
Third step - create the CronJob
INSERT_UPDATE CronJob; code[unique=true];job(code);singleExecutable;sessionLanguage(isocode)
;myBshDynamicCronJob;myBshDynamicJob;true;en
Optional step - create a trigger for the CronJob
INSERT_UPDATE Trigger;cronjob(code)[unique=true];cronExpression
;myBshDynamicCronJob;0 0 0/1 1/1 * ? *
This executes the cronjob every hour.
Execute the CronJob by script
In the hac scripting tab, choose Groovy and run this in commit mode.
def dynamicCJ = cronJobService.getCronJob("myBshDynamicCronJob")
cronJobService.performCronJob(dynamicCJ,true)
After running the Script you should have this displayed
And in the console
INFO [hybrisHTTP27] (myBshDynamicCronJob) [ScriptingJobPerformable] Foo = 4
0
1
2
3
4
In Hybris, go to HMC> System> CronJobs> Search your created cronjob or create a new cronjob> Time Schedule tab> Trigger> Create Trigger.
From this Trigger tab window, you can schedule the interval eg. daily, weekly, etc. Also you can set the start time and frequency.
You can also do this trigger setting via impex as below:
INSERT_UPDATE Trigger;cronJob(code)[unique=true];second;minute;hour;day;month;year;relative;active;maxAcceptableDelay
;CartRemovalJob;0;5;4;-1;-1;-1;false;true;-1
For more detailed information, have a look at this, in case you have access to Hybris Wiki.
If you have access to hybris wiki, here you can find how to create and execute a cronjob.
In order to execute bean shell, in the cronjob "perform" method you should do this:
SimpleScriptContent content = new SimpleScriptContent("beanshell", "here your beanshell script code as string");
ScriptExecutable script = scriptingLanguagesService.getExecutableByContent(content);
ScriptExecutionResult result = script.execute();
...
Here the import section:
import de.hybris.platform.scripting.engine.content.impl.SimpleScriptContent;
import de.hybris.platform.scripting.engine.ScriptExecutionResult;
import de.hybris.platform.scripting.engine.ScriptExecutable;
You should access to scriptingLanguagesService with annotation:
#Autowired
ScriptingLanguagesService scriptingLanguagesService;
I have tried below steps for the groovy script. You can try the same for the beanshell.
You have to create an instance of
Script - the item type where the script content is going to store.
ScriptingJob - a new ServicelayerJob item, which contains additionally the scriptURI
CronJob - This is where the "scripted" cronjob logic is executed
1. Create a Script
Script code: HelloScript
Script engine type: beanshell
Content: log.info("Hello");
2. Create the Scripting Job
Again from HMC/Backoffice, find ScriptinJobs and create the new instance of it. Here you have to define Code and ScriptURI like
Code: HelloScriptJob
ScriptURI: model://HelloScript
You can access this job in the next step to create the CronJob
3. Create a CronJob
From HMC/BackOffice, create an instance of cronJob. Select above-created job(HelloScriptJob) in
Job definition drops down and save the changes. Now you good to schedule/run this cronJob.
Refer detailed post cronjob-using-groovy-script-hybris

SoapUI: Using Run TestCase test step doesn't pass in context

I'm using SoapUI Pro. The SoapUI site says I should be able to set context variables and get those values at any time during the test's execution. In the help it says:
A common usage scenario is for looping or keeping track of progress by saving the corresponding counters and collections to the context and using them to control flow as required.
I can't get this to work if I'm using the out-of-the-box 'Run TestCase' test step. The called test doesn't seem to get passed the context information.
Here's a very basic example. In my originating test I put in some Groovy script that says this:
context.PassedInTest = "Is this passed in?" log.info(context.PassedInTest)
Then in my called test, I have another Groovy script that says this:
log.info(context.PassedInTest)
Upon execution of the test, the log displays: "Is this passed in?" for the originating test, but then the log displays null for the called test:
Mon Oct 27 12:59:45 EDT 2014:INFO:Is this passed in?
Mon Oct 27 12:59:56 EDT 2014:INFO:null
Is there a way to pass in the context if using the out-of-the-box 'Run TestCase' test step in SoapUI (i.e. not using Groovy script)? What am I doing wrong?
I managed to get this working, but I can't say if it's hacky or not...
Consider following project structure:
Project
|-CallingTestSuite
| |-CallingTestCase
| |-TestSteps
| |-LocalScript (Groovy TestStep)
| |-RemoteScript (Run TestCase TestStep)
|-CalledTestsuite
|-CalledTestCase
|-TestSteps
|-CalledScript (Groovy TestStep)
Now, you cannot pass (at least I didn't find a way) context of LocalScript to CalledScript.
You can, however, access the content of LocalScript from CalledScript.
LocalScript:
context.PassedInTest = "Is this passed in?"
log.info(context.PassedInTest)
CalledScript:
if (context.getProperty("#CallingTestRunContext#") != null){
log.info(context.getProperty("#CallingTestRunContext#").PassedInTest);
}
Keep in mind that it needs to be executed as CallingTestSuite, CallingTestCase, or Project, otherwise the target context won't be available.

Resources