GitHub Actions and docker for writing a book

I am trying to wrote a book  ( with Daniel Tila ) about what are the challenges to transfer an application from console to SAAS.

We have decided to put the code on GitHub – and , because of this, the text will be still on GitHub .Each chapter will be in the form of the file – usual for GitHub.

Now – how we can make a PDF / HTML out of this ?

So, first challenge: how to make the PDF ? In these days, all is node-js – and I have found .

So I have created a simple package.json file


“name”: “print”,

“version”: “1.0.0”,

“description”: “print on Docker”,

“author”: “Andrei Ignat”,

“scripts”: {

“start”: “node server.js”


“dependencies”: {

“markdown-pdf”: “10.0.0”



and a javascript file

‘use strict’;

console.log(`start print`);

var markdownpdf = require(“markdown-pdf”)

var mdDocs = [

“”,”Chapter01/”, “Chapter02/”,”Chapter03/”,”Chapter04/”


, bookPath = “book.pdf”

markdownpdf().concat.from(mdDocs).to(bookPath, function () {

console.log(“Created”, bookPath)


And how I can execute ? Docker seems to be the answer ; run the javascript inside  docker ( in order to not install on my pc all kind of tools)

The docker file is simple

FROM node:10

WORKDIR /usr/src/

COPY print/package.json ./print/

RUN npm install ./print/

COPY . .

RUN ls -l print/*.*

RUN node print/server.js

CMD tail -f /dev/null

and to obtain the pdf book:

docker build -t ignatandrei/printsaas .. -f ./exportPDF.txt

docker run -d –name printsaas ignatandrei/printsaas

docker cp printsaas:/usr/src/book.pdf .

docker container kill printsaas

docker container rm printsaas

You can find all those files on .

Where should I put the PDF ? Turns out the GitHub has the docs folder – where you can put any kind of static data . Ad this is available for any project – by switching the name of the project from source code url to

Now , the problem is how to run this every time ? Remember that GitHub ( like any other source control) has Actions – that can run every time something is pushed on the repository. So this is the yml file:

name: ‘CD for generate book and docs folder’




– ‘**.md’



runs-on: ubuntu-latest


– uses: actions/checkout@v2

– name: print pdf

run: |

        chmod +x ./print/getBook.bat

        cd print       


        cp ./book.pdf ../docs/ConsoleToSaas.pdf

– uses: actions/upload-artifact@v1


name: ConsoleToSaas.pdf

path: ./print/book.pdf

– name: Commit files

run: |

        git config –local “”

        git config –local “GitHub Action”

        git commit -m “generate pdf” -a –allow-empty

– name: Push changes

uses: ad-m/github-push-action@master


github_token: ${{ secrets.GITHUB_TOKEN }}

( see )

So now I obtain the PDF automatically generated by docker, I put into docs folder( and into artifact ), and I commit the PDF back to the repository( and yes, GitHub is enough smart to not start the cycle again)

Now I wanted to have also HTML – or for any other format  . So I figure I need a general converte – and I have found PanDoc.

The code is more simple and just in the yml


runs-on: ubuntu-18.04

needs: build


– uses: actions/checkout@v2

– run: |

          git pull

          mkdir output

– uses: docker://pandoc/latex:2.9

with: # needs a README in your repo root!

#args: “–standalone –output=output/README.html”

args: “ Chapter01/ Chapter02/  Chapter03/ Chapter04/ –standalone -f gfm -t html –number-sections –toc -o output/output.html”

– uses: actions/upload-artifact@master


name: output

path: output

– run: |

          cp ./output/output.html ./docs/index.html

          rm -rf ./output

– name: Commit files

run: |

          git config –local “”

          git config –local “GitHub Action”

          git commit -m “generate html” -a –allow-empty

– name: Push changes

uses: ad-m/github-push-action@master


github_token: ${{ secrets.GITHUB_TOKEN }}

( see )- 

Some explanations:

  1. I need to serialize the 2 jobs – they cannot commit in parallel
  2. I need a git pull because the previous jobs commits  – and , somehow, the sources are just once read – not at run time
  3. I delete the output folder to not commit to the repository
  4. To commit , the file must exists and will be overwritten by the cp linux command ( that overwrites by default)

You can find the end result at (make sure you see the download section)  and the source code at