Uff there has been a long, long time since last time I wrote here … but, several people have lately asked me about my blog, so there I go, and better than write a bla bla article about the last time and why I haven’t wrote so much, let’s get technical.
In this article I assume you have the basic knowledge of creating Team Build definitions, and Release Management definitions. I’m not covering this topics in this article, as it would make it so long to read. If you are not familiar with this, I would recommend you to read about it here https://www.visualstudio.com/en-us/docs/release/overview
When we are deploying applications with a database, there are several ways we can do, usually we will deploy differential scripts to update the DB, or DACPAC and other technologies, but we can also use Entity Framework migrations, although I still have to think if it is the best way to do it …
Usually migrations are executed Entity Framework initializers, but if we need to execute them before deployment, so we can be sure we updated the DB even before deploy our application, there is a tool named “migrate.exe” included in the NuGet package of Entity Framework.
There is a couple of steps we need to take to be able to execute this tool from Release Manage:
- Build our migrations Assembly
- Copy the tool migrate.exe from the tools folder in the EF Nuget package folder to the same directory as the migrations assembly
- Execute migrations
Let’s go with the first two steps, which we will do in a Team Build definition which publishes the results, as artifacts, to the Release Management definition. The build step is easy, usually our migrations assembly will be included in the Solution we are building to deploy our application, if not, well include it in the solution or build it in a separate build step in the same build definition, no tricks in this one.
Copy the migrate.exe tool includes a couple more of steps. First I would copy the result binaries from building the migration project to a separate folder we will publish as an artifact. This is done with a Copy task in the build steps, which we will configure this way:
- Source folder: we point to the binaries result of our migration assembly, notice I have oversimplified the directory, with /MigrationAssembly/ be sure to include the full path to it. And I have used a couple of variables $(build.sourcesdirectory) a system variable which points to the root of sources downloaded by the agent, and a custom variable $(buildConfiguration) which points to the current build configuration (i.e.: Debug, Release or whatever you use).
- Contents: ** so we copy all results.
- Target folder: I’m copying to a new folder automatically created in the artifacts staging directory, as configured with the system variable $(build.artifactstagingdirectory), you don’t need to create a complex folder structure under this one, but be sure to at least create a folder structure which allows you to separate different results and artifacts.
Next step, copy the migrate.exe file, again we use a copy task:
With the parameters:
- Source folder: we point to NuGet packages folder, which is usually at the same level of the solution we are building, but be sure to check this correctly, probably this path is one of the trickiest paths of this configuration.
- Contents: “migrate.exe” well, no comments …
- Target folder: I’m copying to a the same folder we copied the results of the migration assembly in the previous step. This is very important for all of this work, so be sure to check it twice.
And the last step in the build, publish the artifacts, usually as simple as this one, which will publish all the folder structure we have in the artifacts directory to a server artifact:
Final steps will be seen like this:
Once we have done this, we can queue this build definition, and once finished, in the resulting artifacts just check you have your binaries from the assembly migration along with the migrate.exe tool in the same folder within the artifacts.
For the Release to execute the migrate.exe file it is just a simple task of execute a command line, of course one gotcha of this is to link the build definition with the Release Management definition (again, I assume you are already familiar with this).
So within the desired environment of our Release definition, we will just add a Run on agent task of type Run script, one important point, remember this tasks runs on the agent, so you need to ensure your agent can communicate with your SQL Server or SQL Azure.
We will configure this task in this way, before the deploying task for the application:
The parameters we are using:
- Path: here we configured the path to migrate.exe within the build artifacts we are using, you can take advantage of the “…” button to look for it, again, remember: you must have linked your Release Management definition to your Build definition for this to be available.
- Arguments: there is different arguments you can use here, even just point to a *.config file with all the values (check full documentation), in this case I just pointed to a custom variable containing the connection string (be sure to make it secret to protect it hehe), and as I pointed to a connection string, it is mandatory to configure the parameter of “Connectionprovidername”, which in my case is just SQL Server.
Some important gotchas here, be sure to test thoroughly your migrations, and be sure to enable the appropriate backups of databases for the rollback cases, this is not easy, and you have to really take care about it, so have different environments of Release Management for test all the deployments and migrations.
Once you have this, next time you run this Build and Release definition, your database will be (hopefully if you have done it correctly) updated to last migration from Entity Framework.
And hopefully, see you later around here with more articles