title: NuGet release management
body: <p>I have for the first time made something I want to share on NuGet, but I am not sure how this "release preparation" is done.</p>
  
  <p>At the moment my following steps are:</p>
  
  <ol>
  <li>Manually change the assembly version  of my main assembly (<code>MyAssembly</code>) in <code>AssemblyInfo.cs</code> from <code>1.0.0.0</code> to <code>1.1.0.0</code></li>
  <li>Build the main assembly release version in Visual Studio</li>
  <li>Pack the release for my main assembly (<code>nuget pack -prop configuration=release</code> == <code>MyAssembly.1.1.0.0.nupkg</code>)</li>
  <li>Publish this package to NuGet (<code>nuget push MyAssembly.1.1.0.0.nupkg</code>)</li>
  <li>Update the NuGet packages for assemblies referring <code>MyAssembly</code> (e.g. <code>MyAssembly.Web.Mvc</code> gets its <code>MyAssembly</code> updated from <code>v1.0.0.0</code> -> <code>v1.1.0.0</code> using the NuGet Package Manager) defined in packages.config</li>
  <li>Change the version <code>AssemblyInfo.cs</code> of <code>MyAssembly.Web.Mvc</code> to <code>1.1.0.0</code>, build release, NuGet pack and publish</li>
  <li>Repeat step 6 for all my references assemblies</li>
  </ol>
  
  <p>This is some steps that are a PITA, and I will some day make an error and break the release.</p>
  
  <p>This got me think, am I missing a crucial point, am I doing all this wrong?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Based on the knowledge @ialekseev provided, I have now created this:</p>
  
  <p>Build.ps1</p>
  
  <pre><code>Param(
      [Parameter(Mandatory=$true)]
      [string]$version,
      [string]$configuration = "Release",
      [boolean]$tests = $false,
      [boolean]$publish = $false,
      [boolean]$pack = $false,
      [string]$outputFolder = "build\packages"
  )
  
  # Include build functions
  . "./BuildFunctions.ps1"
  
  # The solution we are building
  $solution = "NerveFramework.sln"
  $assemblies = "NerveFramework", "NerveFramework.Web", "NerveFramework.Web.Mvc", "NerveFramework.Web.WebApi"
  
  # Start by changing the assembly version
  Write-Host "Changing the assembly versions to '$version'..."
  $assemblyInfos = Get-ChildItem $assemblies -Filter "AssemblyInfo.cs" -Recurse | Resolve-Path -Relative
  foreach ($assemblyInfo in $assemblyInfos) {
      ChangeAssemblyVersion $assemblyInfo $version
  }
  
  # Build the entire solution
  Write-Host "Cleaning and building $solution (Configuration: $configuration)"
  BuildSolution $solution $configuration
  
  # Change dependency version on all depending assemblies
  Write-Host "Changing the NerveFramework(s) NuGet Spec version dependencies to '$version'..."
  $nuspecs = Get-ChildItem $assemblies -Filter "NerveFramework*.nuspec" -Recurse | Resolve-Path -Relative
  foreach ($nuspec in $nuspecs) {
      ChangeNugetSpecDependencyVersion $nuspec "NerveFramework" $version
  } 
  
  # Pack the assemblies and move to output folder
  if ($pack) {
      Write-Host "Packaging projects..."
      $projects = Get-ChildItem $assemblies -Filter "NerveFramework*.csproj" -Recurse | Resolve-Path -Relative
      foreach ($project in $projects) {
          PackProject $project $configuration $outputFolder
      } 
  }
  
  # Publish the assemblies
  if ($publish) {
      Write-Host "Publishing packages..."
      $packages = Get-ChildItem $outputFolder -Filter "*$version.nupkg" -Recurse | Resolve-Path -Relative
      foreach ($package in $packages) {
          PublishPackage $package
      } 
  }
  </code></pre>
  
  <p>BuildFunctions.ps1</p>
  
  <pre><code>Function BuildSolution() {
  
      Param(
          [Parameter(Mandatory=$true)]
          [string]$solution,
          [Parameter(Mandatory=$true)]
          [string]$configuration
      )
  
      # Set the path to the .NET folder in order to use "msbuild.exe"
      $env:PATH = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319"
  
      Invoke-Expression "msbuild.exe $solution /nologo /v:m /p:Configuration=$configuration /t:Clean"
      Invoke-Expression "msbuild.exe $solution /nologo /v:m /p:Configuration=$configuration /clp:ErrorsOnly"
  }
  
  Function ChangeAssemblyVersion() {
  
      Param(
          [Parameter(Mandatory=$true)]
          [string]$filePath,
          [Parameter(Mandatory=$true)]
          [string]$publishVersion
      )
  
      Write-Host "-- Updating '$filePath' to version '$publishVersion'"
  
      $assemblyVersionPattern = 'AssemblyVersion\("[0-9]+(\.([0-9]+|\*)){1,3}"\)'
      $assemblyVersion = 'AssemblyVersion("' + $publishVersion + '")';
      $assemblyFileVersionPattern = 'AssemblyFileVersion\("[0-9]+(\.([0-9]+|\*)){1,3}"\)'
      $assemblyFileVersion = 'AssemblyFileVersion("' + $publishVersion + '")';
  
      (Get-Content $filePath -Encoding utf8) | ForEach-Object { 
              % { $_ -Replace $assemblyVersionPattern, $assemblyVersion } |
              % { $_ -Replace $assemblyFileVersionPattern, $assemblyFileVersion } 
      } | Set-Content $filePath
  }
  
  Function ChangeNugetSpecDependencyVersion() {
  
      Param(
          [Parameter(Mandatory=$true)]
          [string]$filePath,
          [Parameter(Mandatory=$true)]
          [string]$packageId,
          [Parameter(Mandatory=$true)]
          [string]$publishVersion
      )
  
      [xml] $toFile = (Get-Content $filePath)
      $nodes = $toFile.SelectNodes("//package/metadata/dependencies/dependency[starts-with(@id, $packageId)]")
      if ($nodes) {
          foreach ($node in $nodes) {
              $nodeId = $node.id
              Write-Host "-- Updating '$nodeId' in '$filePath' to version '$publishVersion'"
              $node.version = "[" + $publishVersion +"]"
              $toFile.Save($filePath)
          }
     }
  }
  
  Function PackProject() {
  
      Param(
          [Parameter(Mandatory=$true)]
          [string]$project,
          [Parameter(Mandatory=$true)]
          [string]$configuration,
          [Parameter(Mandatory=$true)]
          [string]$outputFolder
      )
  
      if (!(Test-Path -Path $outputFolder)) {
          New-Item $outputFolder -Type Directory
      }
  
      Write-Host "-- Packaging '$project'"
      Invoke-Expression ".nuget\NuGet.exe pack $project -OutputDirectory '$outputFolder' -Prop Configuration=$configuration"
  }
  
  Function PublishPackage() {
  
      Param(
          [Parameter(Mandatory=$true)]
          [string]$package
      )
  
      Write-Host "-- Publishing '$package'"
      Invoke-Expression ".nuget\NuGet.exe push $package"
  
  }
  </code></pre>
  
  <p>Run like <code>.\Build -version 1.2.0.0 -pack $true</code></p>