Create an automated README.md file with Github Actions, node.js and Airtable API
Tags: github, node, javascript, api
Published: 2020-08-05 12:33:16

Github has added a new feature to create a unique profile with README.md file. You can create an automated README.md file using Github Actions, Node.js and any API. In this article, I am using the Airtable API which is very easy to set up and it perfectly fits with Node.js. If you follow the steps below you can easily create an automated README.md file which gets updated when you update your Airtable Spreadsheet.

## Setting up Airtable
The First Step is to create an [Airtable](https://www.airtable.com) account. After creating the Airtable account it will ask you to create a base. I have created a base called "resume". Just add different tabs for Employment, Education, Awards and Web Configurations (configurations to keep about section, contact details and social media handles) in the base. It looks something like this.

![Airtable Screenshot](https://i.ibb.co/6gNhr0K/airtable-screenshot.png)

##### education Table

|programme|university|
|--|--|
|Digital Design and Branding MSc|Brunel University|
|Master of Computer Application|Guru Gobind Singh Indraprastha University|
|Bachelor of Computer Application|Guru Gobind Singh Indraprastha University|
|Certificate in Website Designing|F-Tech Computer Education|

##### employment Table

|designation|organisation|
|--|--|
| London School of Commerce Group of Colleges| Full Stack Developer (Programmer & Designer)|
|Torus Labs| Front End Designer|
|KR Creative Agency| Founder|

##### awards Table

|event |institution|position|
|-|-|-|
| Web Designing | Netaji Subhas Institute of Technology | 1 |
| Web Fiesta |	Indra Gandhi Institute of Technology | 1 |
| Online Web Designing | Indra Gandhi Institute of Technology | 1 |

After you have added all the content to the base just grab your API key from the account overview.

![Airtable API Key](https://i.ibb.co/CnjWfkz/airtable-api-key.png)

## Setting up Github

Now login to your Github and create a repository. The repository name should be same as your GitHub user name. my GitHub user name is [ketanrajpal](https://github.com/ketanrajpal) so I have created a repository named [ketanrajpal](https://github.com/ketanrajpal/ketanrajpal)

### Set up Airtable API as secret

Select the repository you just created and click on “Settings” tab on the top. On the left side you will see a tab named Secrets. Just click on it and add the API key. I named the secret as **AIRTABLE_API_KEY**

![Setting Secrets on Github](https://i.ibb.co/vBn3S3v/github-secret.png)

## Setup your node.js application

Make a pull request from Github and get all the files from Github to your machine. Initialize npm in the folder and also install the dependencies.
```javascript
    npm init
    npm install airtable dotenv
```
In the package.json file add 
```javascript
    "scripts": {
	    ...
	    "start": "node app.js"
	    ...
	},
```
Now create a file named .env, app.js and module.js and add the below code

## .env
.env file will store the Airtable API Secret to test it on the local machine

```javascript
AIRTABLE_API_KEY=<SECRET>
```

## module.js

module.js has all the functions which will interact with the Airtable API and get the data.

```javascript
// airtable documentation https://airtable.com/api
const airtable = require("airtable");
airtable.configure({
  endpointUrl: "https://api.airtable.com",
  apiKey: process.env.AIRTABLE_API_KEY,
});
var base = airtable.base("appwXxMRhgGdZYuqM");

// Fetching the Web Configurations from Airtable
const WebConfigurations = (callback) => {
  const RecordArray = [];
  base("web configurations")
    .select()
    .eachPage(
      (records, fetchNextPage) => {
        records.forEach((record) => {
          RecordArray.push(record.fields);
        });
        fetchNextPage();
      },
      (error) => {
        if (error) console.error(error);
        callback(RecordArray);
      }
    );
};

// Fetching the Employment history from Airtable
const Employment = (callback) => {
  const RecordArray = [];
  base("employment")
    .select({
      sort: [{ field: "serial", direction: "asc" }],
    })
    .eachPage(
      (records, fetchNextPage) => {
        records.forEach((record) => {
          RecordArray.push(record.fields);
        });
        fetchNextPage();
      },
      (error) => {
        if (error) console.error(error);
        callback(RecordArray);
      }
    );
};

// Fetching the Awards from Airtable
const Awards = (callback) => {
  const RecordArray = [];
  base("awards")
    .select({
      sort: [{ field: "position", direction: "asc" }],
    })
    .eachPage(
      (records, fetchNextPage) => {
        records.forEach((record) => {
          RecordArray.push(record.fields);
        });
        fetchNextPage();
      },
      (error) => {
        if (error) console.error(error);
        callback(RecordArray);
      }
    );
};

// Fetching the Education history from Airtable
const Education = (callback) => {
  const RecordArray = [];
  base("education")
    .select()
    .eachPage(
      (records, fetchNextPage) => {
        records.forEach((record) => {
          RecordArray.push(record.fields);
        });
        fetchNextPage();
      },
      (error) => {
        if (error) console.error(error);
        callback(RecordArray);
      }
    );
};

module.exports = { WebConfigurations, Employment, Awards, Education };
```

## app.js

```javascript
// Using the file system module to read and write the README.md file
const fs = require("fs");
const dotenv = require("dotenv");
dotenv.config();

const { WebConfigurations, Employment, Education, Awards } = require("./modules");

let content = "";

WebConfigurations((data) => {
  content = `
  ### :necktie: Ketan Rajpal
  ${
    data.filter((o) => {
      return o.name === "about";
    })[0].value
  }
  `;
  Employment((data) => {
    content += `### :briefcase: Professional Experience.
  `;
    data.forEach((record) => {
      content += `* **${record.designation}** :point_right: ${record.organisation}
  `;
    });
    Education((data) => {
      content += `### :mortar_board: Education.
  `;
      data.forEach((record) => {
        content += `* **${record.programme}** :point_right: ${record.university}
  `;
      });
      Awards((data) => {
        content += `### :beers: Awards.
  `;
        data.forEach((record) => {
          content += `* **${record.position === 1 ? "1st" : "2nd"}** position in **${record.event}** :point_right: ${record.institution}
  `;
        });
        fs.writeFileSync("README.md", content);
      });
    });
  });
});
```

After doing these changes just push the files to Github.

## Setting up Github Actions
Lets now set up Github Actions. Select your repository on Github and then select actions. In the actions tab click on ”set up a workflow yourself”. Just add the below code and save the file as build.yml

```
name: Create Profile README.md
on:
  push:
  pull_request:
  schedule:
    - cron: "0 * * * *"

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Setup Node
        uses: actions/setup-node@v1
        with:
          node-version: "12.x"
      - name: Install Dependencies
        run: npm install
      - name: Run app.js
        run: npm start
        env:
          AIRTABLE_API_KEY: ${{secrets.AIRTABLE_API_KEY}}
      - name: Commit the new README.MD file
        run: |-
          git diff
          git config --global user.email "ketanrajpal@gmail.com"
          git config --global user.name "ketanrajpal"
          git diff --quiet || (git add README.md && git commit -m "Update the README.md file")
          git push
```

## Running the Github Action
After saving the build file just go to the repository and then click on Actions. Click on Workflows **Create Profile README.md**. Now click the **Run workflow** button

![Github Action Workflow](https://i.ibb.co/NppdVjc/Screenshot-2020-08-05-at-5-10-27-PM.png)

Now just see the magic

![Ketan Rajpal Github Profile](https://i.ibb.co/tqfKVNx/Screenshot-2020-08-05-ketanrajpal-Overview.png)

For more information just check the repository [https://github.com/ketanrajpal](https://github.com/ketanrajpal)