使用 GitHub Actions 循环处理多个文件

7

我在代码库的多个子目录中有多个 .md 文件,它们都具有相同的命名约定,例如 seminar1/slides.mdseminar2/slides.md 等。需要使用 pandoc 处理这些 *.md 文件。我希望每次提交到代码库时都能自动执行此操作,并决定将其实现为在 Github 上运行的操作。

我创建了以下工作流程作为 .yml 文件,Github 可以识别为操作。它可以处理单个子目录下的文件,例如/seminar1/*.md,但处理多个子目录时会失败。

name: Make slides

on: push

jobs:
  convert_via_pandoc:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v2
        with:
          ref: slides
      - run: |
          echo "::set-env name=FILELIST::$(printf '"%s"' seminar*/*.md)"
      - uses: docker://pandoc/latex:2.9
        with:
          args: -t beamer --output=${{env.FILELIST}}.pdf ${{env.FILELIST}}
      - uses: actions/upload-artifact@v2
        with:
          name: seminar-slides
          path: seminar*/*.md.pdf        

如何编写一个脚本以检测所有的 seminar*/*.md 文件并对其进行操作?

此外,我需要一些关于通用性的帮助:

  1. 所有脚本都是从根目录运行。这意味着我必须修改 .md 文件的内容以包含目录,例如使用 seminar1/bridge.jpg 而不仅仅是使用 bridge.jpg。如何为每个 $env.FILELIST 更改工作目录?
  2. 如何剥离文件名的扩展名并在 $env.FILELIST 中使用?
2个回答

4

我在谷歌搜索解决方案时遇到了类似的问题(很抱歉在旧问题中添加答案,但我希望在我之后的人能更轻松地找到这个答案),使用 Github Actions 迭代事物。

Github Actions 支持 'matrix' 用于在作业中进行迭代,但它难以使用,我无法将其与来自字符串的列表一起使用。我找到的唯一可行的解决方案是手动拆分字符串并仅使用 bash。

这里是我的解决方案。它不使用 docker://pandoc/latex:2.9,但更加清晰易懂。

  • Github Actions 中的迭代

您有一个逗号分隔的值字符串,例如 "a,b,c"。您需要在每个步骤中将其解析为真实数组,并迭代值。

IFS 代表 "内部字段分隔符"。它由 shell 用于确定如何执行单词拆分,即如何识别单词边界。我们使用 read 命令并将其馈送到我们的数组作为字符串。之后,我们只需在真实数组上进行迭代。

name: Looping over values in Github Actions

env:
  VALUE_ARRAY_AS_STRING: 'a.md,b.md,c.md'

jobs:
  run-my-stuff:
    name: Iterating over comma-separated-values
    runs-on: ubuntu-latest
    steps:
      - name: Echo values from ENV
          run: |
            IFS="," read -a myarray <<< ${{ env.VALUE_ARRAY_AS_STRING }}
            for i in "${myarray[@]}"; do
              echo "Value: ${i}"
              echo "Value: ${i%.*}"
            done

      - name: Finding files and store to output
        id: finding-files
        run: |
          echo "::set-output name=FILELIST::$(find . -name '*.md' -print)"

      - name: Processing my found files from output
        run: |
          IFS="," read -a myarray <<< ${{ steps.finding-files.outputs.FILELIST }}
          for i in "${myarray[@]}"; do
            file_path=$(dirname "${i}")
            file_name=$(basename "${i}")
            cd file_path
            cat file_name
          done

找到所有的*.md文件
find . -name '*.md' -print
  • 文件扩展名分离

参考自https://dev59.com/questions/OXVC5IYBdhLWcg3w-mdO#125340从文件路径中获取文件目录路径

x="filename.md"
echo ${x%.*} 
  • 更改工作目录

您可以按步骤执行此操作,或者如果只运行命令,则可以使用cd。我没有深入研究,但我猜测 docker://pandoc/latex:2.9 也有一个用于工作目录的参数。您需要查看文档。


1
谢谢!不需要为贡献道歉! - Andy Clifton
1
这里的脚本编写有些问题。你不能在for循环的每个迭代中都使用cd命令,除非至少切换回原始目录(pushd/popd)或使用子shell,以便你的脚本CWD不会移动。但即使你解决了这个问题,也无法解决在与预期路径不同的位置上使用GH Action的问题。虽然有一种方法可以解决,但这不是其中之一。 - Caleb
@Caleb,你能提供一个答案吗? - Andy Clifton

1

我的简单解决方案是将我想要执行的操作编写成Python脚本,并使用一个动作来运行Python脚本。

这样编码要简单得多,并且有在本地机器上进行测试的优点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接