Ingenious logo
Photo by Thought Catalog on Unsplash
Photo by Thought Catalog on Unsplash

I don’t code too much these days, but every once in a while I get to kick off projects that will be picked up later by other devs at the company. That’s how I got my last project, a web app for a state public school system that should be installed on-premises in a Windows environment.

I know what you are thinking, yeah on-premises Windows kind of sucks and most of your options are narrowed to .net serving on IIS. I agree, but there’s not much I can do to avoid it, typically the industries we work with (Healthcare and Education) are so regulated that it’s difficult for them to make the switch to the cloud even if they wanted to. Luckily, we have .net core that allows me to develop on my mac and deploy on Windows machines safely.

With that said, I started to build a .net core MVC application for the API (formerly Web API) and a React SPA for the frontend. When the time to build the staging/testing infrastructure came I had a few options.

Measuring my options

I could have used Azure since they probably have the best support for .net, but while the backend app would be easy to install and host maybe my frontend would require more work. Also, while I’ve been using Azure lately, I’m not as familiar with the platform as i would like.

I took a step back and reached out to Heroku, and it turns out that it can handle .net core perfectly fine with community developed build packs. I like Heroku because it’s super simple and it does much of the work for you.

Heroku ftw

$ cd MyAwesomeApp
$ heroku apps:create --buildpack jincod/dotnetcore
$ heroku config:set ASPNETCORE_ENVIRONMENT=Production
$ git push heroku master

These few lines create a Heroku app with a build pack that can handle .net core apps and makes the first deploy. The build pack searches for Startup.cs or Program.cs in your repo to locate the correct .csproj file and run dotnet publish \<project>.csproj.

Running migrations

As the jincod/dotnetcore README says you cannot execute dotnet from the console using heroku run and usually that's not what you want either, you want each deploy to run migrations as well so you end up with your code and DB in sync. To do this, you can add the following lines to your .csproj.

<Target Name="PrePublishTarget" AfterTargets="Publish">
<Exec Command="dotnet ef database update" />
</Target>

Multiple projects

I’m not an expert on the .net core framework so I learned the hard way that tests are created in a different project, coming from JS I tend to co-locate tests and implementation on the same folder and let the transpiler handle what goes into the final bundle. It makes sense that you are requested by .net to move things around and create a different project.

In my case, I ended up moving my implementation into a src folder and tests into a tests one, each one with his own .csproj file.

When you do this the build pack has a hard time to find what to execute, the documented way to solve this problem is to specify PROJECT_FILE, the name of the .csproj you want to target and PROJECT_NAME, the name of the folder where this file is located. I tried this and found it a bit unreliable, sometimes it did the job and some others it blamed me about not finding the correct folder, I'm sure I did something wrong but since I didn't have much time I came up with a much simpler solution.

There is a monorepo build pack for Heroku that handles this case very gracefully, it takes a folder with multiple projects, and it copies the one you specify to the root Heroku folder, this means that if I run that build pack first the .net core one wouldn’t need to worry on locating my src folder.

$ heroku buildpacks:add -i 1 https://github.com/lstoll/heroku-buildpack-monorepo
$ heroku config:set APP_BASE=src

The -i 1 flag is telling Heroku to add lstoll/heroku-buildpack-monorepo first in the build pack pipeline.

Conclusions

While Heroku is not super flexible, it lets you do these type of things mix and matching build packs and gluing them with some custom code. Sometimes that’s all that we need.

Are you looking for a passionate team that can help you envision, design, and build amazing products? Use the link 👇 to schedule a call.

Weaving handSchedule a call