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 readme.md 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 https://www.npmjs.com/package/markdown-pdf .

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 = [

“README.md”,”Chapter01/readme.md”, “Chapter02/readme.md”,”Chapter03/readme.md”,”Chapter04/readme.md”

]

, 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 https://github.com/ignatandrei/console_to_saas/tree/master/print .

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 https://github.com/ignatandrei/console_to_saas to https://ignatandrei.github.io/console_to_saas/

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’

on:

push:

paths:

– ‘**.md’

jobs:

build:

runs-on: ubuntu-latest

steps:

– uses: actions/checkout@v2

– name: print pdf

run: |

        chmod +x ./print/getBook.bat

        cd print       

        ./getBook.bat

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

– uses: actions/upload-artifact@v1

with:

name: ConsoleToSaas.pdf

path: ./print/book.pdf

– name: Commit files

run: |

        git config –local user.email “action@github.com”

        git config –local user.name “GitHub Action”

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

– name: Push changes

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

with:

github_token: ${{ secrets.GITHUB_TOKEN }}

( see https://github.com/ignatandrei/console_to_saas/blob/master/.github/workflows/main.yml )

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

convert_via_pandoc:

runs-on: ubuntu-18.04

needs: build

steps:

– 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 README.md”

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

– uses: actions/upload-artifact@master

with:

name: output

path: output

– run: |

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

          rm -rf ./output

– name: Commit files

run: |

          git config –local user.email “action@github.com”

          git config –local user.name “GitHub Action”

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

– name: Push changes

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

with:

github_token: ${{ secrets.GITHUB_TOKEN }}

( see https://github.com/ignatandrei/console_to_saas/blob/master/.github/workflows/main.yml )- 

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 https://ignatandrei.github.io/console_to_saas/ (make sure you see the download section)  and the source code at https://github.com/ignatandrei/console_to_saas