Skip to content

Getting Started

Jay Clark edited this page Feb 16, 2019 · 23 revisions

Note: AutoAppVersion has been designed initially to work with Azure DevOps pipelines and DotNet Core projects.

AAV: Quick Setup Guide.

Follow these steps to get things rolling as quickly as possible. After that, have a play.

1. Setup Your Project File: In your project file (.csproj or .vbproj), make sure you have a version element. If you're looking for this extension then you will most likely know exactly what that is already. If not, it should be defined something like this:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>...</TargetFramework>
        <PackageId>...</PackageId>
        <Version>1.0.0</Version>
    </PropertyGroup>
    ...
</Project>

2. Add This Extension: from the MarketPlace, then add the task to your primary agent job. Make sure this task is before any other task that depends on the app's version information.


Agent Job Task


3. Configure Your Mask: Tell AAV which version segment you want to automate (major, minor or patch). In this case we'll automate the patch segment. Set AAV's Version Mask Override property like so:



4. Setup Build Variables.

  • A VersionVariable to hold the the latest version number. (Ideally, you should initiate this with your app's current version e.g '3.6.24'). This variable will be automatically updated by AAV and used to provide a new version number on each build. In the screenshot below, I have called mine AutoVersion.
  • A variable to hold your DevOps Personal Access Token. Why do you need a PAT? AAV has to update your VersionVariable via the DevOps api. Your PAT is required for authentication.

Variables


5. Populate The Task Inputs:

  • select the target project file (.csproj or .vbproj). This will be the file where you just set your version mask.
  • Set the name of the VersionVariable used to store the current version. (In the screenshot above I used AutoVersion).
  • Provide your DevOps personal access token. I have used a variable to hold this value (DevOpsPAT in the above screen shot).

Note: The minimum permissions required for your Personal Access Token are Build: Read & Execute.


AutoAppVersion Task Inputs


6. Save and Test: Save your build definition, then commit your project changes, and let your pipeline do the rest.

What exactly is going on?

AAV will read the selected project file, looking for the version element. Depending on the the version mask, and a version number saved from your previous build, a new version number will be generated. The new version number will be saved back into the build's project file. Additional pipeline tasks such as deploying and packing will now make use of the new, incremented, version number inside the project file.

AAV will also update your build's VersionVariable via the Azure DevOps Api. (This is why your DevOps PAT is required for authenticating the request). If you keep an eye on your VersionVariable you will see it automaticvally increment after each build or release.

Why would anyone need this?

I simply made this because I kept on forgetting to update my version number whenever I committed a change. Utilising Azure DevOps CD/CI pipelines, and in some cases automatically re-packing and pushing packages meant that, if (and when) I forgot to update the version number, the release pipeline would fail because "Package with same name and Version number already exists"

A little more detail.

Set your version number in your project file. It is here you will be defining your version mask. Typically if you are planning on packaging your project, you will already have a <PropertyGroup> element which defines certain package information including <Version>. It's the <Version> element we care about.

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>...</TargetFramework>
        <PackageId>...</PackageId>
        <Version>1.0.0</Version>
    </PropertyGroup>
    ...
</Project>

Note: Your project file may have multiple <PropertyGroup> elements. This isn't a problem. However, AAV will only check the first instance of a <PropertyGroup> element for the <Version> element. Long story short, put your package info <PropertyGroup> element with the <Version> element before any others.

Decide which segment of your version number you want to automate. Though you can automate the Major, Minor and Patch segments, it is suggested you only automate the patch segment. Setting a segment's value with $ informs AAV that this segment is to be automated.



AAV only cares about the masked segments ( $ ), the other segments will be ignored. With that in-mind, a valid version format still needs to be provided.

Task options.

Option Group: Other Options

  • Set Assembly Version: Write the newly generated version into the the specified project file's <AssemblyVersion> if present.
  • Set File Version: Write the newly generated version into the specified project file's <FileVersion> if present.
  • Environment Variable Name: If set, AAV will apply the newly generated version number to to an environment variable with the specified name. This environment variable and it's value will be available to all preceding tasks.
  • Version Mask Override: Allows you to provide a version mask which will be applied to your current project version.

Option Group: Warning Actions

  • Stop On No Mask: If AAV doesn't detect a masked version number in the specified project file, stop the build.
  • Stop On Downgrade: If AAV detects a version number downgrade in the specified project, stop the build.
  • Stop On Invalid Environment Variable Name: Stop the build if AAV detects you have provided an invalid environment variable name.

Note: An environment variable name should be less than 256 characters and not contain Any whitespace.

Set Assembly Version and File Version.

If Set Assembly Version or Set File Version have been selected, their corresponding element should exist in the same <PropertyGroup> as your <Version> element.

<PropertyGroup>
    ...
    ...
    <Version>1.0.0</Version>
    <AssemblyVersion></AssemblyVersion>
    <FileVersion></FileVersion>
</PropertyGroup>

The contents of the corresponding element will be overwritten when the AAV task runs. Your project file will look something like this on completion.

<PropertyGroup>
    ...
    ...
    <Version>1.0.11</Version>
    <AssemblyVersion>1.0.11.0</AssemblyVersion>
    <FileVersion>1.0.11.0</FileVersion>
</PropertyGroup>

Note: If the corresponding elements are missing from the PropertyGroup, AAV will skip attempting to set the value/values and continue.

General automated behaviour.

A masked segment can mutate in two ways. Standard incrementation, 1, 2, 3, 4 and reset. Reset sets the segment back to 0.

Incrementing higher priority segments will result in lower priority, masked segments being set back to 0.

Major (Highest Priority)
Minor (Medium Priority)
Patch (Lowest Priority)

If we take the version mask example above 0.0.$ and combine it with a version element <Version>1.0.0</Version>. The final version output will always start with 1.0. and patch will be incremented. Lets say you've deployed, several times, without manually updating your Major and Minor versions, and the current version number is 1.0.14. Incrementing either Major or Minor segments now will cause the patch value to return to 0.

e.g from <Version>1.0.0</Version> to <Version>1.1.0</Version> the next output number will be 1.1.0, 1.1.1, 1.1.2 etc.

The same will happen if you increment the Major version:

e.g from <Version>1.1.0</Version> to <Version>2.1.0</Version> the next output number will be 2.1.0, 2.1.1, 2.1.2 etc.

Any version segment that is hardcoded is still your responsibility to maintain. In the examples above, if you had changed your minor version number from <Version>1.0.0</Version> to <Version>1.1.0</Version>, then you wanted to increase the major version to 2, it is your responsibility to reset the minor version e.g <Version>2.0.0</Version>. AAV will acknowledge this change and set the patch value back to 0 on the next deployment.

AAV will now save the new version number so it knows where to increment from, on the next build. This is done by api, a http request is made against the current pipeline definition and the specified VersionVariable is updated.

Finally, the newly calculated version number is saved back to the project file, ultimately overwriting the mask. Don't be alarmed by this. These files are only for use during this particular build or release.

Note: Currently version suffix isn't supported (the hyphen on the patch version) e.g. '10.6.9-rc'

What happens if...

Here's what happens if you mask your version number any other way then outlined above.

(the masked values here are a combination of the mask and the project file's version):

2.$.0 = 2.0.0, 2.1.0, 2.2.0, 2.3.0
2.$.6 = 2.0.6, 2.1.6, 2.2.6, 2.3.6
$.0.0 = 0.0.0, 1.0.0, 2.0.0, 3.0.0
$.5.8 = 0.5.8, 1.5.8, 2.5.8, 3.5.8

Multi masking.

(the masked values here are a combination of the mask and the project file's version)

$.5.$ = 0.5.0, 1.5.0, 2.5.0, 3.5.0
1.$.$ = 1.0.0, 1.1.0, 1.2.0, 1.3.0
$.$.$ = 0.0.0, 1.0.0, 2.0.0, 3.0.0

Notice how second or third masked values are always 0. This is because a higher priority segment value has been increased. AAV will always set lower priority masked segments to 0 if it detects a higher priority segment's value has increased.