Search code examples
tfscontinuous-integrationtfsbuild

How to reproduce old/previous builds in TFS Build?


Environment:

  • TFS 2018 with source code in TFS Git
  • developers are using gitflow-like workflow (main, develop and short-lived feature branches)
  • there is a build definition used for CI (off of develop branch)
  • ... and another one for releases (off of main branch)
  • as project evolves build definitions get updated (new steps, etc)

What is the best approach that allows reproduction of previous builds (or, at minimum, release builds)? (in case if previously made build was lost in boating accident)

Ideally I need to be able to plug in version (e.g. 8.5.12345.1) somewhere, press OK and eventually receive data identical to that produced by corresponding build in the past.


Solution

  • Your best approach is to switch to YAML builds and releases. That way your pipeline is versioned together with the code.

    If you don't do that, you may need to clone your build and releases every time you make breaking changes.

    Alternatively, use the version diff view in your pipeline to go back to an older version or use the json to create a new definition using the API.

    Upgrading to Azure DevOps Servers 2020 will give you more advanced YAML features not yet available in Team Foundation Server 2018.

    Note: for truly reproducible builds, you'll need to also find a way to lock the build tasks themselves, TFS and Azure DevOps will automatically roll forward to the latest minor version of a given build task. While task authors should try to prevent any breaking changes in those minor upgrades there are no guarantees. You can also never rely on any tool installers that use a v2.x notation or a task that relies on latest. Azure DevOps isn't ideally suited for full reproducible builds.

    You can pin task versions in YAML now, if I remember correctly, this was added in Azure DevOps 2020.

    You can set which minor version gets used by specifying the full version number of a task after the @ sign (example: GoTool@0.3.1). You can only use task versions that exist for your organization.

    See: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/tasks?view=azure-devops&tabs=yaml#task-versions

    The Tasks docs offer special scripts to pin the versions of out-of-the-box tasks as well.