Automate, Accelerate, Accurate

Main menu

Post navigation

PowerShell and GitLab CI – Part 4

Part 3 of this series on using PowerShell and GitLab CI gave us an initial insight into how to setup and run PowerShell code as part of a build script. During it, we were introduced to the YAML build file, .gitlab-ci.yml.

This article, and the following one will cover some of the gotchas I’ve encountered whilst getting to grips with this file, and how to get these working as you’d expect. Hopefully these will help save you some time setting these up.It will also touch on some oddities you might experience creating build scripts.

Overview

At this point, I’m going to continue to use the same project with the same job name, even though it will deviate from the original script we created earlier. This is to allow us to go through the situations I’ll mention slightly faster, and I’ll indicate for each example what the subject is about. Let’s begin!

Succeeds

Don’t use the TAB character

Unless you are using an editor which automatically translate the use of the TAB key into spaces, your scripts will fail. Use normal spaces.

Fails

The script below, whilst appearing indentical to the one that succeeds, uses table characters for indentation.

YAML

1

2

3

4

5

ps_helloworld:

script:

-.\HelloWorld.ps1|Out-File'c:\windows\temp\helloworld.txt'

tags:

-windows

Succeeds

YAML

1

2

3

4

5

ps_helloworld:

script:

-.\HelloWorld.ps1|Out-File'c:\windows\temp\helloworld.txt'

tags:

-windows

Watch Out For ScriptBlocks

The formatting for the use of a scriptblock can sometimes be a bit confusing. The final brace that closes the scriptblock should not have a ‘-‘ prefixing it. Additionally, if there is only one line of code within the scriptblock, it is not neccessary to use this prefix (but see below)

Fails

YAML

1

2

3

4

5

6

7

ps_helloworld:

script:

-For($i=1;$i-le5;$i++){

-.\HelloWorld.ps1|Out-File'c:\windows\temp\helloworld.txt'-Append

-}

tags:

-windows

Succeeds

YAML

1

2

3

4

5

6

7

ps_helloworld:

script:

-For($i=1;$i-le5;$i++){

.\HelloWorld.ps1|Out-File'c:\windows\temp\helloworld.txt'-Append

}

tags:

-windows

And if we actually look a the build output, we will see the details.
You might be quite correctly thinking that something looks a bit unusual with the output. This will be covered shortly……..

And a look at helloworld.txt to make sure it has worked correctly.

You Must Use ‘-‘ For Any Code Within Braces If It Consists of More Than One Line

If you have any code that surrounds itself in braces, such as a scripblock, function, or reiteration action, it will execute successfully without using the ‘-‘ character if there is only one line. However, two or more lines of code will fail.

Fails

YAML

1

2

3

4

5

6

7

8

ps_helloworld:

script:

-For($i=1;$i-le5;$i++){

.\HelloWorld.ps1|Out-File'c:\windows\temp\helloworld.txt'-Append

.\HelloWorld.ps1|Out-File'c:\windows\temp\helloworld.txt'-Append

}

tags:

-windows

Succeeds

It is probably best to start using ‘-‘ even with one single line within braces.

YAML

1

2

3

4

5

6

7

8

ps_helloworld:

script:

-For($i=1;$i-le5;$i++){

-.\HelloWorld.ps1|Out-File'c:\windows\temp\helloworld.txt'-Append

-.\HelloWorld.ps1|Out-File'c:\windows\temp\helloworld.txt'-Append

}

tags:

-windows

The script works, but the output on the screen is even stranger!

But the results are good….

Watch for error handling

Watch your syntax if you are wanting to use a Try..Catch block
Also, code within

Fails

YAML

1

2

3

4

5

6

7

8

9

10

11

ps_helloworld:

script:

-$ErrorActionPreference='Stop'

-Try{

-1/0

}

-Catch{

-Write-Output"Theres been a division by zero action"|Out-File'c:\windows\temp\helloworld.txt'

}

tags:

-windows

Succeeds

YAML

1

2

3

4

5

6

7

8

9

10

11

ps_helloworld:

script:

-$ErrorActionPreference='Stop'

-Try{

-1/0

}

Catch{

-Write-Output"Theres been a division by zero action"|Out-File'c:\windows\temp\helloworld.txt'

}

tags:

-windows

So the script has successfully executed. Again, the output on the screen is a bit strange, but let’s check the helloworld.txt file out.

However, the file itself has not been created, despite the fact that we know this should raise a division by zero error, which should mean the catch scriptblock is executed.

Functions Behave Differently Than You Would Expect

This final part is the greatest challenge i’ve come across so far, and deserves a bit extra detail. It will also be covered further in the next article in this series.

Here, we’ve modified our build script by adding a function which returns a string, and then output it to the same text file we’ve been using previously. If you want, you can verify the PowerShell code in the ISE, and also that the helloworld.txt file has been successfully created.

This would be put into our build script like this :

YAML

1

2

3

4

5

6

7

8

9

10

ps_helloworld:

script:

-functionHappyHelloWorld{

-$x="Hello world"

-Write-Output"I would just like to say $x"

}

-HappyHelloWorld|Out-File'c:\windows\temp\helloworld.txt'

tags:

-windows

And it builds successfully

So let’s take a look at helloworld.txt

This is strange!!! There is other items there that shouldn’t be. In fact, only the last line of the file should be there.

Let’s do a bit of detective work and see if we can get more information about what’s being returned. A good starting place would be to see if we are getting a multiline string or an array returned.

YAML

1

2

3

4

5

6

7

8

9

10

11

ps_helloworld:

script:

-functionHappyHelloWorld{

-$x="Hello world"

-Write-Output"I would just like to say $x"

}

-$result=HappyHelloWorld

-$result.GetType()|Out-File'c:\windows\temp\helloworld.txt'

tags:

-windows

So let’s take a look at helloworld.txt

This is real strange, an array is being returned. But we know that only a string is returned from the function. In the next article, we’ll dig deeper into what’s actually happening during the build process, which will shed some light on some of the strange things we’ve been noticing. Then we’ll also take a look at Lint, and how we can use it carry out checking of our YAML files.