Search code examples
azureazure-devopsartifactorydevopsgitversion

How do I upload Artifacts depending on Release or Prerelease to Artifactory using GitVersion on Azure DevOps?


I prefer to organize my artifacts in Artifactory in a hierarchy of Repo[dev|test|prod] -> Artifact Name -> Releases Artifacts go here -> Pre-Releases go into a sub-folder.

Why? So when I am navigating the Artifactory Repository Browser I don't have an exceedingly long tree. I can expand a repository and see the first level by artifact name and still not see any artifacts, then expand the artifact name leaf and then see my released artifacts. But, the top item underneath will be a sub-directory folder called "prerelease". This is done so I can easily manually delete all my pre-releases if I wish to do so in one action, or schedule to clean them up.

[My Repo]
|
+-\prerelease\
|   |--artifact-1.2.3-ci0004.nupkg
|   |--artifact-1.0.1-ci0002.nupkg
|--artifact-1.0.0.nupkg
|--artifact-1.0.1.nupkg

I know how to use the Artifactory filespec to upload the package to my repository:

** For Pre-Release
{
  "files": [
    {
      "pattern": "$(build.artifactstagingdirectory)\*.nupkg",
      "target": "myrepo-nuget-dev-local/$(PackageName)/prerelease/"
    }
  ]
}

** For Release
{
  "files": [
    {
      "pattern": "$(build.artifactstagingdirectory)\*.nupkg",
      "target": "myrepo-nuget-dev-local/$(PackageName)/"
    }
  ]
}

What I need to do is put each file spec into its own build step and then add conditions that will execute EITHER one build step OR the other, but never both. Why? Because the build artifact will ever be a pre-release or a release artifact but never both. I am using GitVersion and Git Tags along with Azure DevOps.

So the question: What does the Custom Condition need to be to get this working?


Solution

  • This logic should work for any CI system, but this syntax will work for Azure DevOps.

    How to create these can be found here: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/expressions?view=azure-devops

    Here is what it looks like:

    enter image description here

    For Pre-Release:

    and(succeeded(), not(startsWith(variables['GitVersion.BranchName'], 'tags/')), or(ne(variables['GitVersion.PreReleaseLabel'], ''),ne(variables['GitVersion.BuildMetaData'], '')))
    

    This is saying all 3 conditions MUST be met:

    1. if succeeding
    2. GitVersion.BranchName does not start with 'tags/' (this makes sure this build event was not triggered by a tag), and,
    3. GitVersion.PreReleaseLabel is not empty OR GitVersion.BuildMetaData is not empty

    For Release:

    and(succeeded(), or(and(eq(variables['GitVersion.PreReleaseLabel'], ''), eq(variables['GitVersion.BuildMetaData'], ''), eq(variables['GitVersion.BranchName'], 'master')), startsWith(variables['GitVersion.BranchName'], 'tags/')), ne(variables['Build.Reason'], 'PullRequest'))
    

    This is saying all 3 conditions MUST be met:

    1. if succeeding
    2. (GitVersion.PreReleaseLabel is empty AND GitVersion.BuildMetaData is empty AND GitVersion.BranchName is 'master') OR (GitVersion.BranchName starts with 'tags/')
    3. Build.Reason is not 'PullRequest'

    Here is what it looks like:

    enter image description here