如何在Github Actions中运行Pandoc 'convert all files in Dir'命令

6
我希望设置一个 Github Action,在将 repo 推送到 master 时运行 pandoc FAQ 中的 this 命令。我们的目标是使用 pandoc docker 容器将我们 repo 中的所有 md 文件从 md 转换为另一种格式。

这是我到目前为止的进展。在第一个示例中,我没有声明 entrypoint,导致出现错误 "/usr/local/bin/docker-entrypoint.sh: exec: line 11: for: not found."

name: Advanced Usage

on:
  push:
    branches:
      - master

jobs:
  convert_via_pandoc:
    runs-on: ubuntu-18.04
    steps:
      - name: convert md to rtf
        uses: docker://pandoc/latex:2.9
        with:
          args: |
            for f in *.md; do pandoc "$f" -s -o "${f%.md}.rtf"; done

在第二个示例中,我们声明了entrypoint: /bin/sh,结果出现错误信息 "/bin/sh: can't open 'for': No such file or directory"。
name: Advanced Usage

on:
  push:
    branches:
      - master

jobs:
  convert_via_pandoc:
    runs-on: ubuntu-18.04
    steps:
      - name: convert md to rtf
        uses: docker://pandoc/latex:2.9
        with:
          entrypoint: /bin/sh
          args: |
            for f in *.md; do pandoc "$f" -s -o "${f%.md}.rtf"; done

我是git actions的菜鸟,也不是技术人员,所以我猜这对SO社区来说很容易。只是想尝试一些简单的工作流自动化。欢迎提供初学者反馈。谢谢 - Allen

1
值得注意的是,SO 是我能够走到这一步的唯一原因,如果我确实走在正确的轨道上的话! - Allen
也许你需要像这样引用它 "for f in...." 并删除 "|",这样它就成为一个参数了?请参阅 https://github.com/pandoc/dockerfiles#github-actions。 - mb21
谢谢@mb21,我今天尝试了一下,但是还是出现了同样的错误信息。我猜测我缺少的不仅仅是语法,可能还有其他几个东西。 - Allen
2个回答

3

我需要对md文件进行递归转换以创建可下载的包,因此这个答案超出了原帖的目标。

这个Github操作将会:

  1. 创建输出目录(mkdir output
  2. 递归浏览文件夹,在输出目录中创建同名文件夹(for d in */; do mkdir output/$d; done
  3. 递归查找所有md文件(find ./ -iname '*.md' -type f)并执行pandoc命令(-exec sh -c 'pandoc ${0} -o output/${0%.md}.docx' {} \;

请注意,在从终端转换为单个docker命令的过程中,必须小心双引号和单引号的用法。

第一次迭代

jobs:
  convert_via_pandoc:
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v2
      - name: convert md to docx
        uses: docker://pandoc/latex:2.9
        with:
          entrypoint: /bin/sh
          args: -c "mkdir output;for d in */; do mkdir output/$d; done;find ./ -iname '*.md' -type f -exec sh -c 'pandoc ${0} -o output/${0%.md}.docx' {} \;"
      - uses: actions/upload-artifact@master
        with:
          name: output
          path: output

这个解决方案是基于@anemyte提供的信息和这个SO帖子上的递归转换开发的。

@caleb的第二次迭代

name: Generate Word docs
on: push

jobs:
  convert_via_pandoc:
    runs-on: ubuntu-20.04
    container:
      image: docker://pandoc/latex:2.9
      options: --entrypoint=sh
    steps:
      - uses: actions/checkout@v2
      - name: prepare output directories
        run: |
          for d in */; do
            mkdir -p output/$d
          done
      - name: convert md to docx
        run: |
          find ./ -iname '*.md' -type f -exec sh -c 'pandoc ${0} -o output/${0%.md}.docx' {} \;
      - uses: actions/upload-artifact@master
        with:
          name: output
          path: output

这比使用你的解决方案编辑我的回答要好得多。 :) - anemyte
2
还有另一种处理方式,即将顶级容器设置为 Pandoc 容器,以便任何具有简单“run:”参数的步骤都在 Pandoc Docker 容器内运行。请参见此处的我的评论或您的 PR - Caleb

1
如果您只使用shell,那么可以让您的生活更轻松:
name: Advanced Usage

on:
  push:
    branches:
      - master

jobs:
  convert_via_pandoc:
    runs-on: ubuntu-18.04
    steps:
      - name: convert md to rtf
        run: |
          docker run -v $(pwd):/data -w /data pandoc/latex:2.9 sh -c 'for f in *.md; do pandoc "$f" -s -o "${f%.md}.rtf"; done'

-v 键将当前工作目录挂载到容器内的 /data-w 键使 /data 成为工作目录。其他内容由您自己编写。

您面临的问题是,您的 args 被解释为一系列参数。Docker 接受 entrypointcmd(在这种情况下为 args)参数,可以是字符串或字符串数组。如果是字符串,则会对其进行解析以创建元素数组。 for 变成了该数组的第一个元素,并且作为第一个可执行文件尝试执行 for,但失败了。

不幸的是,事实证明,此操作目前不支持元素数组。请查看 @steph-locke 的答案,以获取具有正确 args 字符串的解决方案。


我无法在 GitHub Actions 上使这些工作,但是根据参数等信息,这个可以工作:https://gist.github.com/stephlocke/7eafab0669b6568d423599b89eff9d43 - Steph Locke
很高兴您将gist的内容整合到您的回答中,以便我可以授予您赏金 :) - Steph Locke
这个代码片段修改了你的args和entrypoints示例 - 至少在我第一次运行时,我发现gh不喜欢这些的值数组。 - Steph Locke
感谢您的反馈。我已从答案中删除了那部分内容。 - anemyte

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