How can I use a bamboo plan variable in a script task? - bamboo

I have defined in my bamboo plan a variable (BAMBOO_TEST_VAR) that I'd like to reuse in a particular script but I can't seem to figure out how to make it visible to that script.
If I just reference that variable from the script it merely prints the variable as empty.
27-Oct-2020 23:34:00 TEST JOB
27-Oct-2020 23:34:00 bamboo.shortJobName =
27-Oct-2020 23:34:00 BAMBOO_TEST_VAR=
And if I provide it as input to the Environment variables field it just renders with the value I give in that field taken as a literal, not to the plan variable I was hoping it would evaluate to.
27-Oct-2020 23:36:57 TEST JOB
27-Oct-2020 23:36:57 bamboo.shortJobName =
27-Oct-2020 23:36:57 BAMBOO_TEST_VAR=$BAMBOO_TEST_VAR
How can I reference the plan's environment variable directly from a script task without passing it down through arguments or something of the sort. What aspect or bamboo detail am I ignorant of that would have informed me that what I'm attempting is not possible or not supported because of reason XYZ?

So the trouble was I didn't scope the variable appropriately. What did it in the end was
${bamboo.BAMBOO_TEST_VAR}
Turns out if I slowed down and looked at the bamboo page more carefully I would have noted the help breadcrumbs they left around. Copying that help text here, emphasis mine:
Variables substitute values in your task configuration and inline scripts. If a variable name contains any reference to a password, like "password", "sshKey", "secret", or "passphrase", its value will be masked with "********".
For tasks configuration fields, use the syntax ${bamboo.myvariablename}.

Related

In jsr352 batch job xml, how to read/inject a environmental variable from system

I have environmental variable called ENV, which holds the DEV,QA OR PROD region as value. When the server.xml loaded it includes the corresponding db configuration using this variable. For ex: db-config-${env.GAH_ENV}.xml
I would like to pass the same value to the batch job xml as a job parameter or properties to any of the class. How Can I do that.
below code snippet not working
<property name="environment" value="${env.GAH_ENV}"/>
The short answer is that using a batch property may not be a good solution and you might consider something else like MicroProfile's #ConfigProperty.
The reason is there's not a built-in way to access environmental variables through JSL substitution. There is also not a convenient way for one artifact to set a property value to be used by a second artifact running later within the job execution.
In the special case that you are starting the job from within the same JVM it will execute, of course, you could pass the env var value as a job parameter.
But in the general case, if you can change the Java code and you don't really need a batch property I would use a MicroProfile Config property instead, injected via #Inject #ConfigProperty.
By doing so you lose the batch-specific substitution precedence, including the override available via job parameters passed with the submit/start. You also give up the ability to use this property in other JSL substitutions (to "compose" its value into other batch properties via other substitutions).
But you at least get a property with its own various levels of precedence/override (e.g. server config, env var, microprofile-config.properties), which is more flexible than just always reading the env var via System.getenv( ).
This is certainly an area to consider for the next version of the (now-Jakarta) Batch spec.

Pentaho variables at JVM level

Using set variables step in pentaho, I have defined a variable and the scope is set to "valid in the Java virtual machine", but it is not replacing in one of the sql's used in the table input step.
Table input step is checked with option "replace variables in script". But the same variable when I placed in kettle.properties file, it is working. Pentaho job available in the repository and running from Linux box
Could anyone please share your thoughts?
You can-not set the parameter and use it in the same transformation, because it executes all the steps parallelly.
Logic-wise correct approach is first set the variable and get the variable in next transformation and further use or replace in respected steps.
As Working Hard.. says, you can not use a parameter in the same transformation, you have to use another transformation after setting the variables.

Variable Encapsulation in Case Statement

While modifying an existing program's CASE statement, I had to add a second block where some logic is repeated to set NetWeaver portal settings. This is done by setting values in a local variable, then assigning that variable to a Changing parameter. I copied over the code and did a Pretty Print, expecting to compiler to complain about the unknown variable. To my surprise however, this code actually compiles just fine:
CASE i_actionid.
WHEN 'DOMIGO'.
DATA: ls_portal_actions TYPE powl_follow_up_sty.
CLEAR ls_portal_actions.
ls_portal_actions-bo_system = 'SAP_ECC_Common'.
" [...]
c_portal_actions = ls_portal_actions.
WHEN 'EBELN'.
ls_portal_actions-bo_system = 'SAP_ECC_Common'.
" [...]
C_PORTAL_ACTIONS = ls_portal_actions.
ENDCASE.
As I have seen in every other programming language, the DATA: declaration in the first WHEN statement should be encapsulated and available only inside that switch block. Does SAP ignore this encapsulation to make that value available in the entire CASE statement? Is this documented anywhere?
Note that this code compiles just fine and double-clicking the local variable in the second switch takes me to the data declaration in the first. I have however not been able to test that this code executes properly as our testing environment is down.
In short you cannot do this. You will have the following scopes in an abap program within which to declare variables (from local to global):
Form routine: all variables between FORM and ENDFORM
Method: all variables between METHOD and ENDMETHOD
Class - all variables between CLASS and ENDCLASS but only in the CLASS DEFINITION section
Function module: all variables between FUNCTION and ENDFUNCTION
Program/global - anything not in one of the above is global in the current program including variables in PBO and PAI modules
Having the ability to define variables locally in a for loop or if is really useful but unfortunately not possible in ABAP. The closest you will come to publicly available documentation on this is on help.sap.com: Local Data in the Subroutine
As for the compile process do not assume that ABAP will optimize out any variables you do not use it won't, use the code inspector to find and remove them yourself. Since ABAP works the way it does I personally define all my variables at the start of a modularization unit and not inline with other code and have gone so far as to modify the pretty printer to move any inline definitions to the top of the current scope.
Your assumption that a CASE statement defines its own scope of variables in ABAP is simply wrong (and would be wrong for a number of other programming languages as well). It's a bad idea to litter your code with variable declarations because that makes it awfully hard to read and to maintain, but it is possible. The DATA statements - as well as many other declarative statements - are only evaluated at compile time and are completely ignored at runtime. You can find more information about the scopes in the online documentation.
The inline variable declarations are now possible with the newest version of SAP Netweaver. Here is the link to the documentation DATA - inline declaration. Here are also some guidelines of a good and bad usage of this new feature
Here is a quote from this site:
A declaration expression with the declaration operator DATA declares a variable var used as an operand in the current writer position. The declared variable is visible statically in the program from DATA(var) and is valid in the current context. The declaration is made when the program is compiled, regardless of whether the statement is actually executed.
Personally have not had time to check it out yet, because of lack of access to such system.

how to store sql query result in a variable and messegeBox

I have a simple sql query in my Execute sql task in ssis package,
SELECT MAX(binindex)
FROM dbo.myTable
I need to store this maximum index into a variable and then pass it to Script Task and display it,
I already declared a package variable, the package compiles, however it shows -1 every time, I don't know what I'm doing wrong, any help will be appreciated!
public void Main(){
//TODO: Add your code here
Dts.TaskResult = (int)ScriptResults.Success;
MessageBox.Show(Dts.Variables["User::BININDEX"].Value.ToString());
}
The good news, is that you are doing everything correctly as far as I can see. I recreated your package and I get the expected value from my query.
I can also induce your situation - the correct value is returned from my query but my package produces an "incorrect result."
The problem, I hope, is that you have two BININDEX variables defined at different scopes. My original assumption was the Package scoped one contained a value of -1 and you had a variable scoped to the "Execute SQL Task" with the same name. The default behaviour is a variable is created scoped to the object that currently has focus. This changes in the 2012 release of SQL Server by the way.
As your picture shows a design-time value of 123 for the package scoped variable, the possibility also exists that you have a variable defined on the Script Task with the same name of BININDEX. The local variable would override the globally scoped variable
Click on your Script Task and hopefully you'll see a BININDEX defined there like the above. Otherwise, I think the problem is somewhere in your package, you have conflicting BININDEX variables. You can try slogging through the Package Explorer looking for an instance where you have two variables with the same name listed.
I need to leave but if none of that is the case, add a PostExecute breakpoint on the Execute SQL Task and look at your Locals window (not Variables as that only reflects Design-time values). Expand Variables and you should be able to see the value of BININDEX. Is it correct there?

Variable scope and source command in Tcl

I have the following two files:
a.tcl:
set condition false
source b.tcl
b.tcl:
if {$condition} {
puts "hello"
}
When I run a.tcl, it prints "hello". Is this a correct practice for accessing variable defined in a.tcl? What is the scope of $condition in b.tcl? Thank you.
The scope of condition is global. The source command evaluates the script read from the specified file in the context it's run; in your case this context is also global, hence your puts works.
The question about practice is more complicated as it hightly depends on what you actually do.
The way the source command works is pretty much exactly as if it was reading the file into a string and then passing that to eval (the sole subtlety is to do with info script). That means that the scope that the source was done in will be the one that the outermost level of the script is evaluated in, and so that you could have condition be a local variable there:
proc funkystuff {condition} {
source b.tcl
}
funkystuff true
That will work (and is in fact vital for how Tcl's package definition scripts work; they're evaluated in a context where there is a local variable $dir that describes where the package definition is located) but it can most certainly lead to code that is confusing!
Because of this, it's good practice to write your scripts so that the code inside them makes no assumptions about what context it is evaluated in. The easiest way to do that is often to put the code in the script inside a namespace, where the name of the namespace is fully qualified.
namespace eval ::foobar {
# Do stuff here...
}
It's also a good thing to try to write code that isn't excessively parameterized on sourcing, instead saving that for either which version of the code you load (e.g., one file for Linux, another for Windows) or what parameters you pass to the commands. Of course you don't have to work that way, but it does help make your code robust and easy to understand.
Finally, the scope used for the main script to a Tcl interpreter is always evaluated at the global level (i.e., in the :: namespace with no parent scope).