Vite + Vue3 + VuetifyのサイトをGithub ActionsでGithub Pagesに公開

# はじめに
GitHubのGitHub Pagesで静的HTMLを公開できるのは知っていたんですが、GitHub Actionsのことを全く知らなかったため、Vueで作ったサイトをGitHub Actionsを使って公開するのに1日かかりました。

GitHub Pagesで公開する方法は、GitHub Actionsを直接使うもの以外にも、branchの`/`や`/docs`ディレクトリの中身を公開する方法があります。しかし、これらの方法だと、`main`に`/docs`を置いたり、専用の`gf-pages`ブランチを用意しなければなりません。GitHub Actionsを使えばレポジトリを汚さずページを公開できます。

今回は備忘録として、Vite + Vue3 + VuetifyでGitHub Actionsを使ってGitHub Pagesを公開する方法を回想していきます。

# 参考
以下のページを参考にしました。

https://qiita.com/canary_llama/items/74e86129cf61339abd72

https://qiita.com/kohecchi/items/5d06936745118045a308

https://ja.vitejs.dev/guide/static-deploy

https://zenn.dev/tinytony/articles/8db0967a239635

これがなければ永遠に表示されないことに悩んでいました。

# 環境
- windows11 + wsl(Ubuntu 22.04.3 LTS)
- nodejs(v20.16.0)
- npm(10.8.2)
- git(2.34.1)
- VSCode(1.92.1)

※VSCodeでGitHubと事前に連携しているため、認証関係は飛ばしています。

# 方法

## プロジェクト作成
プロジェクトを作成したいディレクトリに移動します。
（自分の場合は、~/work）
```
$ cd ~/work
```
[公式の説明](https://vuetifyjs.com/en/getting-started/installation/#using-vite)にしたがってVuetifyのプロジェクトを作成します。
```
$ npm create vuetify@latest

Need to install the following packages:
create-vuetify@2.2.6
Ok to proceed? (y) y

> npx
> create-vuetify

Vuetify.js - Material Component Framework for Vue

# プロジェクト名（ディレクトリ名）は今回「vue_vuerify_test」としました
? Project name: ›  vue_vuetify_test

# プリセットはVue + Vuerifyのみを選択
? Which preset would you like to install? › Barebones (Only Vue & Vuetify)
❯   Barebones (Only Vue & Vuetify)
    Default (Adds routing, ESLint & SASS variables)
    Recommended (Everything from Default. Adds auto importing, layouts & pinia)
    
# TypeScriptは使わないのでNoを選択（使う人はYes）
? Use TypeScript? › No 

# パッケージマネージャーはnpmを選択
? Would you like to install dependencies with yarn, npm, pnpm, or bun? › npm
    yarn
❯   npm
    pnpm
    bun
    none

# 依存関係をインストールYes
✔ Install Dependencies? … Yes
```
インストールが終わったら、以下のコマンドを実行して
```
$ cd vue_vuetify_test/
$ npm run dev
```
ブラウザで`http://localhost:3000/`にアクセスして表示されればインストール成功です。

![Vuetify表示](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860270/dfe66510-016a-9320-e72a-a595e22352d2.png)

Ctrl(or Cmd) + Cで`npm run dev`を終了させます。

----

Vuetifyを使わない、Vueのみのプロジェクトにしたい場合は、
[Vite公式の説明](https://ja.vitejs.dev/guide/)の通りにすれば、ほぼ同じようにできます。
```
npm create vite@latest

✔ Project name: … vue_vuetify_test
✔ Select a framework: › Vue
✔ Select a variant: › JavaScript
```

Vite + Vueの場合は以下のような表示になると思います。
![Vite+Vue](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860270/7ead69aa-2c34-2d15-0d62-ae0cbd5849c8.png)

## コードの修正
現在の状態だとローカルでbuildするときはいいんですが、GitHub Actionsからbuild/deployされるとパスが通らなくなってしまうため、`vite.config.mjs`の末尾にコードを挿入します。
```diff_javascript:vite.config.mjs:
// Plugins
import Components from "unplugin-vue-components/vite";
import Vue from "@vitejs/plugin-vue";
import Vuetify, { transformAssetUrls } from "vite-plugin-vuetify";
import ViteFonts from "unplugin-fonts/vite";

// Utilities
import { defineConfig } from "vite";
import { fileURLToPath, URL } from "node:url";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    Vue({
      template: { transformAssetUrls },
    }),
    // https://github.com/vuetifyjs/vuetify-loader/tree/master/packages/vite-plugin#readme
    Vuetify(),
    Components(),
    ViteFonts({
      google: {
        families: [
          {
            name: "Roboto",
            styles: "wght@100;300;400;500;700;900",
          },
        ],
      },
    }),
  ],
  define: { "process.env": {} },
  resolve: {
    alias: {
      "@": fileURLToPath(new URL("./src", import.meta.url)),
    },
    extensions: [".js", ".json", ".jsx", ".mjs", ".ts", ".tsx", ".vue"],
  },
  server: {
    port: 3000,
  },
+ build: {
+   outDir: "dist",
+ },
+ base: "./",
});
```


## GitHubにアップロード
GitHubの[New Repository](https://github.com/new)からリポジトリを作成します。
リポジトリ名はプロジェクト名にします。
公開範囲はPublic(でないと無料版ではGitHub Pagesを利用できない)、他はオフでいいです。
![リポジトリ作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860270/36f531de-785a-03ff-0941-b4360f6d8577.png)

作成したら表示されるレポジトリのURL(`https://github.com/~~~/~~~.git`)をコピーして
![レポジトリURL](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860270/49309687-3260-d7b7-bb3f-881882818d70.png)

ローカルの`vue_vuetify_test/`から
```
$ git init
$ git remote add origin レポジトリのURL
$ git add -A
$ git commit -m "Initial commit"
$ git branch -M main
$ git push -u origin main
```
でGitHubにプッシュできるはずです。

## GitHub Pagesのセッティング
GithubレポジトリのSetting -> PagesからGithub Pagesのセッティングを行います。

Build and deploymentがDeploy from a branchになっているので、Github Actionsを選びます。
![GitHub Pages](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860270/4a2d7896-ed18-0e75-d13f-df3d310ba01f.png)

選択すると下に出てくる、GitHub Pages JekyllのボックスのConfigureを押します。
![Github Actions](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860270/32e8be45-e9c8-d8b7-70f2-4c8311d42ceb.png)

表示された`jekyll-gh-pages.yml`を編集します。

```diff_yaml:jekyll-gh-pages.yml
# Sample workflow for building and deploying a Jekyll site to GitHub Pages
name: Deploy Jekyll with GitHub Pages dependencies preinstalled

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 permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
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 job
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Setup Pages
        uses: actions/configure-pages@v5
+     - run: npm ci
+     - run: npm run build
      - name: Build with Jekyll
        uses: actions/jekyll-build-pages@v1
        with:
-         source: ./
+         source: ./dist
          destination: ./_site
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3

  # Deployment job
  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

```
そうしたら、右上緑色のCommit changesを押します。

`jekyll-gh-pages.yml`の上部分では以下のようにワークフローの起動タイミングが定義されており、
```yaml
on:
  # Runs on pushes targeting the default branch
  push:
    branches: ["main"]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:
```
デフォルトの設定では、mainブランチにpushされたときと、workflow画面から直接起動できるようになっています。GitHubのActions画面で左のタブからDeploy Jekyll with GitHub Pages dependencies preinstalledを押すとrun workflowと表示されるのでそこから能動的に起動できます。

今回は`jekyll-gh-pages.yml`をCommit changesでpushされたのでActionが起動します。
![GitHub Actions](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860270/476a794e-2670-36b6-83e3-61ed574c23ba.png)
おそらく数十秒で完了します。
![Build](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860270/a9931a06-3a9d-8064-a0b5-95be375b9636.png)
deployに表示されたURLを開いて、`npm run dev`したときと同じ画面が表示されれば完了です。

アップロードされたページがこちら

https://katabami83.github.io/vue_vuetify_test/

GitHubから`jekyll-gh-pages.yml`を直接編集してpushしたので、このままローカルから編集してpushするとエラーが起きます。
忘れずにプルしておきましょう。
```
$ git pull origin main
```
終わりです。