Skip to content

Latest commit

 

History

History
198 lines (147 loc) · 8.93 KB

cloudbuild.md

File metadata and controls

198 lines (147 loc) · 8.93 KB

Cloud build support

Nerdbank.GitVersioning implicitly supports all cloud build services and CI server software because it simply uses git itself and integrates naturally in MSBuild, gulp and other build scripts.

Requirements

  1. Your CI build should be configured to actually clone the git repo rather than download sources (i.e. the '.git' folder is required).
  2. Do not enable any 'shallow clone' option on your CI build, as that erases git history that is required for accurate version calculation.

GitHub Actions

In GitHub Actions, actions/checkout@v1 checks out a deep clone, which is great. But actions/checkout@v2 checks out a shallow clone by default, so you'll have to tell it to perform a deep clone:

- uses: actions/checkout@v2
  with:
    fetch-depth: 0 # avoid shallow clone so nbgv can do its work.

Azure Pipelines

Azure Pipelines behavior has changed for new pipelines such that build agents now default to creating shallow clones. You can defeat this, thereby forcing a full history clone by adding this to the top of your steps list:

steps:
- checkout: self
  fetchDepth: 0

In particular, setting fetchDepth: 0 will cause Azure Pipelines to not do shallow clones.

See this example change.

Read more about this and how to configure shallow cloning when not using YAML files in Microsoft documentation.

Optional features

By specifying certain cloudBuild options in your version.json file, you can activate features for some cloud build systems, as follows:

Automatically match cloud build numbers to your git version

Cloud builds tend to associate some calendar date or monotonically increasing build number to each build. These build numbers are not very informative, if at all. Instead, Nerdbank.GitVersioning can automatically set your cloud build's build number to equal the semver version calculated during your build.

Enable this feature by setting the cloudBuild.buildNumber.enabled field in your version.json file to true, as shown below:

{
  "version": "1.0",
  "cloudBuild": {
    "buildNumber": {
      "enabled": true
    }
  }
}

When any cloud build starts, a build number is initially generated by the CI server until the build itself overrides it as this option will cause it to do. If a build aborts before the build reassigns the build number, it will remain at the cloud assigned build number. This can show up in your build history with some failed builds having a different versioning scheme than passing or some other failed builds.

When you enable this feature, consider whether this will cause the generated build numbers to overlap with those generated by the cloud build previously or in the future. For example, AppVeyor defaults to assigning build numbers with a 1.0.x notation where x increases. If your version.json file sets your version to "1.0", the generated build numbers can overlap, making AppVeyor fail builds due to a non-unique number. To avoid this, make sure that your CI build creates initial build numbers that do not overlap with those produced by semantic versioning. For instance, you can set your appveyor build's version to 1.1000 or 50.0 so that your regular semantic version build numbers are in an entirely unique range.

Set special build variables for use in subsequent build steps

Build variable MSBuild property Sample value
GitAssemblyInformationalVersion AssemblyInformationalVersion 1.3.1+g15e1898f47
GitBuildVersion BuildVersion 1.3.1.57621
GitBuildVersionSimple BuildVersionSimple 1.3.1

This means you can use these variables in subsequent steps in your cloud build such as publishing artifacts, so that your richer version information can be expressed in the publish location or artifact name.

This feature is enabled by default via the cloudBuild.setVersionVariables field in your version.json file, which defaults as shown below:

{
  "version": "1.0",
  "cloudBuild": {
    "setVersionVariables": true // the default value
  }
}

There are many more MSBuild variables that the build will set within the build. To make all these available as cloud variables (prefixed with NBGV_), you can set the cloudBuild.setAllVariables field to true:

{
  "version": "1.0",
  "cloudBuild": {
    "setVersionVariables": true,
    "setAllVariables": true
  }
}

Setting both of these fields to true means that a few variables will be defined in the cloud build server twice -- one set with the names in the table above and the other (full) set using the NBGV_ prefix.

Set cloud build variables only once in a build

While each individual MSBuild project has its own version computed, the versions across projects are usually the same so long as you have one version.json file at the root of your repo. If you choose to enable setting of cloud build variables in that root version.json file, each project that builds will take a turn setting those cloud build variables. This is perhaps more work than is necessary, and when some projects compute versions differently it can lead to inconsistently defined cloud build variables, based on non-deterministic build ordering of your projects.

You can reduce log message noise and control for non-deterministic cloud build variables by disabling all the settings under the cloudBuild options in your root version.json file (including disabling default behavior):

{
  "version": "1.0",
  "cloudBuild": {
    "setVersionVariables": false // override the default value of true
  }
}

Two options are described below to set the cloud build number and variables just once in your build.

Set the cloud build number as a build step

The nbgv CLI tool can be used to set the cloud build number and variables. Your CI build script should include these two commands:

dotnet tool install --tool-path . nbgv
.\nbgv cloud

The above will set just the cloud build number, but switches you can add to the nbgv cloud command will cause other build variables to also be set.

See a working sample in a VSTS YAML file.

https://github.com/Humanizr/Humanizer/blob/11bd9fd99c151f2e84eb9d4fa082a6c077504c9f/azure-pipelines.yml#L21-L29

Set them from just one project

After ensuring that your root version.json file does not set cloudBuild.buildNumber.enabled=true, define an additional version.json file inside just one project directory that inherits from the base one, like this:

{
  "inherit": true,
  "cloudBuild": {
    "buildNumber": {
      "enabled": true
    },
    "setVersionVariables": true,
    "setAllVariables": true
  }
}

CI Server specific configurations

GitHub Actions (v2)

We define a GitHub Action that installs the nbgv CLI tool, provides version data as action outputs, and optionally sets environment variables. Check out nerdbank-gitversioning on the GitHub Actions marketplace.

TeamCity

TeamCity does not expose the build branch by default as an environment variable. This can be exposed by adding an environment variable called BUILD_GIT_BRANCH with the value of %teamcity.build.vcs.branch.<vcsid>% where <vcsid> is the root id described on the TeamCity VCS roots page. Details on this variable can be found on the TeamCity docs.

Docker build

When building inside a docker container, special considerations may apply:

  1. Make sure the container has access to the entire repo, including the .git directory.
  2. Certain environment variables from the CI system may need to be exposed to the container. When a CI system checks out a 'detached head', computing the version relies on environment variables to know which 'branch' was checked out, among other things. You can look up the specific environment variables that are necessary for your particular CI service by looking for their names in the src/NerdBank.GitVersioning/CloudBuildServices directory of this repo. For example these lines identify the two environment variables that are required for an Azure Pipelines CI system. When using docker run yourself in your build script, you can add --env BUILD_SOURCEBRANCH --env SYSTEM_TEAMPROJECTID to your command line to pass-through those environment variables to your container.