diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 0000000000..d99b1fee2d
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,81 @@
+name: Deploy to GithubPages
+
+on:
+ push:
+ branches: ["master"]
+
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
+# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
+concurrency:
+ group: "pages"
+ cancel-in-progress: false
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Setup Pages
+ uses: actions/configure-pages@v4
+
+ - name: Set node version
+ uses: actions/setup-node@v3
+ with:
+ node-version: '18.x'
+
+ - name: Install
+ run: |
+ npm install
+ npm run setheapsize
+
+ - name: Lint
+ run: npx grunt lint
+
+ - name: Unit Tests
+ run: |
+ npm test
+ npm run testnodeconsumer
+
+ - name: Production Build
+ if: success()
+ run: npx grunt prod --msg="Release Blog Post Discord"
+
+ - name: Generate sitemap
+ run: npx grunt exec:sitemap
+
+ - name: UI Tests
+ if: success()
+ run: |
+ sudo apt-get install xvfb
+ xvfb-run --server-args="-screen 0 1200x800x24" npx grunt testui
+
+ - name: Prepare for GitHub Pages
+ if: success()
+ run: npx grunt copy:ghPages
+
+ - name: Deploy to GitHub Pages
+ if: success() && github.ref == 'refs/heads/master'
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./build/prod
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4