Deploy a React/Parcel App to GitHub Pages and Azure

A short tutorial on automatically deploying to GitHub Pages and Azure Storage when pushing changes to GitHub.

Deployment flow. React/Parcel app to GitHub to Azure.
Deployment flow. React/Parcel app to GitHub to Azure.

In this tutorial, we'll go through the steps to deploy your React app, which uses Parcel for bundling, to both GitHub Pages and Azure Storage.

Prerequisites

I assume you have already set up your app, created it, and want to deploy it.
If not, below are a couple of resources (both doing basically the same thing) to look into for the initial setup:

You will also need:

  • A GitHub repository with your static website code.
  • An Azure account with an active subscription. (If you want to deploy to Azure)
  • Have the Azure CLI installed. (If you're going to deploy to Azure)

GitHub Pages

Enable

The first step is to enable GitHub Pages on your repository. See the official documentation for an excellent step-by-step process.

Make sure you have the publishing source folder set to /docs for the purpose of this tutorial.

Create build script

Next, we want a specific build script to ensure we have a clean build in the /docs folder.

Add the following line under "scripts" in your package.json file:

"build-github": "rm -rf docs/* && parcel build --public-url ./ --dist-dir docs"

You can test it locally by running npm run build-github, and you should see the /docs folder populated.

Manual vs automatic deployment

To ensure the latest version is displayed on your GitHub Page, you can run this command, npm run build-github before you push every time.

But you can also set it up to happen automatically every time you push to your main branch using GitHub Actions.

To do this, create a file under `.github/workflows/` called something like `build.yml` (You can name it something else if you want) and add the following:

name: build-for-github-pages
on:
  push:
    branches:
      - main # Make sure you have the correct branch name here
jobs:
  build:
    runs-on: ubuntu-latest

    permissions:
      contents: write

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20 # Make sure you have the correct Node version here
      - run: npm ci
      - run: npm run build-github
      - name: Commit files
        id: auto-commit-action
        uses: stefanzweifel/git-auto-commit-action@v5
        with:
          commit_message: Build latest changes # You can change this message
      - name: Push changes
        if: steps.auto-commit-action.outputs.changes_detected == 'true'
        uses: ad-m/github-push-action@master
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
      - name: No changes detected
        if: steps.auto-commit-action.outputs.changes_detected == 'false'
        run: echo "No changes!" # You can change this message

Every time you push to main (or a branch of your choosing), it will run the build-github script and automatically commit and push the changes made to the /docs folder to display the latest changes on your GitHub Page.

Please give it a go by pushing some changes to the repo and see what happens.

For more information about GitHub Pages, check out the docs.

Azure Storage

There are a few steps in this one, but stay with me.

  1. Create a storage account.

    The docs are pretty straightforward; you can keep the default values after completing the Basics tab.

  2. Enable static website hosting & upload.

    I's also simple if you follow the documentation.

    This will also show you how to manually upload your files for the first time to see if your site is working correctly.

  3. Generate deployment credentials and configure GitHub.

    Use GitHub Actions workflow to deploy your static website in Azure Storage.

    This will set it all up for the GitHub Actions flow, but there are a few changes we want to make if you are also using the GitHub Pages workflow.

    Below the previous build job, where we were automatically committed and pushed the changes made to the /docs folder, we want to add the following:

    upload:
        needs: build # Notice that we depend on the previous build to ensure we have the latest changes in the `/docs` folder.
        runs-on: ubuntu-latest
    
        steps:
        - uses: actions/checkout@v4
        - uses: azure/login@v1
            with:
            creds: ${{ secrets.AZURE_CREDENTIALS }}
    
        - name: Clean blob storage
            uses: azure/CLI@v1
            with:
            inlineScript: |
                az storage blob delete-batch --account-name <STORAGE_ACCOUNT_NAME> --auth-mode key -s '$web'
    
        - name: Upload to blob storage
            uses: azure/CLI@v1
            with:
            inlineScript: |
                az storage blob upload-batch --account-name <STORAGE_ACCOUNT_NAME> --overwrite --auth-mode key -d '$web' -s ./docs
    
        - name: Purge CDN endpoint
            uses: azure/CLI@v1
            with:
            inlineScript: |
                az cdn endpoint purge --content-paths  "/*" --profile-name "CDN_PROFILE_NAME" --name "CDN_ENDPOINT" --resource-group "RESOURCE_GROUP"
    
        # Azure logout
        - name: logout
            run: |
            az logout
            if: always()
    

    This will do a similar thing, removing everything in the `$web` container and uploading the latest changes in the `/docs` folder to ensure the latest changes are displayed on your Azure Storage website.

Custom domain

You can also add a custom domain to either of these sites, not both.

The following links will direct you to the relevant documentation for each host:

Conclusion

In this tutorial, we have gone through the steps to deploy your React app to both GitHub Pages and Azure Storage.

Thank you for reading, and I hope this helped you deploy your React/Parcel app where you want.

Good luck!