我的命令行构建步骤不执行,因为显然传入的参数没有被接受。我发现信息表明,为了将变量传递到像这样的 bat 文件中,它们需要是 TeamCity 中的环境参数才能工作,我尝试过,但没有成功。
我正在使用 TeamCity 2023.05.2(内部版本 129341),并且我有一个 Unity 项目,其 Unity 构建步骤可以正常运行。 遗憾的是,第二个构建步骤是有问题的部分。
这是一个命令行步骤,我尝试运行一个 .bat 文件,该文件应将上一步的构建文件夹复制到另一个文件夹。
这是我的.bat脚本的内容:
@echo off
setlocal enabledelayedexpansion
set "SourceFolder=%env.CHECKOUTDIR%\BTSCORE"
set "DestinationFolder=C:\Test"
echo SourceFolder is located at: %env.CHECKOUTDIR%
:: Find the last subfolder with relevant files based on commit number and datetime
for /f "tokens=*" %%d in ('dir /b /ad /o-n "%SourceFolder%\*"') do (
set "LastSubfolder=%%d"
goto :FoundLast
)
:FoundLast
echo Last subfolder: !LastSubfolder!
:: Construct source and target paths
set "SourcePath=%SourceFolder%\!LastSubfolder!"
set "TargetPath=%DestinationFolder%\!LastSubfolder!"
if not exist "%SourcePath%" (
echo Source folder does not exist!
exit /b 1
)
:: Create the target directory if it does not exist
if not exist "%TargetPath%" (
mkdir "%TargetPath%"
)
:: Copy the contents of the last subfolder to the target folder
xcopy /s /e /i "%SourcePath%\*" "%TargetPath%"
if errorlevel 1 (
echo Copy failed!
) else (
echo Copy succeeded!
)
endlocal
现在,当此步骤运行时,我收到一条消息,指出源文件夹不存在,完整日志为:
Starting: G:\BatFiles\CopyBuild.bat G:\TeamCity\BuildAgent\Work\f1099063e78e73d4
18:09:12 in directory: G:\BatFiles
18:09:12 SourceFolder is located at:
18:09:12 Das System kann die angegebene Datei nicht finden.
18:09:12 Last subfolder:
18:09:12 Source folder does not exist
18:09:12 Process exited with code 1
18:09:12 Process exited with code 1 (Step: Copy Files (Command Line))
18:09:12 Step Copy Files (Command Line) failed
我发现为了将变量传递到这样的bat文件中,它们需要环境参数才能工作,但显然仍然找不到
%env.CHECKOUTDIR%
。
我附上了我的设置的这两张屏幕截图。
我在哪里,错过了什么?
我将这两个步骤称为
firststep
和secondstep
如果你正在做的是执行
firststep
secondstep G:\TeamCity\BuildAgent\Work\f1099063e78e73d4
从提示来看,那么很可能,您期望
env.CHECKOUTDIR
由 firststep
建立,然后您假设 env.CHECKOUTDIR
可以被 secondstep
使用。
如果
firststep
包含 setlocal
命令,则在 setlocal
之后对环境所做的任何更改都将在执行 endlocal
命令时被撤销,并且环境将恢复到执行 setlocal
时的状态.
到达文件末尾是隐式的
endlocal
因此,您可以简单地在
secondstep
结束之前调用 firststep
第一步.bat
...
setlocal
...
secondstep
rem execution is now transferred to "secondstep" with the current environment intact
rem hence further commands will not be executed
或者您可以独立运行
secondstep
并提供 env.CHECKOUTDIR
作为参数:
第二步.bat
@echo off
setlocal enabledelayedexpansion
if not defined env.CHECKOUTDIR set "env.CHECKOUTDIR=%~1"
set "SourceFolder=%env.CHECKOUTDIR%\BTSCORE"
set "DestinationFolder=C:\Test"
...
其中
%~1
表示“获取提供给批次的第一个参数,并删除所有括起来的引号”(如果参数包含空格,则应加引号;如果不包含空格,%~1
无论如何都是安全的)
请注意,这涉及
env.CHECKOUTDIR
- 可能还有其他需要处理的变量 - 如果是这种情况,则需要更多信息。
处理此问题的另一种方法是使用(在第一批中)
...
endlocal&set "env.CHECKOUTDIR=%env.CHECKOUTDIR%"
将更改更改为
env.CHECKOUTDIR
“在 setlocal/endlocal 括号上”
哦 - 顺便说一句:
!var!
意味着 var
在 for
循环中发生变化,并在循环内变化时获取变量的运行时值。
由于您的代码不会访问
for
循环中的变量,因此 %var%
与 !var!
相同,因此 !LastSubfolder!
可以是 %LastSubfolder%
,事实上 delayedexpansion
不是必需的,这可能有助于例如,在消息中使用感叹号。