3. Building a software solution – Automate building the environment

Welcome back, I am continuing my journey of building a complete software solution. To remind you, I am building a sports league management solution. Granted, I’m not running any sports leagues, so, any domain knowledge from that side would be excellent, if anyone has any input. What I do have experience with is being a parent and fighting with websites just to figure out when games and practices are. Or, the chain emails that they forwarded around that have 10 different dates and times in them. There has to be a better and easier way to at least coordinate practices and games. Perhaps in the future, I’ll get into stat tracking and analytics.

After the last post, I realized that I wanted to properly version and have an effective CI/CD solution for the infrastructure. So, I deleted all of the After the last post, I realized that I wanted to have correct version control and an effective CI/CD solution for the infrastructure. So, I deleted all of the resources created. We are going to automate and build the environment using Azure DevOps and Azure Resource Manager (ARM) Templates. To start, we go to Azure DevOps and create a new build pipeline.

DevOps will now ask you where the code is being stored, I choose GitHub and select the appropriate repository:

When it asks you to “Configure your pipeline choose “Starter pipeline”. You will then be presented a YAML file that loos like this:

# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml

trigger:
- master

pool:
  vmImage: 'ubuntu-latest'

steps:
- script: echo Hello, world!
  displayName: 'Run a one-line script'

- script: |
    echo Add other tasks to build, test, and deploy your project.
    echo See https://aka.ms/yaml
  displayName: 'Run a multi-line script'

The first thing I want to do is change that trigger statement. I am currently working on building my dev environment. I want this to trigger on commits to my develop branch. I am using the GitFlow branching scheme if you want to use that. What this means is that I’ll have a develop branch that I use for my dev environment. I’ll also create a build pipeline that triggers on my master branch for PROD. To push to master, I’ll do a GitFlow release. I follow this branching mechanism because it also helps me by allowing me to use GitVersion for semantic versioning automatically. I am going to be building that into my pipeline as well. I make use of GitVersion in my pipeline, so it is necessary to add it from the Visual Studio Marketplace.

You can edit the YAML file in the browser, or after you save it, pull it locally from your repository to edit it. If you choose to edit it in the browser, there is an assistant that can help you add items to your YAML from the menu of items available:

Ok, so, after changing the trigger to the develop branch, I then go and delete everything after steps: and then look for the “GitVersion Task” in the Tasks menu. The task asks you for some information, and there is a lot that can be done with GitVersion, just not for this project. I mostly just want it to get the semantic version details from my git repo. So I accept the defaults and add it to my project. My pipeline now looks like this:

trigger:
- master

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: GitVersion@5
  inputs:
    runtime: 'core'

Now that I have GitVersion installed, I want my build version the same as the version of the code in the repository. I found a fantastic article where the author accomplished this. Check it out at https://www.neovolve.com/2019/05/03/gitversion-and-github-with-azure-devops-build-yaml/. They added a script task like this:

- script: echo %Action%%BuildVersion%
  displayName: 'Set build version'
  env:
    Action: '##vso[build.updatebuildnumber]'
    BuildVersion: $(GitVersion.SemVer)

In their article, they were doing NuGet versioning, and I knew from the Visual Studio Marketplace page that by adding the GitVersion to my project, I would have access to the $(GitVersion.SemVer) variable. So I changed their example, which sets the build version to my semantic versioning provided by GitFlow.

And then select New variable:

As the screen shows, DevOps can store encrypted secrets so that you should NEVER put a username and password, or certificate, or anything that should be secure in your source code. Later, when we add a SQL Server and DB to our project variables will store secrets. Now I’ll add my variables:

I add the following variables:

NameValue
ResourceGroupNameLeagueTrackr-DEV
ResourceGroupLocationeastus
SubscriptionIDThis is the GUID of my subscription

Now, the only way I could figure out how to create a resource group was to use a Powershell script. Since I want this to run inside of my Azure subscription I chose the Azure CLI item from the task list:

I then chose my subscription from the drop-down, I chose Powershell Core (because everything I do on my Mac is using Powershell Core). Next, you can save the script in your repo and select it, but I chose to put my script inline. Here is the entire step in the pipeline with the script:

- task: AzureCLI@2
  displayName: 'Create Resource Group if one does not exist'
  inputs:
    azureSubscription: 'My Subscription Name'
    scriptType: 'pscore'
    scriptLocation: 'inlineScript'
    inlineScript: |
      az login --identity
      $GroupExists = $(az group exists --name $env:ResourceGroupName --subscription $env:SubscriptionID)
      if ($GroupExists -eq "False") {
          az group create --location $env:ResourceGroupLocation --name $env:ResourceGroupName --subscription $env:SubscriptionID
      }

Ok, let’s break this down. The Powershell script I wrote is in the inlineScript: section. The first line is az login --identity There are several options here. You can pass in a username and password, or a certificate. If you want to see all of your options look here. I chose identity because I have authenticated my DevOps environment to my Azure Tenant. It has the necessary roles to create my items. Next, I get the result of the Azure CLI command az group exists --name $env:ResourceGroupName --subscription $env:SubscriptionID This command will return the boolean string value of either “True” or “False.” You also see that I have added some of the environment variables to the Azure CLI command. The exists command will tell me if the Resource Group exists. If it does not, I then run the az group create to create the resource group. If you want to know more about what Azure CLI options for resource groups, check out the documentation.

So, now, our build pipeline creates the resource group if it is needed. I am not going to create all of the resources in this pipeline completely. I plan to put the actual template deployment in the release pipeline. The reason for this is that if I want to roll back my environment, I want to have that available as an option. So, instead, I am going to publish all of the items in my repo as a pipeline artifact using the Publish Pipeline Artifacts step:

I named my artifact Templates-Develop with the step looking like this:

- task: PublishPipelineArtifact@1
  inputs:
    targetPath: '$(Pipeline.Workspace)'
    artifact: 'Templates-Develop'
    publishLocation: 'pipeline'

The Publish Pipeline Artifacts takes my entire repository and saves the files for the release pipeline. In my next post, I’ll go over how to build an ARM Template and release it.

Azure.Mobile.Server.EntityData ModelState is invalid… why?

So, I have been building an ASP.NET MVC 5 web application making use of the Azure.Mobile.Server SDK.  So I created my model objects, and everything is excellent.  I used the scaffolding to generate my Controllers and Views.  From there I spent some time customizing my views, which I hate to do.  I’m not a very good front-end developer, and I have all the respect in the world for those who are skilled at making things look pretty.  So I went to test the various CRUD operations and starting at Create, I failed.  I set a breakpoint and found out that my model state was invalid.  The default code does something like this:

https://gist.github.com/jshinevar/1651c63f16f82989309068d02dc92162

When I was clicking the submit button on my form, the check of ModelState.IsValid was coming back false.  This is because in my form, I was only adding data to “ModelProperty.”  The rest of the bindings (Id, Version, CreatedAt, UpdatedAt, Deleted) are all part of the Microsoft.Azure.Mobile.Server.EntityData object type which I inherited in my model.  I use this data type because I have an accompanying mobile app and the Mobile SDK does a great job of offline syncing my data.  So… I had to remove those bindings from the [Bind(Include = “…”)] statement.  Once I removed those, my ModelState was valid, and life continued.

Greatest Common Denominator/Divisor/Factor (Geek Style – Euclidean Algorithm)

I recall learning about performing fractional math when I was young.  To be completely honest, I never actually learned an efficient way of determining greatest common denominator.  I brute forced it most of the time, meaning I just kept trying numbers until it seemed like I got the right denominator.  My method was very similar to what you see here at Kahn Academy.  As part of an algorithms course, I needed to write a function to determine the Greatest Common Denominator.  Any time you start talking about writing code

Any time you start talking about writing code, and you consider performing a function that “brute forces” an answer, your code will not run very fast.  Sometimes, you have no choice but to brute force a solution.  Sometimes there is a better way.  In this case, brute force is not the best way.  Here is how a brute force method would look:

Continue reading → Greatest Common Denominator/Divisor/Factor (Geek Style – Euclidean Algorithm)

Shuffle a list C# (Fisher-Yates shuffle)

So, recently I was writing some code, and I was presented with a problem.  I had a List<CustomObject> in C#.  I needed to jumble that list up and still use those items.  Keeping in mind that I am not one of these prodigies that went to MIT, and I do not memorize algorithms for fun, I set about like most good programmers to Stack Overflow.  I came across this post which provided me this code: Continue reading → Shuffle a list C# (Fisher-Yates shuffle)