Deploy to Github Pages like a pro with Github Actions
Tags: vue, react, git
Published: 2020-03-15 09:12:10

---
title: Deploy to Github Pages like a pro with Github Actions
published: true
description: Vue and React guide to deploy to Github Pages automating deployment with Github Actions
tags: #vue, #react, #git
---

GitHub Pages is a static site hosting service designed to host your personal, organization, or project pages directly from a GitHub repository.

Note that GitHub Pages is a static site hosting service and doesn’t support server-side code such as, PHP, Ruby, or Python.

To learn more about the different types of GitHub Pages sites, take a look [here](https://help.github.com/articles/user-organization-and-project-pages/).

🤨 That’s the theory! Let’s start: 🤨

### **Copy the name of your project.**

![](https://dev-to-uploads.s3.amazonaws.com/i/uegn7c6igtbri4igf7pf.png)

The name of my repo is `deploy-react-to-gh-pages`.

### **For React specify the `homepage` in `package.json` [(Docs)](https://create-react-app.dev/docs/deployment/#building-for-relative-paths).**

```json
{
  ...
  "homepage": "/name-of-your-project/",
  ...
}
```

![](https://dev-to-uploads.s3.amazonaws.com/i/uqdu3flrcyp836mw1n4e.png)



### **For Vue create a new file in your project root named `vue.config.js` [(Docs)](https://cli.vuejs.org/config/#vue-config-js) and specify the `publicPath`  [(Docs)](https://cli.vuejs.org/config/#publicpath).**

```javascript
module.exports = {
  publicPath: '/name-of-your-project/'
}
```



### **Now commit and push your changes.**

**Note: if you don't commit your changes, you will lose them in the next command, so make sure you don't skip this step**



### **Open your terminal in your project and run:**

**Note:** For the following commands, if you are using vue, just copy paste them, if you are using react replace `dist` with `build`.
 `npm run build` creates a directory with a production build of your app. In vue, that directory in named `dist`, in react is named `build`.

- `git checkout --orphan gh-pages` [Docs](https://git-scm.com/docs/git-checkout/1.7.3.1#git-checkout---orphan)
- `npm run build`
- `git --work-tree dist add --all` [Docs](https://git-scm.com/docs/git#Documentation/git.txt---work-treeltpathgt) (**for react: replace dist with build**)
- `git --work-tree dist commit -m 'Deploy'` (**for react: replace dist with build**)
- `git push origin HEAD:gh-pages --force`
- `rm -r dist` (**for react: replace dist with build**)
- `git checkout -f master`
- `git branch -D gh-pages`
- Navigate to your github project and click 'Settings'
  ![](https://dev-to-uploads.s3.amazonaws.com/i/iup3jxzgr8f7v1gmjx33.png)
- Scroll to find the section 'Github Pages' , select the `gh-pages` branch and click 'Save'
  ![](https://dev-to-uploads.s3.amazonaws.com/i/ttynt8nge4ajxb29txpn.png)

### 🚀🚀 Congrats 🚀🚀

Your site is ready to be published.
You might have to wait a bit. Generally it takes 2–10 minutes until this process is done.

------


🤔🤔But... wait. You probably want to re-deploy. There must be a simpler solution instead of re-doing over and over again all the commands above.

### **Create a node.js script**

Now, we are gonna create a node.js script so whenever we want to deploy, we just run one command.

- Create a `scripts` folder in your project root.

- Inside `scripts` folder, create a `gh-pages-deploy.js` file.

- Copy and paste the code below:

  ```javascript
  const execa = require("execa");
  const fs = require("fs");
  
  (async () => {
    try {
      await execa("git", ["checkout", "--orphan", "gh-pages"]);
      console.log("Building...");
      await execa("npm", ["run", "build"]);
      // Understand if it's dist or build folder
      const folderName = fs.existsSync("dist") ? "dist" : "build";
      await execa("git", ["--work-tree", folderName, "add", "--all"]);
      await execa("git", ["--work-tree", folderName, "commit", "-m", "gh-pages"]);
      console.log("Pushing to gh-pages...");
      await execa("git", ["push", "origin", "HEAD:gh-pages", "--force"]);
      await execa("rm", ["-r", folderName]);
      await execa("git", ["checkout", "-f", "master"]);
      await execa("git", ["branch", "-D", "gh-pages"]);
      console.log("Successfully deployed");
    } catch (e) {
      console.log(e.message);
      process.exit(1);
    }
  })();
  ```

- Open `package.json` and add `execa` ([Docs](https://www.npmjs.com/package/execa)) to your `devDependencies`.

  ```json
    "devDependencies": {
      ...
      "execa": "latest"
    },
  ```

- Also add a new script in `scripts` section:

  ```json
    "scripts": {
     ...
     "gh-pages-deploy": "node scripts/gh-pages-deploy.js"
    },
  ```

- Finally, run `npm install`.



### ✨🎉 And... that's it! 🎉✨

**You can now deploy as many times as you want by just running `npm run gh-pages-deploy`.**

------

**Me-** But, hey... 🤫🤫! Wouldn't be even more exciting if we automate everything ?

**Everyone-** Do you mean that the app will be deployed itself ? 🤨🤨

**Me-** 😉😉

**Everyone-** 😲😲 

**Github Pages-** 🤭🤭

### Create a github action to automate deployment

Wouldn't be great if on every push on master, the app gets deployed without us doing nothing ?? 🧙‍♂️🧙‍♂️

We can achieve that by using... 🙌🙌 **Github Actions** 🙌🙌. 

GitHub Actions enables you to create custom software development life cycle (SDLC) workflows directly in your GitHub repository. [Docs](https://help.github.com/en/actions/getting-started-with-github-actions/about-github-actions)

Let's start:

- Create a `.github` (Don't forget the dot in front) folder in your project root

- Inside create another folder named `workflows`

- Inside `workflows` create a file named `gh-pages-deploy.yml` (The name is up to you).

- Now copy & paste the code below inside that file.

  ```yaml
  name: Deploy to github pages
  on:
    push:
      branches:
        - master
  jobs:
    gh-pages-deploy:
      name: Deploying to gh-pages
      runs-on: ubuntu-latest
      steps:
        - name: Setup Node.js for use with actions
          uses: actions/setup-node@v2
          with:
            version:  12.x
        - name: Checkout branch
          uses: actions/checkout@v2
  
        - name: Clean install dependencies
          run: npm ci
  
        - name: Run deploy script
          run: |
            git config user.name "Your username" && git config user.email "your email"
            npm run gh-pages-deploy
  ```

  **Important:** Make sure to change your username and email:

  ![](https://dev-to-uploads.s3.amazonaws.com/i/z5j8iikvs1st8f10031x.png)

  

- Commit and push your changes

- Now, navigate to your github project and first click *Actions* (1) then *Deploy to github pages* (2) and last click on the action (3).

  ![](https://dev-to-uploads.s3.amazonaws.com/i/hrgn3ww1w75uxxdfuzen.png)

- If everything goes well, you will see this:

  ![](https://dev-to-uploads.s3.amazonaws.com/i/2nshvsc10qivoif44d7f.png)



### 🌟🌟 Taadaaa!!! You successfully automated deployment!!! 🌟🌟

**Now, whenever you merge a PR or push to master this action will run and will deploy your app automatically**. 👏👏



### Things to know

- React & Vue provide their own steps to deploy on github pages:
  - For React, See the steps [Here](https://create-react-app.dev/docs/deployment/#github-pages).
  - For Vue, see the steps [Here](https://cli.vuejs.org/guide/deployment.html#github-pages).
  - Also [Read the steps to create a github action](https://help.github.com/en/actions/configuring-and-managing-workflows/configuring-a-workflow)
- Great libraries to use for deploying to gh-pages:
  - [gh-pages](https://www.npmjs.com/package/gh-pages)
  - [push-dir](https://www.npmjs.com/package/push-dir)
- It's definitely a good thing to know how to manually deploy to gh-pages. Also, the script is very minimal and easy to understand. This simplicity gives you the power to modify it. (add colors, emojis, promts).
  So here are some great resources to enrich the script:
  - [inquirer](https://www.npmjs.com/package/inquirer)
  - [ora](https://www.npmjs.com/package/ora)
  - [chalk](https://www.npmjs.com/package/chalk)
  - [node-emoji](https://www.npmjs.com/package/node-emoji)
- Repositories (feel free to checkout the commits):
  - [deploy-vue-to-gh-pages](https://github.com/Rolanddoda/deploy-vue-to-gh-pages)
  - [deploy-react-to-gh-pages](https://github.com/Rolanddoda/deploy-react-to-gh-pages)

🙏🙏 Thank you for reading. I would be glad to help you if you face any problem, so don't hesitate to email me at rolanddoda2014@gmail.com 🙏🙏