Managing Application & assembly versioning in an automated release process - azure-pipelines-release-pipeline

I am managing a .net solution containing API Project, Web Project and shared assemblies.
All source code are under VSTS
And I use VSTS release for deploying project in différents environment.
Now I would like adding a version number in my web site and API site (I don't call API endpoint versioning, it's a different story).
For now the only way to do that is to Store the version information in my code and update it as any other part of the code. I would like finding a way to do that directly as part of the release process.
How are you managing the application versioning on automated release process?
Thanks.
regards,

You could store the version in the config file, such as web.config, then read the value in the code.
A simple sample:
Add <appSettings><add key="version" value="#{Release.ReleaseName}#"/></appSettings> to web.config file
Add Replace Tokens task to release
Then, the token (#{Release.ReleaseName}#) will be replaced with the value of Release.ReleaseName variable.
There are many build-in variables in release, you also can add variable to release too.

Related

Deployment multiply releases at once

I have got about 30+ services. Each service has it's own repository, build and release on different environments.
Is it possible to deploy all releases for the latest build artifacts on the specified environment by single command?
There isn’t the built-in command can do it, but you can build a app (e.g. console application, PowerShell) to create release through Rest API: Create a release
You can create an overarching Release pipeline that use all the build artifacts. The downsides of this option are:
duplication of "code" between the single-component pipeline and the overarching one, mitigate using Task Groups
you do not have a simple display of what is deployed in an environment because you have to look in two places (single-component and overarching)

JsonLocalisation - linked translation files in TFS

I am using Visual Studio 2013 and TFS for source control. My solution contains json files with the translations for my app made with the mvvmcross framework. The mvvmcross JsonLocalisation plugin recommends to link the translation files from a commen location to the different projects needing them.
When trying to shelve or check-in these changes, TFS complains about the translation files not being available in the platform projects.... Do any of you guys have a nice solution to that (one that doesn't include branching)?
I'd really like to avoid branching because I then need to merge the files to all my platform projects on every change I make.
How do you solve that using TFS?
I am now certain branch/merge is the best option in TFS. File linking is NOT supported by TFS. I ended up putting my json translation in a resource folder outside the platform specific projects (Droid, Windows Phone and WPF). Then I branched that directory to mentioned projects.
The process for changes are now as follows. Changes made to translation files in i.e. Droid projects must be;
Checked-in in Droid project
Merged from Droid to CommonResource
Checked-in in CommonResource
Merged from CommonResource to WindowsPhone and WPF
Checked*in in Phone & WPF
It makes it a bit more cumbersome compared to File-linking but it'll work...
Best regards
You should package your files for distribution as a NuGet package.
If you create a nuget package you can automate the update and control of the files while making them an external dependency. You then publish your nuget package to a repository (UNC or ProGet) and reference from VS.
If you edit the files you create a new versions package and deploy then update the solutions. You can automate this by having a CI build that created your nuget from the files automatically and publishing.
Look at how the Node, Angular, and other JavaScript nuget packages are composed.

Box-API: How can I add a strong name to a 3rd party assembly written for the .NET Portable Subset

I am trying to strongly name a 3rd party API that I have the code for but it's using a 3rd party DLL/NuGet Package that is also not strongly named and I'm having a lot of trouble.
I'm using the Box Windows SDK and the API was written in the .NET portable subset and supports .NET for Windows Store Apps, .NET Framework 4 and higher, SL4 and higher, and Windows Phone 7 and higher. Granted, I do not need all of these but I do need the .NET 4 and Silverlight versions. The API already works wonderfully and runs fine on its own. It would with my application also, if all my projects were unsigned but they aren't. We use strongly named assemblies for our Silverlight application in order to make use of application library caching.
Anyway, I have the source code for the API so I simply added my PFX file to the project to sign it. I then get an error that a dependency that this API is using called NitoAsnycEx.dll is not signed. I do not have the code for Nito.AsyncEx.dll but normally this isn't such a problem, more of an annoyance. So now I have an age-old problem of needing to take a 3rd party DLL of which I don't have code for and sign it with my PFX or another SNK file.
I can do either and normally I use one of the processes so wonderfully explained in this post by Ian Picknell: http://ianpicknell.blogspot.com/2009/12/adding-strong-name-to-third-party.html. So I have followed that process and the IL signing tools seem to sign the DLL just fine.
To make a long story shorter, let's use the simplest version of the signing process where I already have a simple SNK file ready to go. Basically, I do this:
I can run ILDASM to get the .il file for this 3rd party EXE:
ILDASM Nito.AsyncEx.dll /out:Nito.AsyncEx.il
I can then run ILASM to get the signed DLL:
ILASM Nito.AsyncEx.il /dll /resource=Nito.AsyncEx.res /key=NPSAssemblyKeyNoPassword.snk
It works great and I get this result:
Method Implementations (total): 118
Resolving local member refs: 0 -> 0 defs, 0 refs, 0 unresolved
Writing PE file
Signing file with strong name
Operation completed successfully
So now I have a signed DLL. I go back to my 3rd Party API code and remove the old reference to NitoAsyncEx.dll and put a new one to this. I try to compile and then I get an error like this:
Error 44 The base class or interface 'System.Object' in assembly 'System.Runtime, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' referenced by type 'Nito.AsyncEx.AsyncLock' could not be resolved r:\Data\GM\Source\GrantManagement\GrantManagement\3rd Party\Nito\Nito.AsyncEx.dll
I figure there is some problems using the portable .net library here but I'm not sure what it is. This same process normally works for me for Silverlight 4+ and Full .NET 4.5 framework libraries. Is there another ILASM or ILDASM set somewhere that will disassemble and reassemble the portable code correctly? Is this even possible?
I also tried to go and get the source code for the NitoAsyncEx.dll, which is open source btw, and compile it but that source code will not compile as it's missing some files. So currently I'm stuck with my integration of this API into my project and need a little assistance from any experts in the community.
Is there a way to sign this DLL correctly so we're not missing references to basic classes such as System.Object?
Is there a way to get around needing to sign this DLL at all and having it referenced from my projects?
UPDATED
The Box SDK has been updated and is now strong-named on nuget. This is thanks to the recent update to AsyncEx which strong-named the assembly.
As you mentioned, it's unfortunately out of our control that the NitoAsyncEx library is not strongly named. This library provides the ability to properly lock resources during an async/await call, and I do not believe there is a better alternative at the moment.
This being said, I may have a (hopefully temporary) workaround for you. I've downloaded the source from https://nitoasyncex.codeplex.com/ and was able to get it to compile. These are the steps I performed:
Removed the reference to MSBuild in the csproj
Copied the missing Dequeue.cs file from the packages folder
Resolved missing nuget references
Regenerated the AssemblyInfo.cs
Excluded the .tt template files from the project
Unloaded all other projects the SDK does not use
Here's the resulting solution:
https://cloud.box.com/s/7ikurtyajqmhq9p8q52x
I've successfully ran the resulting dll through the SDK's tests so hopefully this should cover what you need. I cannot guarantee the stability of this method, but having a working source should allow you to do any signing you need. From there, you should be able to drop the signed assembly into the SDK source and sign that assembly as well.

Production vs QA configuration

Time and again I am faced with the issue of having multiple environments that must be configured individually for an application that would run in all of them (e.g. QA, regional production env's, dev, staging, etc.) and I am wondering what would be the best way to organize different configurations?
Would it be in the database? Different configuration files per environment? Or maybe the same file with different sections/xml tags? How would these be then deployed? Embedded within the app? Or put manually in after installation to be modified in-place?
This question is not technology-specific - I've worked with .net and Java, web-apps and desktop apps and this issue comes up time and again. I'm looking to learn different approaches to maybe adapt a hybrid to address this.
EDIT: There's one caveat that I must point out - when configuration is part of the deployed solution, it is generally installed under root user on the host. In large organizations developers usually don't have a root access to production hosts so any changes to the configuration require a new build and deployment. Needless to say this isn't the nicest approach - especially at organizations that have a very strict release process involving multiple teams and approval levels... (sigh I know!)
Borrowed from Jez Humble and David Farley's book "Continuous Delivery (page 41)", you can:
Your build scripts can pull configuration in and incorporate it into your binaries at build time.
Your packaging software can inject configuration at packaging time, such as when creating assemblies, ears, or gems.
Your deployment scripts or installers can fetch the necessary information or ask the user for it and pass it to your application at
deployment time as part of the installation process.
Your application itself can fetch configuration at startup time or run time.
It is considered bad practice by them to inject configuration files in build and compile times, because you should be able to deploy the same binary file to every environments.
My experience was that you could bake all configuration files for every environments (except sensitive information) to your deployment file (war, jar, zip, etc). And you design your application to take in an extra parameter when starts, to pickup the right sets of configuration files (from your extracted deployment file, or from local/remote file system if they are sensitive, or from a database) during application's startup time.
The question is difficult to answer because it's somewhat vague. There is no technology-agnostic approach to configuration as far as I know. Exactly how configuration is set up will depend on the language/technology in question.
I'm not familiar with .net but with java a popular approach is to have a maven build set up with different profiles. Each profile is specific to an environment. You can then define different properties files that have environment-specific values, an example from the above link is:
environment.properties - This is the default configuration and will be packaged in the artifact by default.
environment.test.properties - This is the variant for the test environment.
environment.prod.properties - This is basically the same as the test variant and will be used in the production environment.
You can then build your project as follows:
mvn -Pprod package
I have good news and bad news.
The good news is that Config4* (of which I am the maintainer) neatly addresses this issue with its support for adaptive configuration. Basically, this is the ability for a configuration file to adapt itself to the environment (including hostname, username, environment variables, and command-line options) in which it is running. Read Chapter 2 of the "Getting Started" manual for details. Don't worry: it is a short chapter.
The bad news is that, currently, Config4* implementations exist only for C++ and Java, so your .Net applications are out of luck. And even with C++ and Java applications, it won't make pragmatic sense to retrofit Config4* into an existing application. Because of this, I'd advise trying to use Config4* only in new applications.
Despite the bad news, I think it is worth your while to read the above-mentioned chapter of the Config4* documentation, because doing so may provide you with ideas that you can adapt to fit your needs.

Can I parameterize a CruiseControl.NET project configuration such that the parameters are exposed by the web interface?

I am currently trying to use NAnt and CruiseControl.NET to manage various aspects of my software development. Currently, NAnt handles just about everything, including replacing environment specific settings (e.g., database connection strings) based on an input target that I specify on the command line.
CruiseControl.NET is used to build the application for the default environment (dev) anytime new code is committed. I also want CruiseControl.NET to invoke a build for my additional environments test and stage, but I do not want these to be automatically invoked every time that a dev build invoked (daily) as test and stage deployments happen far less frequently. Test and stage deployments only occur when the application is ready for QA.
I can easily do this by specifying multiple projects, one for each environment. However, I already have many projects configured, one for each milestone in within my application. If I have to setup 3 projects for each milestone the CruiseControl.NET configuration can get out of hand quickly.
Here is my question:
Can I parameterize a CruiseControl.NET project configuration such that the parameters are exposed by the web interface?
Preferably (I think), I could have checkboxes for each environment (e.g., dev, test, stage) exposed in the web interface. A build would be made for each environment that is checked, whether the build was forced or automatic. It would be even better if I could default the checked state.
This feature (Dynamic Build Parameters) is currently being worked on for 1.5, and you can try it out in the nightlies. Here's a post describing the feature.
As Scott has mentioned, this isn't available, but it wouldn't take too much just to write a little template and then auto-generate the ccnet.config file given that template and a list of environments in a mail-merge type way.
Unfortunately, you can't do anything like that with CruiseControl.NET. It's a good idea, so you might want to submit it as a feature request.
This is fully supported now starting with cruisecontrol 1.5: http://cruisecontrolnet.org/projects/ccnet/wiki/Parameters