如何使用 GitVersion 环境变量

How to use GitVersion Environment variables

我有一个项目是通过 AppVeyor 构建的。构建顺序如下:

  1. 安装和运行Git版本
  2. 构建项目
  3. 使用评估的版本号创建包。

最后一步由 PowerShell 命令完成:

nuget pack path/tofile.nuspec -Version (get-item env:GitVersion_InformationalVersion).Value

如您所见,版本取自 GitVersion 定义的环境变量。 现在我想将构建迁移到 FAKE 构建脚本。

我在脚本中定义了这些依赖项。

"Clean"
  =?> ("GitVersion", Choco.IsAvailable)
  ==> "RestorePackages"
  ==> "BuildApp"
  ==> "CreatePackage"
  ==> "Default"

Git 版本步骤很简单。

Target "GitVersion" (fun _ ->
    "gitversion.portable" |> Choco.Install id
    Shell.Exec("gitversion","/l console /output buildserver" ) |> ignore
)

我可以在我的日志中看到变量是由 Git版本设置的。

Adding Environment Variable. name='GitVersion_SemVer' value='1.1.1-xxx'

下一步是创建包。

Target "CreatePackage" (fun _ ->
    TraceEnvironmentVariables()
    let version = 
        match buildServer with 
        | AppVeyor -> environVar "GitVersion_SemVer"
        | _ ->  baseVersion + "-local"
    NuGet (fun p -> 
        {p with
            OutputPath = packagingDir
            WorkingDir = "."
            Version = version
            Publish = false }) 
            nuspecFileName
)

我正在打印所有定义的变量,之后我试图通过读取变量并将其分配给 version 来获取版本。

不幸的是,当我 运行 构建时,version 仍然是空的。添加 TraceEnvironmentVariables() 方法调用后,我可以看到输出中显示了 GitVersion 定义的 none 个变量。

正如 John Palmer 和 dustinmoris 所说,由 Shell.Execute 启动的进程将所有变量设置为进程级变量。

有没有办法使用Shell.Execute让进程可以设置全局范围的环境变量?

UPD

作为解决方法,我在 AppVeyor.yml 配置文件中添加了额外的步骤:

init:
  - git config --global core.autocrlf input
install: 
  - choco install gitversion.portable -y
before_build:
  - ps: gitversion /l console /output buildserver /b (get-item env:APPVEYOR_REPO_BRANCH).Value 

build_script:
  - cmd: build.bat BuildApp

在这种情况下,变量是在全局范围内设置的,我可以获取它们并在我的构建脚本中使用。

显然,PowerShell 以不同的方式启动 GitVersion。我想,我应该在我的构建脚本中以某种方式模仿它。

所以我的问题还是一样,如何在我的脚本中使用 GitVersion 作为目标并取回版本号。

您的问题是您创建了进程级环境变量。在你存在 shell 进程后,在不同进程中运行的下一步不知道你在那里设置的任何环境变量。

您将必须设置一个永久环境变量,例如用户级或机器级变量。

看看 .NET 中的 Environment.SetEnvironmentVariable 方法。

示例:

Environment.SetEnvironmentVariable("key", "value", EnvironmentVariableTarget.Machine);

不过,我认为这不是一个好的解决方案。我不知道 GitVersion 并且坦率地说不明白你为什么需要这个东西。您的构建脚本不能确定语义版本本身吗?显然设置 sem 版本是一个手动步骤,因为没有自动化工具知道如何根据您的代码更改正确地增加版本。因此,您应该在项目中选择一个位置(1 个文件,如自述文件,或任何其他有意义的文件)来设置语义版本,并让所有其他工具从那里读取它以在构建期间设置程序集版本,打包 nuget 包, 在 git 中创建标签等..

你看过 Fake GitVersionHelper 了吗? http://fsharp.github.io/FAKE/apidocs/fake-gitversionhelper.html

#r "packages/FAKE/tools/FakeLib.dll"
open Fake
open Fake.GitVersionHelper

let version = GitVersion (id)

printfn "FullSemVer %s" version.FullSemVer
printfn "NuGetVersionV2 %s" version.NuGetVersionV2