bridgetownrb / bridgetown

A next-generation progressive site generator & fullstack framework, powered by Ruby
https://www.bridgetownrb.com
MIT License
1.13k stars 114 forks source link

docs: How to setup GitHub Pages + Bridgetown #820

Open KonnorRogers opened 10 months ago

KonnorRogers commented 10 months ago

Motivation

GitHub Pages is currently not the easiest to setup with a number of gotchas.

Suggestion

Add docs on how to deploy with GH pages!

Deploying to GitHub pages with Bridgetown + GitHub actions + preview deployments.

First step. Let's add the gh-pages packages to make deploys easier.

  1. yarn add -D gh-pages
  2. Make a build command in your package.json "scripts" key that looks like this:
  "scripts": {
    "esbuild": "node esbuild.config.js --minify",
    "build": "NODE_ENV=\"production\" yarn run esbuild && BRIDGETOWN_ENV=\"production\" bundle exec bridgetown build && touch output/.nojekyll"
  },
  1. Setting a base_url. I know Bridgetown deprecated the base_url options, but I really liked it. Modify config/initializers.rb to look like this:
Bridgetown.configure do |config|
  config.url = ENV.fetch("URL", "https://konnorrogers.github.io")
  config.base_path = ENV.fetch("BASE_PATH", "/rougeify")
  config.base_url = config.url + config.base_path
end
  1. Optionally, you can also make a .env or .envrc at the root of your project so you can simulate "base_path" deployments.
# .envrc
export URL="http://localhost:4000"
export BASE_PATH="/rougeify"
  1. With ENV variables in place, let's modify our esbuild.config.js
// esbuild.config.js

+ const path = require("node:path")
const build = require("./config/esbuild.defaults.js")

// You can customize this as you wish, perhaps to add new esbuild plugins.
//
// ```
// const path = require("path")
// const esbuildCopy = require('esbuild-plugin-copy').default
// const esbuildOptions = {
//   plugins: [
//     esbuildCopy({
//       assets: {
//         from: [path.resolve(__dirname, 'node_modules/somepackage/files/*')],
//         to: [path.resolve(__dirname, 'output/_bridgetown/somepackage/files')],
//       },
//       verbose: false
//     }),
//   ]
// }
// ```
//
// You can also support custom base_path deployments via changing `publicPath`.
//
// ```
// const esbuildOptions = {
//   publicPath: "/my_subfolder/_bridgetown/static",
//   ...
// }
// ```

/**
 * @typedef { import("esbuild").BuildOptions } BuildOptions
 * @type {BuildOptions}
 */
const esbuildOptions = {
  + // If for some reason we need the `base_path` in the frontend. We could also add `base_url`. But its largely not needed.
  + define: {
  +  "process.env.BASE_PATH": `"${process.env.BASE_PATH}"`
  + },
  + // Adds `/<base_path>/_bridgetown/static`
  + publicPath: path.join(process.env.BASE_PATH, "_bridgetown", "static"),
  plugins: [
    // add new plugins here...
  ],
  globOptions: {
    excludeFilter: /\.(dsd|lit)\.css$/
  }
}

build(esbuildOptions)

Deploying from GitHub Actions

  1. Go to https://github.com///settings
  2. Go to "Actions -> General"
  3. Change from "Read repository contents" to "Read and Write Permissions". This allow you to deploy to gh-pages using GitHub actions.
github-actions-permissions

This gives your GitHub actions permissions to write to the gh-pages branch.

  1. Now, we need to setup GH Pages in the Settings -> Pages tab.

https://github.com/{username}/{repo}/settings/pages

Yours should look something like this where Source is Deploy from a branch. And the branch should be set to gh-pages.

Screenshot 2023-10-29 at 12 45 17 AM
  1. Create your GitHub Actions file. I named mine .github/workflows/deploy-site.yml

Here's the contents:

# .github/workflows/deploy-site.yml

name: Deploy Site

on:
  push:
    branches:
      - main # deploy main. If your branch is `master`, you'll have to replace that throughout this file.
  pull_request: # This will publish a site preview on every pull request, and also run the build command to test if the site is broken.
  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [20]
        ruby-version: [3.1]
    env:
      PR_PATH: pull/${{github.event.number}}
    steps:
      - name: Comment on PR
        uses: hasura/comment-progress@v2.2.0
        if: github.ref != 'refs/heads/main'
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          repository: ${{ github.repository }}
          number: ${{ github.event.number }}
          id: deploy-preview
          message: "Starting deployment of preview ⏳..."

      - name: Set domain
        # If you're using the default github pages url, use this instead:
        run: echo "DOMAIN=${{ github.actor }}.github.io" >> $GITHUB_ENV

      - uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}

      # https://stackoverflow.com/questions/76107036/how-do-i-use-yarn-version-3-5-on-github-actions-error-cannot-find-module
      - name: Install Yarn Stable
        run: corepack prepare yarn@stable --activate

      - name: Activate Yarn stable
        run: yarn set version stable

      - name: Install NPM dependencies
        run: yarn install --immutable --check-cache

      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby-version }}
          rubygems: latest
          bundler-cache: true

      - name: Set production base URL
        run: |
          echo "URL=https://${{ env.DOMAIN }}" >> $GITHUB_ENV
          echo "BASE_PATH=/${{ github.event.repository.name }}" >> $GITHUB_ENV

      - name: Set base_path for preview if PR
        if: github.ref != 'refs/heads/main'
        run: echo "BASE_PATH=/${{ github.event.repository.name }}/${{ env.PR_PATH }}" >> $GITHUB_ENV

      - name: Set base_url
        run: echo "BASE_URL=$URL/$BASE_PATH" >> $GITHUB_ENV

      - name: Build site
        run: yarn run build

      - name: Set username + email
        run: |
          git config --global user.email "support+actions@github.com"
          git config --global user.name "github-actions-bot"

      - name: Deploy with gh-pages
        if: github.ref == 'refs/heads/main'
        run: |
          git remote set-url origin https://git:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git
          yarn exec gh-pages -d ./output --dotfiles -b gh-pages -- -u "github-actions-bot <support+actions@github.com>"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Deploy preview with gh-pages
        if: github.ref != 'refs/heads/main'
        run: |
          git remote set-url origin https://git:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git
          yarn exec gh-pages -d ./output --dotfiles --dest "${{ env.PR_PATH }}" -b gh-pages -- -u "github-actions-bot <support+actions@github.com>"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Update comment
        uses: hasura/comment-progress@v2.2.0
        if: github.ref != 'refs/heads/main'
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          repository: ${{ github.repository }}
          number: ${{ github.event.number }}
          id: deploy-preview
          message: "A preview of ${{ github.event.after }} is uploaded and can be seen here:\n\n ✨ ${{ env.BASE_URL }} ✨\n\nChanges may take a few minutes to propagate. Since this is a preview of production, content with `draft: true` will not be rendered. The source is here: https://github.com/${{ github.repository }}/tree/gh-pages/${{ env.PR_PATH }}/"

I know this was a lot, but this was me dumping what I did to deploy my last 3/4 sites with GH Pages. Sorry if it didn't make sense.

jaredcwhite commented 7 months ago

Just making a note here we should either commit to updating docs to support GH Pages or make a note we don't offer support for GH Pages. Adding the 2.0 milestone.

SimBed commented 1 month ago

@KonnorRogers I followed these steps, but the Github workflow hit an error at:

yarn install --immutable --check-cache

Do you have any suggestions? ( I started off with a clean set of files... bridgetown new mysite ...)

image

SimBed commented 1 month ago

It turns out I was using Yarn Classic and upgrading to Yarn Modern (berry) solves the problem.