具有构建功能的自定义TeamCity插件,可以执行长时间运行的过程

时间:2018-11-07 16:33:52

标签: teamcity

我正在开发与企业部署平台集成的自定义TeamCity插件。它应通过执行命令行命令在构建结束时将二进制文件部署到某个部署平台。当前,在服务器端有一个扩展BuildFeature类的类来设置要部署的工件的详细信息。在代理程序方面,有一个扩展AgentLifeCycleAdapter类的类,该类重写beforeBuildFinish()方法并执行长时间运行的命令行过程。我正在使用SimpleCommandLineProcessRunner类来执行外部命令行过程:

final ExecResult result = SimpleCommandLineProcessRunner.runCommand(commandLine,
        null,
        new SimpleCommandLineProcessRunner.RunCommandEventsAdapter());

该过程在两分钟后停止,这看起来有些超时:

  

[18:13:50]以atom_builder身份运行   [18:13:50]正在执行C:\ TeamCity \ buildAgent \ work \ db4107aa7e390a67 \ adeploy \ adeploy.exe    artifactVersion推送   C:\ TeamCity \ buildAgent \ work \ db4107aa7e390a67 \ agent \ atom-agent-artifact-version.xml   [ 18:13:50 ]运行在C:\ TeamCity \ buildAgent \ work \ db4107aa7e390a67 \ agent   [ 18:15:22 ] 2018-11-07 18:13:51 [信息]   [“ ArtifactPushService:PushArtifactAsync”]带有参数“'adeploy.exe”的调用方法[18:15:22]退出代码:-1

当构建配置具有自定义构建功能时,执行长时间运行的过程作为构建一部分的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

我找到了答案,所以如果有人遇到相同的问题,我将在这里发布。

由于我们在谈论自定义插件,所以它完全在执行外部过程的插件的代理程序代码中。如问题中所述,外部过程是使用SimpleCommandLineProcessRunner类执行的,并且它传递RunCommandEventsAdapter类的实例。最后一个在getOutputIdleSecondsTimeout()方法中返回null。这意味着,除非在teamcity.execution.timeout参数中定义,否则SimpleCommandLineProcessRunner将使用默认的90秒超时。

因此解决方案是定义一个实现ProcessRunCallback接口的LongRunningProcessRunCallback类。请注意,getOutputIdleSecondsTimeout()返回相当长的超时时间。

public class LongRunningProcessRunCallback implements SimpleCommandLineProcessRunner.ProcessRunCallback {

    private static final int DEFAULT_TIMEOUT_SECONDS = 60 * 60 * 24;

    @Nullable
    @Override
    public Integer getMaxAcceptedOutputSize() {
        return null;
    }

    @Override
    public void onProcessStarted(@NotNull Process process) {

    }

    @Override
    public void onProcessFinished(@NotNull Process process) {

    }

    @Nullable
    @Override
    public Integer getOutputIdleSecondsTimeout() {
        return TeamCityProperties.getInteger("teamcity.execution.timeout", DEFAULT_TIMEOUT_SECONDS);
    }
}

然后将其传递给SimpleCommandLieProcessRunner:

final ExecResult result = SimpleCommandLineProcessRunner.runCommand(commandLine,
                null,
                new LongRunningProcessRunCallback());