【问题标题】:GitHub action to check out repo as a git submodule将 repo 作为 git 子模块签出的 GitHub 操作
【发布时间】:2020-09-11 07:36:32
【问题描述】:

背景

我有一个包含 git 子模块的项目,两者都托管在 GitHub 上。
子模块源是作为项目的一部分构建的,子模块中的更改可能会影响包含的项目。

我的目标是确保子模块不会破坏包含的项目。
为此,我正在尝试在子模块 repo 上创建一个 GitHub 操作 ,该操作在推/拉时执行以下操作:

  • 克隆包含的项目
  • 查看带有特定 push/PR SHA 的子模块
  • 使用子模块构建项目

问题

标准的Checkout v2 操作不支持此类工作流。
相反,我正在根据$GITHUB_SHA 克隆和签出子模块,如下所示:

- name: Checkout project
  run: git clone <Project>
- name: Update submodules
  run: git submodule update --init --recursive
- name: Checkout submodule
  working-directory: ./<submodule dir>
      run: |
        git fetch
        git checkout $GITHUB_SHA
- name: Build
  run : make

这适用于推送,但不适用于拉取请求
在 PR 上,我得到了这样的结果:

fatal: reference is not a tree: 48fd1d918a25e7544969d13949b1d436f525412c

在 PR 的情况下,$GITHUB_SHA 提供的 SHA 根本找不到。

示例

问题

  • 为什么在 PR 的情况下$GITHUB_SHA 是错误的?如果是 PR,它代表什么?
  • 有没有更好的方法来实现我想要做的事情?

澄清

如果不清楚 - 有问题的 PR 位于 子模块 的存储库中,而不是主(包含)项目存储库。
该操作在子模块 repo 上运行,并检查包含和子模块。

这个问题与 PR(子模块的)的 $GITHUB_SHA 似乎并不代表子模块上的提交有关,尽管我预计会这样。


更新 1

我又做了一次尝试:
尝试将此作为 Checkout 子模块“运行”步骤:

        git fetch ${{ github.event.repository.git_url }}
        git fetch ${{ github.event.pull_request.head.repo.clone_url }}
        git checkout ${{ github.sha }} || git checkout ${{ github.event.pull_request.head.sha }}

在 PR 上,两个 SHA 的签出仍然失败:

fatal: reference is not a tree

所以从 PR 来源的原始存储库中获取 - 没有帮助。
pull_request.head.sha 看起来是正确的(这次是正确的 SHA),但 git checkout 即使这样也失败了!不知道为什么。


更新 2

最终我找到了解决方法!
这是“结帐子模块”运行步骤:

      run: |
        git fetch --force ${{ github.event.repository.git_url }} "+refs/heads/*:refs/remotes/origin/*"
        git fetch --force ${{ github.event.repository.git_url }} "+refs/pull/*/head:refs/remotes/origin/pr/*"
        git checkout ${{ github.sha }} || git checkout ${{ github.event.pull_request.head.sha }}

所以我正在做的是:

  • git_url获取磁头
  • git_url获取所有PR
  • 正在尝试结帐github.sha。这适用于推送,但不适用于 PR
  • 如果上述操作失败,请查看github.event.pull_request.head.sha。这适用于 PR 但不适用于推送....

但是,同样的问题仍然存在 -

  • 为什么在 PR 的情况下github.sha 是错误的?如果是 PR,它代表什么?
  • 有没有更好的方法来实现我想要做的事情,而不是从远程获取所有 PR 并尝试 github.shagithub.event.pull_request.head.sha

【问题讨论】:

  • 您能否在您的 Checkout 子模块“运行”步骤中执行 git statusgit remote -v,以检查您是否在正确的工作文件夹中?
  • @VonC git remote -v 无关紧要,因为我没有使用命名遥控器,而是提供遥控器的完整 URL。 fetch 命令成功完成。 git status 返回:HEAD detached at ...nothing to commit, working tree clean
  • $GITHUB_SHA 是否可能是 PR 分支的一部分,而不是默认 refspec 的一部分? (如图所示:gist.github.com/piscisaureus/3342247)。你能添加一个遥控器,然后git config --add remote.origin.fetch "+refs/pull/*/head:refs/remotes/origin/pr/*",然后git fetch吗?
  • @VonC 最后我找到了一个解决方法,通过获取 PR 并尝试 GitHub 上下文提供的两个 SHA,请参阅“更新 2”。我没有将其添加为答案,因为它提出的问题多于答案...
  • @VonC 好的,我想我已经破解了!看我的回答。

标签: git github github-actions


【解决方案1】:

我在这里找到了答案:
https://frontside.com/blog/2020-05-26-github-actions-pull_request/#how-does-pull_request-affect-actionscheckout

显然,在 PR 的情况下,github.sha(或$GITHUB_SHA)表示生成的提交的 SHA,该提交是通过将基础合并到头部创建的,而不是基础更改提交本身。

要获取它,我需要获取 refs/pull/*/merge 而不是 refs/pull/*/head

现在这个运行步骤更有意义了:

        git fetch --force ${{ github.event.repository.git_url }} "+refs/heads/*:refs/remotes/origin/*"
        git fetch --force ${{ github.event.repository.git_url }} "+refs/pull/*/merge:refs/remotes/origin/pr/*"
        git checkout ${{ github.sha }}

第一次获取将获取头部,用于推送操作。第二个将获取 PR 的合并提交。
两者都由github.sha 表示。

【讨论】:

    猜你喜欢
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-20
    相关资源
    最近更新 更多