How to pass BUILD_USER from Jenkins to PowerShell - powershell

I'm having difficulty passing BUILD_USER from Jenkins to PowerShell. I'm using the Build User Vars plugin in Jenkins. I can output "${BUILD_USER}" just fine, but when I try to pass it to PowerShell, I get nothing.
Here's my current groovy file:
#!groovy
pipeline {
agent {
label 'WS'
}
stages {
stage ('Pass build user'){
steps {
wrap([$class: 'BuildUser']) {
script {
def BUILDUSER = "${BUILD_USER}"
echo "(Jenkins) BUILDUSER = ${BUILD_USER}"
powershell returnStatus: true, script: '.\\Jenkins\\Testing\\Output-BuildUser.ps1'
}
}
}
}
}
post {
always {
cleanWs(deleteDirs: true)
}
}
}
Here's my PowerShell file:
"(PS) Build user is $($env:BUILDUSER)"
Not sure what else to try.

def BUILDUSER = ... does not create an environment variable, so PowerShell (which invariably runs in a child process) won't see it.
To create an environment variable named BUILDUSER that child processes see, use env.BUILDUSER = ...

Related

Jenkinsfile pipeline running PS1 script from git

Am really struggling with this and the only examples I can seem to find are for cmdlets to be run not scripts cloned from a Git repo. I have the following:
pipeline {
environment {
JOB_BASE_NAME="org-onprem-2016"
VERSION="$BUILD_NUMBER"
teamsColorRed="C50E2E"
teamsColorGreen="7FBA00"
}
// Helper function to run PowerShell Commands
agent {
node {
label 'Windows'
}
}
stages {
stage('Checkout SCM') {
steps {
step([$class: 'WsCleanup'])
dir ('inv_onprem_2016') {
git url: 'https://github.local/org-cit/org_onprem_2016.git', credentialsId: 'svc-tokenauth'
}
}
}
stage('Initiate Build Variables') {
steps {
powerShell('scripts\\2012\\initiatevars.ps1')
}
}
I have tried multiple iterations over the steps bit but always get some form of error around path not found etc. I think I am missing how the workspace should be addressed but tried $ENV:WORKSPACE in front and got the same result (different error around no "ENV" being defined). Can anyone help steer me in the right direction for this?

VS Code task process stdout/stderr

I'm attempting to write some test for a VS Code extension.
The extension basically creates some tasks, using ShellExecution to run a local executable file, for example:
new Task(
definition,
folder,
name,
source,
new ShellExecution('./runme', { cwd })
);
I would like to be able to test the shell process, but don't have access to this process and so cannot attach to any of the output streams nor get the exit code.
In my tests, I execute the task like so: await vscode.tasks.executeTask(task); which runs successfully regardless of the exit code of the process created by ShellExecution.
Is there any way I can get access to the child process generated from executing a task?
With Node.js' child_process this is simple to do. I use it to run an external Java jar and capture its output to get the errors. The main part is:
let java = child_process.spawn("java", parameters, spawnOptions);
let buffer = "";
java.stderr.on("data", (data) => {
let text = data.toString();
if (text.startsWith("Picked up _JAVA_OPTIONS:")) {
let endOfInfo = text.indexOf("\n");
if (endOfInfo == -1) {
text = "";
} else {
text = text.substr(endOfInfo + 1, text.length);
}
}
if (text.length > 0) {
buffer += "\n" + text;
}
});
java.on("close", (code) => {
let parser = new ErrorParser(dependencies);
if (parser.convertErrorsToDiagnostics(buffer)) {
thisRef.setupInterpreters(options.outputDir);
resolve(fileList);
} else {
reject(buffer); // Treat this as non-grammar error (e.g. Java exception).
}
});

How to pass GitHub action event hook from a javascript to a bash file?

I want to create a GitHub action that is simple and only run a bash-script file, see previous
question: How to execute a bash-script from a java script
With this javascript action, I want to pass values to the bash-script from the JSON payload given by GitHub.
Can this be done with something as simple as an exec command?
...
exec.exec(`export FILEPATH=${filepath}`)
...
I wanted to do something like this, but found there to be much more code needed that I originally expected. So while this is not simple, it does work and will block the action script while the bash script runs:
const core = require('#actions/core');
function run() {
try {
// This is just a thin wrapper around bash, and runs a file called "script.sh"
//
// TODO: Change this to run your script instead
//
const script = require('path').resolve(__dirname, 'script.sh');
var child = require('child_process').execFile(script);
child.stdout.on('data', (data) => {
console.log(data.toString());
});
child.on('close', (code) => {
console.log(`child process exited with code ${code}`);
process.exit(code);
});
}
catch (error) {
core.setFailed(error.message);
}
}
run()
Much of the complication is handling output and error conditions.
You can see my debugger-action repo for an example.

Jenkins Powershell write to console

I have a jenkins job that calls a powershell file. When I use it from a freestyle project it shows the powershell execution in the console output. Having switched it to a pipeline job I no longer see the output.
Currently my pipeline looks like this:
pipeline
{
stages
{
stage ('Deploy To Dev')
{
steps
{
powershell '"%WORKSPACE%\\SpearsLoad\\Scripts\\CIDeployToDev.Ps1"'
}
}
}
}
but I get no logging of the powershell steps.
Following the documentation I tried changing the stage to:
pipeline
{
stages
{
stage ('Deploy To Dev')
{
steps
{
node('Deploy the SSIS load')
{
//Deploy the SSIS load
def msg = powershell(returnStdout: true, script: '"%WORKSPACE%\\SpearsLoad\\Scripts\\CIDeployToDev.Ps1"')
println msg
}
}
}
}
}
but that gives:
Expected a step # line 123, column 6. def msg =
powershell(returnStdout: true, script:
'"%WORKSPACE%\SpearsLoad\Scripts\CIDeployToDev.Ps1"')
I feel like I am missing something quite fundamental. What am I doing wrong ?
You need to wrap your pipeline execution into script section, because you're trying to use scripted syntax in declarative pipeline:
script {
//Deploy the SSIS load
def msg = powershell(returnStdout: true, script: '"%WORKSPACE%\\SpearsLoad\\Scripts\\CIDeployToDev.Ps1"')
println msg
}
For anyone who comes here looking for answers, I need to point out that there were actually 3 separate problems with the code:
The lack of a script section as per the accepted answer.
The powershell was not actually running due to not calling it correctly
The powershell was not running due to spaces in the %WORKSPACE% variable
in the end, I went with:
script {
def msg = powershell(returnStdout: true, script: " & './SpearsLoad\\Scripts\\CIDeployToDev.Ps1'")
println msg
}
which actually works!
I use
Write-Host "My message"
in powershell. This will show up in the log.

Call a function from an InlineScript

How can I call a function in a workflow from a nested InlineScript?
The following throws an exception because the function is out of scope in the InlineScript:
Workflow test
{
function func1
{
Write-Verbose "test verbose" -verbose
}
InlineScript
{
func1
}
}
test
"The inlinescript activity runs commands in a standard, non-workflow Windows PowerShell session and then returns the output to the workflow."
Read more here.
Each inlinescript is executed in a new PowerShell session, so it has no visibility of any functions defined in the parent workflow. You can pass a variable to workflow using the $Using: statement,
workflow Test
{
$a = 1
# Change the value in workflow scope usin $Using: , return the new value.
$a = InlineScript {$a = $Using:a+1; $a}
"New value of a = $a"
}
Test
PS> New value of a = 2
but not a function, or module for that mater.
In the past I used the technique where I put all the common stuff in powershell module file, and do:
workflow Hey
{
PrepareMachine
ConfigureIIS
}
function PrepareMachine() {
Import-Module "MyCommonStuff"
CallSomethingBlahBlah()
}
function ConfigureIIS {
Import-Module "MyCommonStuff"
CallSomethingBlahBlah2()
}
You don't even have to wrap it in a module, you could just define the function out of workflow, and it would still work:
workflow Hey
{
InlineScript {
func1
}
}
function func1 {
Write-Output "Boom!"
}
That said, I was not impressed by workflows at all. Seems like quite pointless feature if you ask me. The most useful stuff about workflows is the ability to run things in parallel, but jobs can do it too. The idea above rant is that make sure you really do need workflows :)