How to pass arguments / parameters to the npm-script using npmExecuteScripts? - sap-business-technology-platform

I'm trying to run the npm-script from the Jenkins pipeline via the SAP Project Piper's npmExecuteScripts:
npmExecuteScripts:
runScripts: ["testScript"]
That works! Now, I want to pass some arguments to my script.
According to the Project Piper documentation, there is a property scriptOptions, which cares about passing arguments to the called script:
Options are passed to all runScripts calls separated by a --. ./piper npmExecuteScripts --runScripts ci-e2e --scriptOptions --tag1 will correspond to npm run ci-e2e -- --tag1
Unfortunately, I can't figure out what is the proper syntax for that command.
I've tried several combinations of using scriptOptions, e.g.:
scriptOptions: ["myArg"]
scriptOptions: ["myArg=myVal"]
and many others, but still no desired outcome!
How can I call an npm-script and pass arguments / parameters to the script using the Project Piper's npmExecuteScripts?

To solve the issue, it's important to bear in mind that in contrast to the regular argument-value mapping via the npm_config_-prefix, the SAP Project Piper scriptOptions doesn't perform a mapping and passes an array of argument-value pairs «as is» instead, and then this array can be picked up via process.argv.
The Jenkins pipeline configuration:
npmExecuteScripts:
runScripts: ["testScript"]
scriptOptions: ["arg1=Val1", "arg2=Val2"]
package.json:
"scripts": {
"testScript": "node ./testScript.mjs"
}
The server-side script:
/**
* #param {Array.<String>} args - array of console input arguments to be parsed
*/
const testScript = function testScript(args) {…}
testScript(process.argv.slice(2));
P.S. Just to compare, the regular way to pass an argument's value to the npm-script looks like:
npm run testScript --arg=Val
and the server-side script:
"testScript": "echo \"*** My argument's value: ${npm_config_arg} ***\""
The output:
*** My argument's value: Val ***
The npm-script engine performs an argument-value mapping under the hood by using the npm_config_-prefix.

Related

Jenkinsfile environment variables not available with parameter variables

I am using a Jenkins plugin to upload test run results to Jira. Using this plugin I can send two JSON blobs of data for the import, but the variables in those JSON blobs can only be environment variables (not variables generally available in the Jenkinsfile).
When I run it is recognizing environment variables that come from the parameters block (this is a parameterized build), but it does not recognize any environment variables I set, either in an environment {} block in the pipeline or by nesting the build step in a withEnv() {} block.
As a sanity check, right before the step in question, I echo two environment variables, one from the parameters block and one from the environment block, and both spit out to the console as expected, but then, as consumed by the plugin, only the variables coming from the parameters block are read as variables, with the rest being left as string.
So is there some difference in how these environment variables are stored/managed behind the scenes that might play into this?
So, for example, here are the parameters and environment blocks:
parameters {
choice(name: 'ENVIRONMENT', choices: ['dev', 'test', 'staging', 'prod'], description: 'Select the environment to run against.')
choice(name: 'TESTS', choices: ['All', 'API', 'Web'], description: 'Select the tests to run.')
}
environment {
PROJECT_KEY = "$jiraProjectKey"
TEST_PLAN_KEY = "$testPlanKeys[$env.ENVIRONMENT]"
PRODUCT_NAME = "$productName"
TEAM_NAME = "$teamName"
}
When I used these environment variables in the JSON blobs to set the Summary field of a Test Execution in Jira with a line that looks like this:
...
"summary": "${ENVIRONMENT} - ${PRODUCT_NAME} - ${TESTS} Tests",
...
The resulting issue summary is:
dev - ${PRODUCT_NAME} - API Tests
So it will properly interpret the environment variables set by the parameters block, but not ones I set explicitly in the environment block.
In the JSON blobs that you are sending inline make sure that for multiline strings you are using """ to delimit those strings and not '''.
Replace:
... importInfo: '''{...'''
by:
...importInfo: """{..."""

gradle and luiquibase run diffchangelog task from command line with arguments

I would like to execute a gradle luqibase plugin diffChangelog task with my custom arguments from command line.
I DO NOT want to add/modify any of the project files, no modifications of build.gradle, no gradle.properties or such i just want to run a task and pass its parameters from command line and i am so far unable to do so i would like to distribute my script that executes this task in one bash file.
I have a problem even figuring out how to pass parameters to a gradle task, moreover even the format of the arguments is confusing - there are documentation snippets pointing that i should use camelCase or hyphenated version also zero/one/two hyphens are possible in the beginning . Additionally can either use -P or -D to pass arguments to gradle so far none of it seem to work it looks like the arguments are not being passed at all.
I would like to execute something like:
./gradlew diffChangelog --url=AA --username=BB --password=CC --reference-username=DD --reference-password=EE --reference-url=FF --changelog-gile=GG
Of course proper values will be provided by inline.
Is there a concise way to do so? So far googling up for the solution results in multiple complex explanations requiring modification of existing files and then passing arguments, is there really no way of just running a gradle task with arguments or am i missing something?
Update:
The error i am alyways getting is:
liquibase.exception.CommandValidationException: Invalid argument '--reference-url': missing required argument
You should check what end of line you have. This can sometimes be resolved by changing the end of line from from windows eol to linux.
Reference:
Unexpected error running Liquibase: Unexpected value [...] (options must start with a '--') && howTo? diff w/ properties file

Jenkins Pipeline throws "syntax error: bad substitution" when Passing in Parameter

I have a Terraform project that I was trying to use Jenkin's Custom Checkbox plugin (Custom Checkbox Parameter) with so that I can build separate applications dynamically using the same IaC, however, I'm getting the following error when passing in the name parameter for that plugin into the Terraform plan and apply commands.
syntax error: bad substitution
The idea for all this is just to click on "select all" or each individual app and run the build, and this will create the IaC for the given application(s).
I have a terraform plan that I am running as a smoke test to verify the parameters above are being passed in correctly before running the apply. This looks like the following:
sh 'terraform plan -var-file="terraform-dev.tfvars" -var "app_name=[${params[${please-work}]}]" -input=false'
The documentation for the plugin states that you can reference the items checked by using this format: "${params['please-work']}" which is what I've done above. That said, one caveat to this is that Im having to set the values in quotes for this to work since the variables are being set in the Terraform using list(string).
NOTE: I have tested that all this works if I just hardcode the app names with the escapes as following:
sh 'terraform plan -var-file="terraform-dev.tfvars" -var "app_name=[\\"app-1\\",\\"app-2\\"]" -input=false'
Again, what I need is for this to work with the -var "app_name=[${params[${please-work}]}]" without throwing that error.
If needed, here is the setup for the JSON that the plugin is using:
Additionally, I can see the values are being set the way I need them to be set when running the echo of echo "${params['please-work']}" on the initial build step. So these are coming back as "app-1", "app-2"
Again, all but that one bit is working and I've tried various ways to escape the needed strings to get this work and I need insight on a path forward. This would be greatly appreciated.
You are casting the script argument in your sh step method as a literal string, and therefore it will not interpolate the pipeline variable of type object params within the Groovy pipeline interpreter. You also are passing the variable value for the app_name with [] syntax (attempted list constructor?), which is not syntactically valid for shell, Terraform, or JSON, but is for Jenkins Pipeline and Groovy with undesired behavior (unclear what is desired here). Finally, please-work is a literal string and not a Jenkins Pipeline or Groovy variable, and since params is technically an object and not a Map, you must use the . syntax and not the [] syntax for accessors. You must update with:
sh(label: 'Execute Terraform Plan', script: "terraform plan -var-file='terraform-dev.tfvars' -var 'app_name=${params.please-work}' -input=false")
If another issue arises after fixing all of this, then it would be recommended to convert the plugin usage to the pipeline with a parameters directive, and also to probably remove the unusual characters e.g. - from the parameter name.
Thanks for helping me think through this, Matt. I was able to resolve the issue with the following shell script in the declarative pipeline:
sh "terraform plan -var-file='terraform-dev.tfvars' -var 'app_name=[${params['please-work']}]' -input=false"
This is working now.

How to pass command line arguments to Deno?

I have a Deno app, that I wish to pass some command line args to. I searched the manual, but found nothing.
I tried to use the same commands used in Node.js, assuming they might be sharing some for the std libraries, but it didn't work as well.
var args = process.argv.slice(2);
// Uncaught ReferenceError: process is not defined
Any suggestions?
You can access arguments by using Deno.args, it will contain an array of the arguments passed to that script.
// deno run args.js one two three
console.log(Deno.args); // ['one, 'two', 'three']
If you want to parse those arguments you can use std/flags, which will parse the arguments similar to minimist
import { parse } from "https://deno.land/std/flags/mod.ts";
console.log(parse(Deno.args))
If you call it with:
deno run args.js -h 1 -w on
You'll get
{ _: [], h: 1, w: "on" }
You can use Deno.args to access the command line arguments in Deno.
To try it create a file test.ts :
console.log(Deno.args);
And run it with deno run test.ts firstArgument secondArgument
It will return you with an array of the passed args:
$ deno run test.ts firstArgument secondArgument
[ "firstArgument", "secondArgument" ]
If you take a stroll through the standard library, you will find a library named flags, which sounds like it could be library for command line parsing. In the README, you will find your answer in the very first line:
const { args } = Deno;
Also, if you look at the Deno Manual, specifically the Examples section, you will find numerous examples of command line example programs that perform argument parsing, for example, a clone of the Unix cat command (which is also included in the First Steps section of the Deno Manual), where you will also find your answer in the first line:
for (let i = 0; i < Deno.args.length; i++)
So, in short: the command line arguments are a property of the global Deno object, which is documented here:
const Deno.args: string[]
Returns the script arguments to the program. If for example we run a program:
deno run --allow-read https://deno.land/std/examples/cat.ts /etc/passwd
Then Deno.args will contain:
[ "/etc/passwd" ]
Note: According to the Manual, all non-web APIs are under the global Deno namespace.

How to check if pipeline parameter is empty [duplicate]

We used to be able to check if a parameter is available via:
binding.variables.containsKey()
or
getBinding().hasVariable()
But that no longer works at least as of Jenkins v 2.39. (These functions work for variables set within the groovy script but not the parameters from 'Build with Parameters'.)
Instead of using binding.variables.containsKey() to check, you should use:
params.containsKey()

Resources