Skip to content

GitHub Actions to automate your build#

Deploying static frontend web apps (such as Vanilla, Angular, React, Vue, etc) in GitHub?

It's possible to just add, commit and push your code and automate things like npm run build to setup Github Pages for your repository.

Introduction#

If you were manually deploying your application before using things like npm run build and additional setups like creating a docs/ folder, then you came to the right place.

Getting Started#

Configure repository#

You must already have a GitHub repository before the following steps:

  1. Go to Settings tab
  2. Go to Pages under Code and Automation section
  3. Select GitHub Actions the Source dropdown under Build and Deployment section

Add GitHub workflow#

Create ci.yml file in .github/workflows folder.

.
├─ .github\workflows
│    └─ ci.yml (1)
├─ ...
└─ README.md
  1. You can rename the file to any name you want.
    (e.g. deploy.yml)

General Build Template#

When you have to generate a /dist folder, then you need this content (1)

  1. See example:
    https://github.com/lightzane/test-labs/blob/main/.github/workflows/ci.yml
ci.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# Simple workflow for deploying static content to GitHub Pages
name: Deployment of static content to Pages

on:
  # Runs on pushes targeting the default branch
  push:
    branches: ['main']

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# Sets the GITHUB_TOKEN permissions to allow deployment to GitHub Pages
permissions:
  contents: read
  pages: write
  id-token: write

# Allow one concurrent deployment
concurrency:
  group: 'pages'
  cancel-in-progress: true

jobs:
  # Single deploy job since we're just deploying
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Set up Node
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'
      - name: Install dependencies
        run: npm ci
      - name: Build
        run: npm run build
      - name: Setup Pages
        uses: actions/configure-pages@v4
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          # Upload dist folder
          path: './dist'
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

Test Template#

When you have unit tests to run in background (i.e. Vitest, Jest) (1)

  1. See example:
    https://github.com/lightzane/try-vitest/blob/main/.github/workflows/test.yml

    See example run:
    https://github.com/lightzane/try-vitest/actions/runs/8459849190/job/23176953453#step:5:1

test.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
name: Unit test workflows

on:
  push:
    branches: [main]

jobs:
  unit-test:
    name: Unit tests with coverage
    runs-on: ubuntu-latest
    env:
      ci: true
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up node
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run tests with coverage
        run: npx vitest --coverage # (1)!
      # Note: env.ci is set to true, so this will only run once without watch mode
  1. When using Jest, update accordingly:

    npx jest
    

    Or when you have custom scripts in your package.json

    npm run test:cov
    

MkDocs Material Template#

GitHub Pages settings NOT required

When deploying MkDocs Material, there is no need to setup anything in repository settings.

Just create the ci.yml in your .github/workflows with the following content:

ci.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
name: ci

on:
  push:
    branches:
      - main

permissions:
  contents: write

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Configure Git Credentials
        run: |
          git config user.name github-actions[bot]
          git config user.email 41898282+github-actions[bot]@users.noreply.github.com

      - name: Setup Python 3.x
        uses: actions/setup-python@v5
        with:
          python-version: 3.x

      - name: Set cache_id
        run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV

      - name: Setup cache
        uses: actions/cache@v4
        with:
          key: mkdocs-material-${{ env.cache_id }}
          path: .cache
          restore-keys: |
            mkdocs-material-

      - name: Install pip dependencies
        run: pip install mkdocs-material

      - name: Deploy
        run: mkdocs gh-deploy --force

GitHub Pages

Remember when you were manually building your apps and saving it to /docs folder?

It is actually using the same GitHub Actions behind the scenes when you selected the Deploy from a branch under Source dropdown.

Auto Release Tag Template#

You can do more than just deployment!

Such as automatically creating git tag or Releaes Tags for your GitHub repository.

See example:
https://github.com/lightzane/test-labs/blob/main/.github/workflows/release-tag.yml

release-tag.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
name: Auto Release Tag

on:
  push:
    branches: [main]

permissions:
  contents: write

jobs:
  create_release:
    name: Create Release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Node
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - name: Extract version from package.json
        run: |
          version=$(node -e "console.log(require('./package.json').version)")
          echo "PACKAGE_VERSION=$version" >> $GITHUB_ENV

      - name: Create Release Tag
        run: |
          version=$PACKAGE_VERSION
          new_tag="v$version"
          git tag $new_tag
          git push origin $new_tag -f
        # -f will forcefully override any existing release

Regarding the highlighted Line 34:

You can remove the -f flag if you want the pipeline to fail and so that you could be remind to update your version.

Or you can also handle this locally before even pushing your code.

💡 See this blog to see how you can prevent committing and pushing your code with the same version.

Conclusion#

There you have it! 🔥 You have used GitHub Actions to create workflows to automate the build and deployment of your application.

You just went through the basics of CI/CD, which stands for Continuous Integration and Continuous Deployment. GitHub Actions is a feature in GitHub where it helps you automate your software workflows with CI/CD.

Learn more: https://github.com/features/actions

Comments