Easy CQRS with ASP.NET Core & MediatR

This post is a supplement to a development talk I created with the same name. You can view the slide deck here.

References / Links

Automation Trepidation: Does DevOps Freak You Out? Part 4

In my last post, we learned how Azure DevOps projects set up our VSTS account, the code repo, and the build and release pipeline. We added a branch policy and protected our master branch with a PR build that we cloned from the one Azure set up for us.

In this post, we will clone the repo and go through the process of integrating our changes into our master branch.

There are several ways to clone a repo using VSTS and Visual Studio. I prefer to clone from within Visual Studio. To do so, I need to get the URL for the repo. From your VSTS account homepage, hover over the row containing your team project and click “Code”.

From the “Code” -> “Files” page, find the “Clone” button in the top right-hand area of the page. Click that and you’ll be presented with the following dialog. Click the “Copy” button circled to copy the repo URL to your clipboard.

From here, I like to switch over to Visual Studio and clone from there. Open Visual Studio and open the “Team Explorer” window. Make sure you’re logged into Visual Studio using the Microsoft Account you used to setup the DevOps project (and the VSTS account). Inside the Team Explorer window, click the icon at the top of the window that looks like a plug and click “Manage Connections” -> “Connect to a team project”.

This will open a dialog displaying all TFS and VSTS connections tied to the account you are currently logged in as. Locate the VSTS account you just created, expand until you reach the repo, click the repo, change the path to the appropriate location (if necessary) and click the “Clone” button.

The repo will be cloned to the selected location, but you’ll have to open the solution manually from the selected location. It doesn’t open automatically. So open the solution. We now have a VS solution ready to be worked on. But not quite. We currently only have the master branch, and the remote branch that our local branch is tracking is now gated by pull requests, thanks to us.

So we need to create a new branch off of the master branch, on which we can make our changes.

You can clone using the IDE or command line. I prefer to use Git Bash, and I do so by executing:
git checkout -b develop

So now I have a branch on which to make my changes.

I’m going to add a new controller action that simply writes out “Hello, World!” (yes, lame), and a new navigation menu item to route to the controller action so we can navigate to it.

Once you have made your changes and ran them locally to verify that they work, you need to commit them locally. To do so, I recommend using the “Team Explorer” window in Visual Studio. Click the home icon at the top of the window and then click the “Changes” button.

You’ll hopefully see all the files that you modified. Verify that the changes listed match what you did. Enter a commit message and click “Commit”.

Now at this point you could push this branch to the VSTS server and begin the pull request process. But I recommend checking out master again and getting any recent changes. If you are working by yourself, you can obviously skip this step. But if not, it would be smart to pull the latest changes to the master branch and rebase your branch onto them. To do so, switch over to Git Bash and type:
git checkout master
git pull

Then checkout your develop branch again and rebase onto develop by executing:
git checkout develop
git rebase master

Use Visual Studio to resolve any merge conflicts (there shouldn’t be). If there are, commit the changes once merge is complete.

Once we have rebased (if necessary), we need to push our changes to the server. Again, I like to use Visual Studio Team Explorer window. Inside this window, click the home icon and click “Sync”. You should see something like this:

Click the “Push” button to push the branch and it’s changes to the VSTS server.

Back in VSTS, in your team project portal, click the “Code” -> “Files” menu to get to your repo. In the main pane, you should see a message indicating that the branch was updated and a link to “Create a new pull request”. Alternatively, you could use the “Pull Requests” button off of the “Code” menu.

In the “New Pull Request” page, make sure you are pulling “develop” into “master”. Modify the title and description as needed. Add the reviewer you want to review the PR (or leave blank and anyone on the team can do it).

But we forgot one little detail…

We forgot to create a work item. Remember our master branch policy that requires each PR be attached to at least 1 work item?

Open the “Work” menu in a new tab (so we can leave our changes to the PR open). Click “Iteration 1”, then click the board view in the main pane, then click “Schedule work for this sprint”.

You’ll be taken to a form to enter a new user story. Enter a title (I used “Hello World”), and click “Add”. You now have a user story on your sprint. Feel free to go further and add a task. But this will suffice for our branch policy.

You’ll have to actually open up the user story to get it’s id. The id should be the number beside the title inside the user story editor.

Use that id in the “work items” box back over in your “New Pull Request” window. You should see the user story in the list box. Select it to add it to the PR, and click “Create”.

You’ll be taken to the PR review page. You’ll see our PR build got kicked off. If successful, the PR will be able to be approved.

Explore the “Files” tab. Inside there, you’ll be able to see side-by-side code comparison to review what was changed. You can leave comments for the author. Remember our build policy requires those comments to be resolved. So if you literally are just leaving a comment, not a question, make sure you mark it as “Resolved”. Once you are satisfied, click “Approve” and then “Set auto-complete”, or click the dropdown beside “set auto-complete” and click “Complete”.

Once you get the completion modal, make sure the checkbox for “Delete develop after merging” is NOT checked. We want to keep that branch around.

The reason we do not want to delete develop is because in the future, we want to use feature branches to update develop, which we will in turn, pull into master.

Once the PR is approved and completed, you’ll get a message that the changes were merged into master. Once you see this, click the “Build and Release” menu at the top of the page and you should see your continuous integration build has been kicked off. You can click the build number if you want to keep track of the build’s progress.

Once the build is complete, you can click “Releases” and verify the CD release gets kicked off.

Once the build and release have both completed successfully, our changes should now be live in our Azure App Service. Verify the changes are there.

Congratulations! You just DevOps’d.

If you recall the first post in this series. We talked about Donovan Brown’s “checklist” of sorts, that can guide you in where to go next in implementing a DevOps culture at your organization. We made it all the way down to deploying to a static environment!

So where do we go from here?

Well, we begin deploying to more environments for one. But beyond that, we want to try and focus on getting our code to stand up itself. We want to start getting into IaC (Infrastructure as Code) and CaC (Configuration as Code). We want to be able to control and automate how our application is provisioned and configured. The faster we can deliver value to our customers, the better we will all be.

I hope you enjoyed this series on baby-stepping into DevOps.

Automation Trepidation – Does DevOps Freak You Out? Part 3

In my previous post, I showed you how to create a new “DevOps Project” using Microsoft Azure. By now, Azure should be finished setting up your VSTS project and your Azure resources. In this post, we’ll poke around Azure and VSTS and take a look at what was created as well as show you how to use branch policies to do things like gate your branches with pull requests.

First, let’s check out what Azure created for us.

You should see a page like this once Azure is finished.

You’ll see on the left side, your CI/CD pipeline info and on the right, your app service URL. Also, on the bottom left, you’ll see your Git repo with a link that reads “Code”. Clicking that link will pop you over to VSTS, but let’s hold off on that for now.

Let’s check out the Azure resources that were created. In the left side “hamburger menu”, select “Resource Groups”. Find the resource group that you created. Mine is called “automation-trepidation-rg”. Click the resource group name.

In the resource group blade, you’ll see a list of resources that were created by Azure and placed into the resource group. You should see an App Service, an App Service Plan and Application Insights. The App Service is your web application. The Service Plan is your hosting plan, and Application Insights is your resource for monitoring your application.

From here, you can click around and into the various resources and get a feel for which options you have. For our purposes here, we’re done in Azure.

In the left-hand side “hamburger menu”, click “Dashboard”. Azure should have placed a “DevOps Project” tile on your dashboard with the title of whatever you called your DevOps Project. Mine is called “Automation Trepidation”. Click the tile.

You should be back at your DevOps Project “home”. Click the “Code” button in the bottom left-hand side of the blade in the section entitled “Repository”.

This will open VSTS up in a new tab. Once you login (using the same account you used to create the DevOps Project in Azure), you should be taken to the Code section, specifically “Files”. Here you can see your Git repo containing the ASP.NET Core application that was automatically created for you. Yours should look similar to this:

So you should’ve noticed from your Azure DevOps Project home blade that you now have a “CI/CD Pipeline”. Inside of VSTS, that translates to “Build and Release”.  So, click the “Build and Release” menu item at the top of the page. You should be taken to the “Builds” tab and you should see your CI build that Azure created for you (and subsequently fired off).

If you click the build title, you’ll be taken to a build summary page with details about the build history. In the top right-hand side of the build summary page, there should be a button or link that says “Edit”. Click this and you’ll be taken to the build definition edit view.

From this view, you can customize the build tasks that make up your CI build. Take some time and go through the options. Take special note of the menu inside the build definition editor. The menu option entitled “Triggers” are where you configure Continuous Integration. This is already configured so I won’t go through it, but make note of its existence.

In our next step, I’ll create a new build by first cloning the existing build that was created for us by Azure. The purpose of this build is to serve as a build policy that we will enforce when pull requests are created.

So, after you are done exploring the options within the build definition, click the “Builds” menu item and return to the builds page. Hover over the row containing your CI build and notice the ellipsis.

Click the ellipsis, and select “Clone”. You will be taken to the build definition editor, specifically the “Tasks/Process” tab. Inside this tab, find the “Name” box and change the name of the build to something like “AutomationTrepdication – PR”. It should look something like this:

We want to be able to easily distinguish between the CI and the PR (pull request) build.

After you change the name, remove the “Publish” and “Publish Artifact” tasks. You can remove a task by right-clicking on the task and selecting “Remove Selected Task(s)”. Once you have done this, your PR build should look like this:

The last thing you need to do is, click the “Triggers” tab and switch the “Continuous Integration” switch to “Disabled”.

One last modification will be for test results Currently, with .NET Core, the test results aren’t uploaded to VSTS. The test task will run your test, but you need to add a Publish Test Results build task to the build to get the test results uploaded to VSTS. Also, we have to change the test task to create a log file that will contain the test results.

So first, lets navigate to the test task and in the “Arguments” text box, add the following after the –configuration parameter.

–logger trx;logfilename=TEST.XML

This will output a log file that we can then upload in our publish test results task.

Now, click the plus sign in the Phase tab containing the build tasks. It probably reads “Phase 1” if you haven’t changed the name of the build phase.

Now, in the right-hand pane, find the “Test” tab and find the “Publish Test Results” build task. Click the add button to add it to your build. Click and drag it right below the test task.

Inside the Publish Test Results build task, change the Test Results Files file selection to use the filename specified in the test task. Click the checkbox for Merge Test Results. Change the name to something meaningful and you’re done.

Save your build definition by click the “Save & queue” button and selecting “Save”.

Now we’re ready to setup our branch policy. Click the “Code” menu option at the top of the page and select “Manage Repositories”. In the left-hand side pane, there should be an explorer-type window in which you can explore your respositories in this account. Click your repo name and expand down until you reach the “master” branch and click on that branch. You should see something similar to this:

In the middle pane, click the link that reads “Branch Policies”.

Branch policies give you control over how your branches are updated and help you enforce a specific developer workflow.

I enforcing that the master branch be updated via a pull request and that pull request must be approved by at least 1 reviewer. I’m allowing myself to approve my own PRs for obvious reasons. I’m also requiring that PRs be linked to work items. I like to discourage ad-hoc updating of source code. If it needs updated, there must be a documented task on the board to account for the change. Also, I’m enforcing that reviewers comments must be resolved in order to approve. I find this useful in that if a reviewer has a question, he/she can choose to resolve the comment immediately, or they can wait until the author justifies or explains or answers the question. It’s good for a nice back and forth.

The last bit here is merge strategy and build policy. The merge strategy I chose was “Squash merge”. Squash merge will squash the incoming commits into one commit against the master branch. The build policy stipulates that our previously created PR build, complete successfully against the incoming commit.

So we’ve covered the build side of things. We’ve gated the master branch by pull request, preventing devs from pushing directly to the branch, and we’ve stipulated that the pull requests must pass a build successfully as well as be subject to review.

So now we have that covered, let’s switch over to the release side of things.

Hover over the “Build and Release” menu option and select “Releases”. In the left-hand pane, you should see “Automation Trepidation – CD” (or whatever you called your project). Hover over the release and click the ellipsis, followed by “Edit”. You should see something like this:

I actually don’t want to change anything here, but explore the options. Make note of the lightning bolt icon in the “Artifacts” section. That is what you click to configure Continuous Delivery. But Azure already configured this correctly for us. I don’t have anything else to configure. It’s already linked to the “Automation Trepidation – CD” Continuous Integration build in that whenever that build completes successfully, it will trigger this release definition and a new release will be deployed to what’s configured in the “Environments” section.

We do have to make one small change. We need to check the checkbox to take the app offline when we are trying to deploy. Once the app has been started you’ll have to either manually take the app offline or use the release to do so automatically in order to update. So, click the link that reads “1 phase, 1 task”. Inside the release definition editor you can customize things like which agent the release runs on, which (if any) deployment slot to deploy to, and for our use, an option to take the app offline. Check the checkbox and click “Save”.

So now we have a place to put our code, a way to protect our code, a way to automatically build and deploy our code and a place to put our backlog and work items. All we have to do now is actually get to work and start making some changes. In the next post, I’ll show you how to clone the repo in Visual Studio and begin to make changes to our master branch.

Automation Trepidation – Does DevOps Freak You Out? Part 2

In my previous post, I told you about how Donovan Brown inspired me and my company to begin down the DevOps path. I outlined and paraphrased his “checklist” of progression down the winding road towards DevOps rock-stardom.

In this post, I’m going to show you how you can use Microsoft Azure and Visual Studio Team Services (VSTS), to facilitate your DevOps journey.

Step 1 – Azure DevOps Project

If you already have an Azure account, log into portal.azure.com. If you do not have an account, create one. You’ll need a credit card. But you SHOULDN’T incur any charges. Azure changes frequently, so I won’t be held liable if you accidentally get charged a few bucks because they changed pricing tiers or you clicked the wrong button 🙂

Once you’re logged into Azure Portal, click on the top-left “hamburger” menu (if menu not expanded), click “New”.

In the “New” blade, type “DevOps” in the “Search marketplace” box. Click “DevOps Project”. In the following blade, click “Create”.

In the next blade, you’ll see options for create different types of new applications or the option to use existing code. In our example, I’ll select .NET and click “Next”.

In the following blade, you’ll have the option to choose ASP.NET or ASP.NET Core for our web application. I’ll select “ASP.NET Core” and click “Next”.

The next blade allows you to select which app service that will be used when deploying your web application. You have the option to choose between Windows, Linux or Azure Containers. For this example, I’ll choose “Windows”.

The next blade is where you can configure your VSTS options as well as your Azure subscription info. I chose to create a new VSTS project. Whether you create a new one or use an existing, you’ll be asked to create a new team project. This team project will house your Git repo, your work items and everything else associated with this specific project. Also, please note that I selected “Change” in the Azure options. This is because it defaults to the “S1 Standard” app service pricing tier, which is not free. I customized my options so that I could select the “F1 Free” plan. I also changed the default app sevice and Application Insights location and the resource group name. Choose the options best for you and click “Ok” and “Done”.

Once you click “Done”, Azure will begin working on spinning up all the resources for your new “DevOps Project”.

In the next post, I’ll walk you through the build and release and show you how to use branch policies to enforce pull requests.

Automation Trepidation – Does DevOps Freak You Out? Part 1

So you’re not a consultant. You don’t work at a high-end software shop. Your team is small. Maybe it’s just you? You keep hearing about this “DevOps” thing. You’ve heard of Continuous Integration and Continuous Delivery. But those things don’t apply to you. All of that stuff is just over-complicated nonsense reserved for people who work at bigger companies. Those people don’t have to deal with all of the mess and all of the problems you have to deal with. Right?

Wrong. Everyone has mess. Everyone has issues with the applications they support. But you have to start somewhere. You simply cannot afford to ignore this topic. Eventually, there will be too much mess and too much manual process to support. You will not be able to deliver sufficient value to your customers in sufficient time. Then what happens?

DevOps is a culture. But how to you build a culture?

I actually don’t know…

But I DO know that you can’t start by doing “all the things”. You have to start small. But you have to start doing SOMETHING.

This topic is very near and dear to my heart, as I fit the aforementioned description. I don’t work at Google. I don’t work with a bunch of industry experts who know all the Agile, DevOps, Buzzwordy things that make everything look so cool. I work at a trucking company. We have some messy processes. We have more messy code. We have legacy code. Lots of it. But you know what? Even we have started doing something. But we started small.

This all started for me at Visual Studio Live Las Vegas 2017. Donovan Brown gave a keynote entitled “Rub Some DevOps On It”. It fired me up so much that I went straight back to Dayton OH and started “Rubbing Some DevOps On It”. I didn’t wait for a boss to tell me to do it. I didn’t wait for someone to say it was ok to do it. I just started doing it. You can too. I’m going to show you how.

Again, this is all inspired by that awesome keynote by Donovan Brown and more specifically, this blog post here.

I’ll paraphrase…

  • Get source control
    • Centralized or Decentralized
    • Decide on an effective branching strategy
  • Get your Agile right
    • Produce incremental, shippable code
    • Use work items for tasks, backlog items, bugs, features, etc.
    • Make sure your task board and backlog are visible
      • Set goals
      • Work on unit testing
      • Work on quality
      • Create a definition of done and adhere to it
  • Start doing Continuous Integration
    • Build each checkin
    • Automate unit tests
    • Package for deployment
  • Continuous Delivery
    • Automate delivery to ONE environment, a development environment
    • Start creating automated integration and load tests
    • Don’t forget about humans. Have a QA or user acceptance group using your development environment. Build your confidence
  • Beyond…
    • Infrastructure as Code
    • Configuration as Code
    • Monitor how you’re doing

Ok, so that IS a bit of a list. But chances are, you’re not starting from scratch. In my next post, I’ll detail how to get from source control through continuous delivery.