Blog post: Getting to Know GitHub Actions with Markdownlint
Tags: github, markdownlint, actions, ci
Published: 2019-11-15 15:59:03

---
title: Blog post: Getting to Know GitHub Actions with Markdownlint
published: true
description: one mans venture into GitHub Actions with Markdownlint
tags: github, markdownlint, actions, ci
---
Finally [GitHub Actions][github_actions] got out of beta! Well I actually participated in the beta programme, but I wanted to wait a bit with writing about GitHub Actions until I had used it some more and I wanted to evaluate it in context of a very specific set of projects, where I did not have access to GitHub Actions during the beta, you can see [my result](https://github.com/jonasbn/hello-github-actions) from going through the tutorial.

I maintain a large set of public specifications for services offered by my employer and for which I am the product manager. A long story short, after discovering Markdown I migrated from Word documents to GitHub some years ago - this solved a lot of problems. I actually [blogged about it][specs_ftw_post] back in 2016 and as for that post, this post is not endorsed by my employer either.

Many edits and changes have run under the bridge since 2016, but the framework is the same. I have extended my toolchain to use [Markdownlint][markdownlint] and [Travis CI][travis_ci]. I also [blogged about this][markdownlint_post], where the use of Travis CI was part of the _bonus_ information.

Along came GitHub Actions and I decided to check it out. Do note that there is absolutely **NOTHING** wrong with Travis CI and I use it for a lot of projects, but I wanted to consolidate the open sourced specifications offered by my employer, the reasoning about this was my personal interpretation of an issue related to company policy and use of systems, so in order to minimize the amount of red tape, I decided to consolidate.

Do note this posting is not going to be a tutorial on how to get started with GitHub Actions, it is simply a reflection of the steps I have taken for a set of GitHub hosted projects to demonstrate how to work with GitHub Actions, solving a very basic use-case previously handled using Travis CI.

Since all of the specifications I work on are written in Markdown, I pretty early on fell in love with Markdownlint. I started using it with Sublime Text and later Visual Studio Code (or `code`). At some point I decided to utilize [Continuous Integration][ci] for Markdown using Markdownlint and Travis CI as I [mentioned earlier][markdownlint_post].

The configuration (`.travis.yml`) for Markdownlint using Travis CI, looks as follows (currently):

```yaml
language: node_js
node_js:
- '8'
install:
- npm install -g markdownlint-cli
script:
- markdownlint *.md ; markdownlint */*.md
```

Now lets take a step back, since I actually started during the beta, with the goal in mind to migrate all the public specification repositories from Travis CI to GitHub Actions, I actually started with [my TIL collection][til] (_Today I Learned_).

First I added the the directory structure `.github/workflows/` and the file: [`main.yml`]((https://github.com/jonasbn/til/blob/master/.github/workflows/main.yml))

```yaml
name: Markdownlint Workflow
on: push

jobs:
  build:
    name: Markdownlint
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@master
    - uses: ./github-action-markdownlint
```

And then the actual action pointed to in the workflow definition. The action consists of a Docker image ([`Dockerfile`](https://github.com/jonasbn/til/blob/master/github-action-markdownlint/Dockerfile)) and an entry point executable (this is a Docker thing and beyond the scope of this post).

```Dockerfile
FROM node:10.16.0-alpine

LABEL "com.github.actions.name"="Markdownlint"
LABEL "com.github.actions.description"="Tests all Markdownfiles"
LABEL "com.github.actions.icon"="mic"
LABEL "com.github.actions.color"="purple"

LABEL "repository"="http://github.com/jonasbn/til"
LABEL "maintainer"="jonasbn"

RUN npm install -g markdownlint-cli

ADD entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
```

The entry point executable ([`entrypoint.sh`](https://github.com/jonasbn/til/blob/master/github-action-markdownlint/entrypoint.sh)) is just a basic shell script, which does partly resemble the `.travis.yml`.

```bash
#!/bin/sh -l

echo ""
echo "Using Markdownlint on all Markdown files"
echo "----------------------------------------"

markdownlint *.md && markdownlint */*.md
```

With this setup, on `push` against my master branch. All the Markdown is evaluated using Markdownlint and uses my `markdownlint` configuration file: `.markdownlint.json`.

In order to mimic Travis CI, I decided to add a badge. This did not work out of the box as easily as the other parts and I did [a little write up](https://dev.to/jonasbn/til-adding-an-action-workflow-status-badge-to-your-github-repository-388d) describing the issue. Bottom line, be aware that the name you specify in your workflow YAML file is significant.

You can see the result [here](http://jonasbn.github.io/til/) notice the badge.

When GitHub Actions became public available and I found the (company) time and I started the migration.

All of the above was put to use, I did however run into a minor issue with `markdownlint` since my TIL repository is a deep structure and some of the other repositories were shallow, The followling line was teasing me a bit.

```bash
markdownlint *.md && markdownlint */*.md
```

I wanted the action to be flexible if a given repository would all of a sudden become a deeper structure, so I came up with the following solution.

```bash
find . -name "*.md" | xargs -t markdownlint
```

Later when reading the documentation I found out that I could simply write:

```bash
markdownlint .
```

But I actually prefer the `xargs -t` which emits all the files being worked at, which makes it easier to debug and since `markdownlint` does not have a _verbose_ flag at this time.

The output from the action, can be a bit put of order, so I am evaluating handling the output buffering so order is restores. I extended the endpoint with some _niceness_ when this go well (to avoid that empty feeling)...

```bash
#!/bin/sh -l

echo ""
echo "Using Markdownlint on all Markdown files"
echo "----------------------------------------"

find . -name "*.md" | xargs -t markdownlint

EXITCODE=$?

test $EXITCODE -eq 0 && echo "Everything looks good" || echo "Markdown does not comply with Markdownlint configuration";
exit $EXITCODE
```

REF: [StackOverflow](https://stackoverflow.com/questions/26675681/how-to-check-the-exit-status-using-an-if-statement)

You can see all of [the repositories](https://github.com/DK-Hostmaster) using this setup on GitHub.

And then I found out that somebody made [an action you can install from the GitHub Marketplace](https://github.com/marketplace/actions/markdownlint-cli). So either you can take all the snippets I have shared and build your own or you can use the one from the Marketplace, whatever rocks your boat.

This was aimed at migrating from Travis CI to GitHub to limit the number of systems/dependencies and it was aimed at Markdown contents. What if you wanted to do the same for XML. I did demonstrate this for [one of the repositories](https://github.com/DK-Hostmaster/epp-xsd-files) as described [in one of the mentioned blog posts][markdownlint_post]...

Well the same repository was ALSO migrated.

I followed the above recipe, but added an additional workflow and action:

- [`.github/workflows/xmllint.yml`](https://github.com/DK-Hostmaster/epp-xsd-files/blob/master/.github/workflows/xmllint.yml)
- [`github-action-xmllint/Dockerfile`](https://github.com/DK-Hostmaster/epp-xsd-files/blob/master/github-action-xmllint/Dockerfile)
- [`github-action-xmllint/entrypoint,sh`](https://github.com/DK-Hostmaster/epp-xsd-files/blob/master/github-action-xmllint/entrypoint.sh)

This repository holds two workflows, triggered by the `pull` event.

> Why two workflows?

Then I can have a badge representing each, do [check it out](https://github.com/DK-Hostmaster/epp-xsd-files).

The documentation on GitHub actions is quite okay and I did not touch on anything advanced. I hope this can spark your interest, get you going or help you out - or as it SHOULD be put:

> “Are there any questions or compliments?” 

Quote from Twitter: [Tweet from @ishabazz](https://twitter.com/ishabazz/status/1166737266003152896?s=20)

[markdownlint_post]: https://dev.to/jonasbn/blog-post-markdownlint-24ig
[specs_ftw_post]: https://lastmover.wordpress.com/2016/06/09/public-specifications-ftw/
[github_actions]: https://github.com/features/actions
[travis_ci]: https://travis-ci.org/
[markdownlint]: https://github.com/DavidAnson/markdownlint
[ci]: https://en.wikipedia.org/wiki/Continuous_integration
[til]: http://jonasbn.github.io/til/