如何将一个git仓库的构建输出集成到另一个

时间:2015-04-30 10:16:02

标签: git git-submodules git-subtree

我正在处理2个项目,这些项目存储在2 git repos Project1和Project2

Project1是一个javascript项目。它有自己的回购(例如https://github.com/gandra/project1.git
Project2是一个java maven项目。它有自己的仓库(例如https://github.com/gandra/project2.git

以下是我想要改进的当前工作流程:

  1. 提交Project1中的更改​​并将其推送到原点
  2. 在Project1中运行grunt。这会生成Project1 / build目录
  3. 将Project1 / build内容手动复制到Project2 / libs / project1-lib目录
  4. 在Project2中提交更改(Project2 / libs / project1-lib)
  5. Runk jenkins构建和部署
  6. 我想以某种方式避免第3步(将Project1 / build内容手动复制到Project2 / libs / project1-lib目录中) 我PROJECT1想过融入Project2中作为一个子,但这种方法的问题是怎么一回事,因为它得到所有PROJECT1目录结构到Project2的/库/ PROJECT1-lib和我想只取一PROJECT1的子目录(PROJECT1 /编译/ *)< / p>

    一些重要的说明: Project1更改仅在其自己的仓库(https://github.com/gandra/project1.git)中发生,此更改应传播到Project2。因此Project2 / libs / project1-lib中没有Project1的更新 换句话说:
    - Project1中的提交影响Project2 - Project2中的提交不会影响Project1

3 个答案:

答案 0 :(得分:4)

如果你控制了你正在使用的Git服务器,那么你可以使用post-receive server-side hook来完成你所要求的。

但是,我不禁觉得应该有更好的方法,而不是将更改从Project1推送到Project2。很明显Project1是Project2的依赖项。我更习惯于使用Maven和Gradle来处理依赖关系:

  • 让Project1的构建工具(例如Gradle)将构建工件发布到构建工件存储库(例如Artifactory)。
  • 让Project2的构建工具根据需要从构建工件存储库中提取最新工件。

我在这种方法中看到的优点是:

  • Project1独立于Project2。由于Project2需要Project1(反之亦然),因此Project1不应该保持Project2的更新。
  • Project2控制它如何使用Project1。例如,您可以免费冻结某个Project1版本的依赖项(例如,因为Project1当前已损坏,您希望继续开发Project2而不等待修复)。
  • 您没有使用与Project2源无关的更改来污染Project2的提交。如果每次更新Project1,你都会在Project2中获得一个新的提交,很快就会在合并,变基,平分或者你通常不得不做的任何其他事情上让你的生活变得困难。

缺点主要在于基础架构要求(突然您需要另一台服务器)以及选择和配置构建工具。谈到Java,我建议使用Gradle,以获取构建工具和构建工件存储库的Artifactory。但是你说你的Project1是Javascript而我没有在那个生态系统中工作过,所以我在那里没有任何好的建议。

编辑:我刚才意识到我混淆了Project1和Project2。问题是Project2使用Project1并且我的初始答案被写成好像Project1消耗了Project2。我现在解决了这个问题,以避免混淆。

答案 1 :(得分:1)

Vojislav说的是正确的。这两个项目的建设(以你描述的方式)应该是分离的。如果最终产品需要两个组件,那么编译应用程序就是构建工具(jenkins)的工作。这两个项目应该是彼此非常不可知的。

我有一段时间没有使用Jenkins,但在Bamboo中我会有一个名为BuildProduct的任务,它有两个任务(Build Project 1)和(Build Project 2),其中Project 2的构建将使用结果第一个构建(构建的JS)。

答案 2 :(得分:1)

好的,让我们回顾一下最重要的事实:

  1. Project2是maven项目(可能包含war包装,因为你将部署它)。
  2. Project2以某种方式依赖于Project1,它希望他的输出构建在路径Project2 / libs / project1-lib
  3. 在我看来,构建(甚至是部分构建)并不意味着在任何源代码管理之下,因此我不会保留Project2 / libs / project1-lib之类的Project2的任何路径。 Maven war插件有这个很好的功能maven-war-plugin-overlays。 因此,如果Project2将Project1视为与战争类型packaginig的maven依赖关系,例如

      <dependencies>
        ...
        <dependency>
          <groupId>your.group.id</groupId>
          <artifactId>project1</artifactId>
          <version>1.0-SNAPSHOT</version>
          <type>war</type>
          <scope>runtime</scope>
        </dependency>
        ...
      </dependencies>
    

    ,你不必对Project2 / libs / project1-lib位置进行任何处理,因为这将在你打包的阶段为你做。 但要做到这一点,你必须将Project1的war artifact安装到你的nexus中。 这里有几个解决方案:

    解决方案1)

    1. 使Project1成为完全maven项目,并确保构建的输出在他的战争中的路径./libs/project1-lib上完成。 由于Project1现在将使用maven构建,因此您必须集成Project1的先前构建工具(grunt,gulp或其中任何一个),以便在打包阶段之前由maven调用。
    2. 在Project2中添加新依赖项,如下所示:

      <dependency>
        <groupId>your.group.id</groupId>
        <artifactId>project1</artifactId>
        <version>1.0-SNAPSHOT</version>
        <type>war</type>
        <scope>runtime</scope>
      </dependency>
      

    3. 解决方案2)。

      1. 使用Project1的当前构建器,确保使用以下结构将项目打包为war ./libs/project1-lib。 使用相同的构建器将此安装在您的nexus上作为war artifact(注意:您必须在nexus上安装pom.xml,以便其他项目可以引用Project1) 如果你幸运地使用grunt作为js构建器,那么这个np​​m组件grunt-nexus-deployer将完全按照我在这里描述的那样进行。
      2. 与解决方案1相同......)
      3. 说明:

        当您推送Project1的更改时,您的CI将触发作业,该作业将在您的nexus上安装project1-1.0-SNAPSHOT.war 完成此操作后,将触发Project2的CI作业,它将包含project2构建所需的所有内容。

        注意: 在这两个解决方案中,删除Project2 / libs / project1-lib层次结构,因为它不再使用...

        编辑:

        对于解决方案2),您可以使用grunt-maven-tasks代替grunt-nexus-deployer,因为它有更多选项,更适合。