Skip to content

Commit 268e12d

Browse files
author
Jake Ginnivan
committed
Added some better docs about how to use with Octopus deploy
1 parent 05161c3 commit 268e12d

File tree

2 files changed

+135
-28
lines changed

2 files changed

+135
-28
lines changed

docs/build-server-support/build-server/octopus-deploy.md

Lines changed: 132 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,138 @@ While not a build server, there are a few things to consider when using Octopus
55

66
Because Octopus Deploy uses NuGet like this you cannot continue to push revisions in this manner without some intervention (or changes to GitVersion's configuration). To work around this problem we have two possible options:
77

8-
## Solutions
9-
### Publish your 'release' branch to Octopus deploy
10-
With this approach you will not automatically push every build of your release branch into the NuGet feed that Octopus is consuming. Instead you'll choose which revisions become an Octopus release, and use git tags to keep the NuGet version incrementing as needed. When you have a release version that should be published to Octopus, you push the NuGet package, but also tag the source commit with the desired version. This will cause GitVersion to increase the version for the *next* commit, and you can then combine a series of commits into a new Octopus package.
11-
12-
This has the advantage that if you have a multi-stage deployment pipeline you pick packages which you would like to start through the pipeline, then you can see all the versions which did not make it through the pipeline (for instance, they got to UAT but not production due to a bug being found). In the release notes this can be mentioned or those versions can be skipped.
13-
14-
The following shows an example with the corresponding git commands:
15-
16-
1. Assume your build server has a release build that should be published
17-
- Current semver is `1.0.0-beta.1+0`
18-
- Current NuGet package is `1.0.0-beta0001`
19-
2. This NuGet package is pushed to the Octopus deploy feed and starts the deployment lifecycle
20-
3. After deploying, tag the current commit with the semver so GitVersion will start incrementing on the *next* commit
21-
- `git tag 1.0.0-beta.1`
22-
- Note, with this tag GitVersion won't increment the reported version until a new commit happens
23-
4. Push this tag to the origin so it's available to the build server
24-
- `git push --tags` (or just push the specific tag)
25-
3. Now you can commit changes to the release branch and see the version increment (e.g., after 4 commits):
26-
- Current semver is now `1.0.0-beta.2+4`
27-
- NuGet version is now `1.0.0-beta0002`
28-
- Since we tagged the repo in step 3 GitVersion is automatically incrementing both the semver and NuGet versions
29-
4. We can now build this and push the package to Octopus since our NuGet version has incremented
30-
5. Now each time you deploy the package you should re-tag the repo with the version deployed
31-
- So here we'd tag it like so: `git tag 1.0.0-beta.2`
32-
- Don't forget to push the tag to the origin: `git push --tags`
33-
6. Repeat as needed
34-
35-
This approach works well with Semantic Versioning, as you will not be burning version numbers between releases (except if a build fails to get through UAT or something, then the burnt number means something!).
8+
The solutions to this issue are a bit different for GitHubFlow and GitFlow.
9+
10+
## GitHubFlow Solutions
11+
### Promote to Octopus feed
12+
The first option is to keep the continuous delivery default in GitVersion, depending on which build server you have this approach may or may not work for you.
13+
For instance in TFS Build vNext you cannot chain builds to publish artifacts built in one build in another.
14+
15+
1. Your CI build creates the stable NuGet package
16+
- Do *not* publish this package into the Octopus nuget feed
17+
2. When you want to push a package into the Octopus deployment pipeline you trigger the second build
18+
- it will either take the package built from the first build in the chain (your CI build?) or rebuild
19+
- It will publish that package into the Octopus deploy feed
20+
- The build then is *tagged* with the version, this will cause GitVersion to increment the version
21+
22+
This means that CI builds are *not* available to Octopus deploy, there will be a manual build in your *build server* which pushes the package to Octopus deploy.
23+
24+
### Tag to release
25+
Another simple option is to tag a stable version to release, the basic idea is:
26+
27+
1. GitVersion is set to continuous deployment mode, so master will create `-ci.x` pre-release builds
28+
1. CI Builds only create NuGet packages for stable builds
29+
1. You tag master with a stable version of the next version then push it
30+
1. The CI build triggers, GitVersion will always respect tags so you will get a stable version
31+
1. The stable package will be pushed to Octopus
32+
1. Because of the tag, then next build will be incremented and will be producing pre-release packages of the next build
33+
34+
35+
#### Script to create the release
36+
Here is an example script which could be used to tag the stable version, it uses GitVersion to calculate the version so you just run `./CreateRelease.ps1` and it will tag and push the tag.
37+
38+
``` powershell
39+
[CmdletBinding()]
40+
param()
41+
42+
##### Config #####
43+
# Path to GitVersion.exe
44+
$gitversion = "tools\GitVersion\GitVersion.exe"
45+
function Create-AdditionalReleaseArtifacts
46+
{
47+
param( [string]$Version )
48+
49+
# Put any custom release logic here (like generating release notes?)
50+
}
51+
### END Config ###
52+
53+
$ErrorActionPreference = "Stop"
54+
trap
55+
{
56+
Pop-Location
57+
Write-Error "$_"
58+
Exit 1
59+
}
60+
61+
Push-Location $PSScriptRoot
62+
63+
# Make sure there are no pending changes
64+
$pendingChanges = & git status --porcelain
65+
if ($pendingChanges -ne $null)
66+
{
67+
throw 'You have pending changes, aborting release'
68+
}
69+
70+
# Pull latest, fast-forward only so that it git stops if there is an error
71+
& git fetch origin
72+
& git checkout master
73+
& git merge origin/master --ff-only
74+
75+
# Determine version to release
76+
$output = & $gitversion /output json
77+
$versionInfoJson = $output -join "`n"
78+
79+
$versionInfo = $versionInfoJson | ConvertFrom-Json
80+
$stableVersion = $versionInfo.MajorMinorPatch
81+
82+
# Create release
83+
Create-AdditionalReleaseArtifacts $stableVersion
84+
# Always create a new commit because some CI servers cannot be triggered by just pushing a tag
85+
& git commit -Am "Create release $stableVersion" --allow-empty
86+
& git tag $stableVersion
87+
if ($LASTEXITCODE -ne 0) {
88+
& git reset --hard HEAD^
89+
throw "No changes detected since last release"
90+
}
91+
92+
& git push origin master --tags
93+
94+
Pop-Location
95+
```
96+
97+
#### Sample build script (build.ps1)
98+
``` powershell
99+
[CmdletBinding()]
100+
param()
101+
$ErrorActionPreference = "Stop"
102+
trap
103+
{
104+
Pop-Location
105+
Write-Error "$_"
106+
Exit 1
107+
}
108+
Push-Location $PSScriptRoot
109+
110+
# Tools
111+
$gitversion = "tools\GitVersion\GitVersion.exe"
112+
$octo = "tools\Octo\Octo.exe"
113+
$nuget = "tools\NuGet\NuGet.exe"
114+
# Calculate version
115+
$output = & $gitversion /output json /l GitVersion.log /updateAssemblyInfo /nofetch
116+
if ($LASTEXITCODE -ne 0) {
117+
Write-Verbose "$output"
118+
throw "GitVersion Exit Code: $LASTEXITCODE"
119+
}
120+
121+
$versionInfoJson = $output -join "`n"
122+
Write-Host $versionInfoJson
123+
124+
$versionInfo = $versionInfoJson | ConvertFrom-Json
125+
$nugetVersion = $versionInfo.NuGetVersion
126+
127+
#Build your project here
128+
msbuild MyProj.sln
129+
130+
# Only create nuget package for stable
131+
if ($versionInfo.PreReleaseTag -eq '')
132+
{
133+
Write-Host
134+
Write-Host "Creating a release" -ForegroundColor Magenta
135+
136+
# You probably want to specify output directory too
137+
& $nuget pack "src\myProj\MyProj.nuspec" -version $nugetVersion
138+
}
139+
```
36140

37141
### Configure GitVersion to [increment per commit](../../more-info/incrementing-per-commit.md)
38142
As mentioned above, this means you will burn multiple versions per release. This might not be an issue for you, but can confuse consumers of your library as the version has semantic meaning.

docs/faq.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
## Why is my version not incrementing?
44
GitVersion calculates the semantic version, this will only change once per *release*. Read more at [version increments](more-info/version-increments.md)
55

6+
## I'm using Octopus deploy
7+
Because Octopus deploy cannot have the same version of a package to a NuGet feed. There is no magic solution to this, but you can read more about your options at [octopus deploy](build-server-support/build-server/octopus-deploy.md).
8+
69
## How can GitVersion run for a shallow clone or checkout on server working directories
710
GitVersion needs a proper git repository to run, some build servers do not do a proper clone which can cause issues. GitVersion has a feature called [dynamic repositories](more-info/dynamic-repositories.md) which solves this by cloning the repository and working against that clone instead of the working directory.
811

0 commit comments

Comments
 (0)