Tag Archives: Build

Debugging GitHub Actions

I’ve recently been playing with GitHub actions. Having been around the block a few times, I’ve seen a fair few methods of building and deploying software, and of those, a fair few that are automated in some way. Oddly, debugging these things seems to be in the same place it was around 10 years ago: you see an error, try to work out what caused it, fix it, and run the build / deploy, rinse and repeat.

In some respects, this process may have actually become harder to debug since the days of TFS (at least with TFS, you could connect to the server and see why the software wasn’t building).

Anyway, onto GitHub actions

I’ve been trying to set-up an automated CI/CD pipeline for a new utility that I’ve been playing with.

After I’d configured a basic build, I started getting the following error:

MSBUILD : error MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file.

So, I thought future me (and perhaps one or two other people) may like to see the process that I went through to resolve (or at least to diagnose) this.

1. Git Bash

Your build is very likely trying to run on a Linux platform. If you have a look at your build file, it will tell you (or, more accurately, you will tell it) where it’s building:

So, the first step is to load up bash and manually type in the commands that the build is executing, one at a time. Again, these are all in the build file:

Make sure that you do this from the root directory, in case your problem relates to the path.

2. Add Debug Steps

Assuming that you’ve done step one and everything is working, the next stage is to start adding some logging. I strongly suspect that someone reading this will tell me there’s an easier way to go about this (please tell me there’s an easier way to go about this!) but this is how I went about adding tracing:

steps:	
	- uses: actions/[email protected]
	- name: Setup .NET Core
	uses: actions/[email protected]
	with:
	dotnet-version: 3.1.101
	- name: where are we
	run: pwd
	- name: list some key files
	run: ls -lrt
	- name: try a different die
	run: ls -lrt websitemeta
	- name: Install dependencies
	run: dotnet restore ./websitemeta/

As you can see, I was working under the assumption that my build was failing because the directory paths were incorrect. In fact, the paths were fine:

With the logging stage, there’s two ways to look at this
1. You’re closely following the scientific method of establishing a hypothesis and testing it; or
2. You’re blindly logging as much information as you can to try and extract a clue.

You’d be surprised how quickly 1 turns into 2!

3. Remember the platform that you’re running on

Okay, so in Step 1, I stated that you should try running the build in bash; but remember that, despite the Unix like interface, you’re still on Windows. As you can see from my build file, my build is on Ubuntu. In my particular case, this held the key – in fact, my build was failing because I’d used the wrong case for the directory path.

This is also true for your tests; for example, if you’ve hard-coded a directory path like this in your test:

string path = "tmp\myfile.txt";

It will fail, because in Unix, it would be:

string path = "tmp/myfile.txt";

Microsoft Chat Bot Framework – Up And Running

Some time ago (think early to mid-nineties), I used to run a BBS. One Christmas, I logged onto another BBS based in Manchester, and they had a “Santa Chat”. I tried it for a while, and was so impressed by it, that I decided to write my own; it was basically the gift that kept giving: you put this thing on your BBS (basically an Eliza clone) and it records the responses of the unsuspecting users to a text file (or log).

These days there are laws against recording such things, but those were simpler times, and once they realised the joke, everyone was happy, and life went on (albeit at 14.4k bps).

A few years ago, I decided to relive my youth, and wrote an app for the Windows Store – this one didn’t keep logs, although I imagine, had I added a “Post Log to Facebook” button, it probably would have got some use. It has since removed by MS in their wisdom. There was very little difference between it and Eliza.

Now, Microsoft seem to have jumped on this bandwagon, and they have released a framework for developing such apps. Clearly their efforts were just a copy of mine… well, anyway, this is a quick foray into the world of a chat bot.

You’re first step, in Azure, is to set-up a Web-App bot:

This will actually create a fully working bot in two or three clicks; select “Test in Web Chat” if you don’t believe me:

Okay – it doesn’t do much – but what it does do is fully working! You can download the code for this if you like:

The code doesn’t look too daunting when you download it:

In fact, looking inside MessagesController, it appears to be a simple API controller. In fact, the controller selects a dialog to use, and the dialog is the magic class that essentially controls all the… err… dialog. The default is called “EchoDialog”.

For the purposes of this demo, we can change the part we want using the web browser; select Online Code Editor:

The bit we’re interested in for the purpose of this is the EchoDialog. Let’s try changing the text that gets sent back a little; replace the test in MessageReceivedAsync with this:

public async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
{
    var message = await argument;
 
    if (message.Text == "reset")
    {
        PromptDialog.Confirm(
            context,
            AfterResetAsync,
            "Are you sure you want to reset the count?",
            "Didn't get that!",
            promptStyle: PromptStyle.Auto);
    }
    else
    {
        if (message == "test")
        {
            await context.PostAsync("Testing 1, 2, 3...");
        }
        else
        {
            await context.PostAsync($"{this.count++}: You said {message.Text}");
        }
        context.Wait(MessageReceivedAsync);
    }
}

So, we are checking the input, and where it’s “test”, we’ll return a slightly different response. You’ll need to build this; select the “Open Console” button down the left hand side of the screen and type “build”:

When it’s done, open up your test again and see what happens:

Remember that the bot itself is exposed as an API, so you can put this directly into your own code.

References

https://blogs.msdn.microsoft.com/uk_faculty_connection/2017/09/08/how-to-build-a-chat-bot-using-azure-bot-service-and-train-it-with-luis/

https://github.com/Microsoft/BotFramework-Emulator

Lock a TFS branch through builds

One of the things that is necessary if you subscribe to the feature branching method of source control in TFS is that, once a release is cut, it needs to be locked. There are other reasons that you might want to lock a branch, but this was my specific use case when I came up with this.

There are a dozen ways to do this; you can simply delete the branch, you can remove check-in permissions; however, you could also create a custom build, which prevents check-ins. This isn’t perfect, but it does give you a lot more flexibility that some of the other options.

How

Create a new build definition:

lockbranch1

Then remove all the standard components. As a base level, it probably looks something like this:

lockbranch2

Now, set the build as a gated check-in for your branch, and the next time you try and check something into that branch, you’ll end up with a build failure:

lockbranch3

Why?

The advantage of this method is mainly flexibility. When someone attempts to check into this branch, you execute a custom workflow; so you can send an e-mail, give a custom message, connect to an IoT device that administers a small electric shock, etc. You don’t have to blanket reject check-ins, you can call call the TFS API, interact with services; you could even implement some kind of rudimentary approval system for it.

Caveats

There are a couple of issues with doing this: firstly, if someone tries to check into two gated branches at the same time, they are given the option of a build – as far as I’m aware, there’s no way around this (obviously this means that this solution is not water-tight). Although, again, one of the advantages of the flexibility, is that you could probably check for this in the build.