Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How might I run Pandoc 'convert all files in Dir' command in Github Actions

I would like to setup a github action that runs this command from pandoc FAQ on a repo when its pushed to master. Our objective is to convert all md files in our repo from md to another format using the pandoc docker container.

here is where I got so far. In the first example i do not declare an entrypoint and i get the error "/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

In the second example we declare entrypoint: /bin/sh and the result is error "/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

I am a total noob to git actions and not a technical person so my guess is this is easy idea for the SO community. just trying some simple workflow automation. any explicit and beginner feedback is appreciated. thanks - allen

like image 943
Allen Avatar asked Mar 09 '20 02:03

Allen


2 Answers

I needed to do a recursive conversion of md files to make a downloadable pack, so this answer extends beyond the OP's goal.

This github action will:

  1. Make the output directory (mkdir output)
  2. Recurse through the folders, create similarly named folders in an output directory (for d in */; do mkdir output/$d; done)
  3. Find all md files recursively (find ./ -iname '*.md' -type f) and execute a pandoc command (-exec sh -c 'pandoc ${0} -o output/${0%.md}.docx' {} \;)

Note that you have to be careful with double and single quote marks when converting from stuff that works in terminal to things that get correctly transformed into a single docker command as part of the github action.

First iteration

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

This solution was developed using @anemyte's info and this SO post on recursive conversion

Second iteration from @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
like image 71
Steph Locke Avatar answered Oct 18 '22 19:10

Steph Locke


You can make your life easier if you do this with just 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'

The -v key mounts current working directory to /data inside the container. The -w key makes /data a working directory. Everything else you wrote yourself.

The problem you faced is that your args is been interpreted as a sequence of arguments. Docker accepts entrypoint and cmd (args in this case) arguments either as a string or as an array of strings. If it is a string it is parsed to create an array of elements. for became first element of that array and as the first element is an executable it tried to execute for but failed.

Unfortunately, it turned out that the action does not support an array of elements at this moment. Check @steph-locke's answer for a solution with correct args as a string for the action.

like image 1
anemyte Avatar answered Oct 18 '22 19:10

anemyte