【问题标题】:Compare build artifacts from two different commits via github actions通过 github 操作比较来自两个不同提交的构建工件
【发布时间】:2023-01-25 18:59:29
【问题描述】:

我在 github 操作中有一个工作流程,每次我将 PR 合并到 mainhere's repo)时,它会自动创建构建工件并使用这些新的构建工件更新单个版本。

我想知道新的 PR 是否会导致构建工件发生变化(具体来说,我只关心一个 CSV 文件)。有时这些更改是有意的,有时不是,所以我想要在 PR 之前的 CSV 文件和 PR 之后的 CSV 文件之间添加类似 git diff 的内容。

我知道我可以设置一个 github 操作来:

  1. 检查旧版本的代码。
  2. 运行代码生成构建工件
  3. 将感兴趣的文件保存到光盘
  4. 从 PR 中检查建议的代码版本
  5. 运行 PR 代码以生成构建工件
  6. git diffPR之前的版本到PR之后的版本。
  7. 格式化git diff 输出并将其作为注释写入 PR,让 我知道发生了什么变化,所以我可以手动检查一切是否正常。

    但这似乎是一个非常普遍的问题,我不敢相信没有一个简单的问题 工具/解决方案已经存在了吗?也许是一些 github 操作,你给它两个 SHA,一个要运行的命令,以及一个文件列表到git diff

    需要明确的是,这些是构建工件,因此不会被 git 跟踪,因此 git diff pullrequest main -- myfile.csv 之类的解决方案将不起作用。

【问题讨论】:

  • 我面临同样的问题。一个侧面的想法:在main(或您的 PR 指向的任何分支)上运行代码以生成工件,然后在分支的 HEAD 上运行代码不是 DRY。因此,一种方法可能是使用 git notes 来跟踪工件列表及其各自的 SHA,为下一次 PR 做好准备。
  • 直到关于 git 笔记。但是关于这个问题,我最终放弃了尝试,因为我找不到一个简单的方法来解决它并且不想在项目中花费很多时间。
  • 好吧,我有一点空闲时间(:

标签: github-actions cicd artifact


【解决方案1】:

这是一个利用 git notes 的解决方案:

(简而言之,git notes 允许您对提交进行 CRUD 元数据不触及提交本身——从而保存历史。比照。 § 以下参考资料。)

本质上,我们希望我们的工作流程能够:

  1. 构建工件
    我们通过运行 make build 来模拟这一点——以适应您自己的场景。为了示例,我们还假设 build/ 目录包含所有且仅包含生成的工件。
  2. “记住”人工制品及其内容(一个所谓的“人工制品摘要”)
    我们使用sha512sum shell 命令来创建人工制品内容(通过它们的 SHA 和表示)到它们的文件名的映射。
    我们通过find results/ -type f 检索所有人工制品,然后使用sed 's/ /,/' | cat <(echo 'sha512,file_name') - 将映射转换为带有标题的 CSV
  3. 附上人工制品摘要提交
    这就是我们利用 git notes 的地方,它允许我们将元数据添加到事后提交中,而无需修改历史记录。

    这些步骤应该针对主分支上的任何提交执行。

    如果是 PR,您还想在分支机构的 HEAD 上重复这些步骤,加上:

    1. 检索人工制品摘要你的 PR 的目标分支
      所以你现在有两个人工制品摘要来比较:base(你的main/master分支的一个)和 head(你的 PR 的分支)。在下面的示例中,根据硬编码为main,但您可以通过letting the workflow retrieve the target branch's name automatically对其进行优化。
    2. 比较两个人工制品摘要
      为此,我创建了artefactscomparison Python package。 (注意:它非常适合我的用例和需求。)
    3. 将工件比较报告添加到您的 PR
      Beebop,一个机器人会为你做这件事。

    最后,您应该会在上面的屏幕截图中看到类似的内容。

    笔记:

    • 下面的工作流涵盖了两种用例(在分支 main 和提出 PR 时),这是为了避免在两个不同的 YAML 文件中重复相同的代码(步骤 1 到 3)。
    • 将步骤 4 到 6 打包到一个单独的步骤中会更清晰(只有一个 if: ${{ github.event_name == 'pull_request' }} 声明)。但是,这意味着需要再次检索 HEAD 的注释——性能折衷。
    name: Artefacts Comparison
    
    on:
      push:
        branches:
          - main
    
      pull_request:
        branches:
          - main
    
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout repo
            uses: actions/checkout@v3
            with:
              fetch-depth: 0
              token: ${{ github.token }}
          - name: Build artefacts
            run: make build
          - name: Generate “artefact summary”
            id: head-artefact-summary
            run: |
              echo "ARTEFACTS_SUMMARY<<EOF" >> $GITHUB_OUTPUT
              find build/ -type f -exec sha512sum {} ; | sed 's/  /,/' | cat <(echo 'sha512,file_name') - >> $GITHUB_OUTPUT
              echo "EOF" >> $GITHUB_OUTPUT
          - name: Add the artefact summary as a git notes
            id: git-notes
            run: |
              git fetch origin refs/notes/*:refs/notes/*
              git config user.name "github-actions"
              git config user.email "bot@github.com"
              git notes add --allow-empty --force --message="${{ steps.head-artefact-summary.outputs.ARTEFACTS_SUMMARY }}"
              git notes show
              git push origin refs/notes/*
          # In case of PR, add report of artefacts comparison
          - name: Retrieve main's artefact summary
            if: ${{ github.event_name == 'pull_request' }}
            id: artefact-summary-main
            run: |
              git checkout main
              echo "ARTEFACTS_SUMMARY<<EOF" >> $GITHUB_OUTPUT
              git notes show >> $GITHUB_OUTPUT
              echo "EOF" >> $GITHUB_OUTPUT
          - name: Setup Python
            if: ${{ github.event_name == 'pull_request' }}
            uses: actions/setup-python@v4
            with:
              python-version: "3.10"
          - name: Install `artefactscomparison` Python package
            if: ${{ github.event_name == 'pull_request' }}
            run: pip install -U artefactscomparison
          - name: Generate artefact comparison report
            if: ${{ github.event_name == 'pull_request' }}
            id: artefact-comparison-report
            run: |
              echo "${{ steps.artefact-summary-main.outputs.ARTEFACTS_SUMMARY }}" > base.csv
              echo "${{ steps.head-artefact-summary.outputs.ARTEFACTS_SUMMARY }}" > head.csv
              echo "ARTEFACTS_REPORT<<EOF" >> $GITHUB_OUTPUT
              artefacts_comparison -b base.csv -h head.csv >> $GITHUB_OUTPUT
              echo "EOF" >> $GITHUB_OUTPUT
          - name: Comment PR with artefact comparison report
            if: ${{ github.event_name == 'pull_request' }}
            uses: thollander/actions-comment-pull-request@v2
            with:
              message: ${{ steps.artefact-comparison-report.outputs.ARTEFACTS_REPORT }}
              comment_tag: artefact_comparison_report
              mode: recreate
    

    参考:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-06
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 2020-01-09
    相关资源
    最近更新 更多