00 缘由

手上有个前端项目使用的 Vite 来打包,我打算使用免费的 Github Actions 执行 workflows 工作流,实现自动打包,并通过 Github Pages 自动部署打包后的页面。

以前只知道用 Github Pages 部署静态内容,但对 Github Actions [1] 知之甚少,今天正式认识一下 GitHub workflows,探究之前在别人的项目根目录下总是见到的 .github/workflows/deploy.yml 文件的身份之谜。

话不多说,开始。


01 何为 GitHub Actions 工作流?

GitHub Actions 组织页面,我们可以看到它的自身定位是:

“Automate your GitHub workflows”

“自动化你的工作流”

GitHub Actions 提供了一种在 GitHub 仓库中直接自动化、定制和执行软件工作流程的方法,从而简化了开发、测试和部署过程[2]

02 如何使用 GitHub Actions ?

2.1 设置仓库的生成和部署源

若要为项目仓库配置为使用 GitHub Actions 进行构建和发布,需要执行以下操作[3]

  1. 打开 GitHub 的项目仓库。

  2. 在存储库名称下,单击 “Settings”(设置)。

    2024-13 (1)

  3. 在边栏的“Code and automation”(代码和自动化)部分中,单击“ Pages”。

  4. 在“Build and deployment”(生成和部署)的“Source”(源)下,选择“GitHub Actions”。

    2024-13 (2)

  5. GitHub 将推荐多个入门工作流(workflows)。 如果已有用于发布站点的工作流,可跳过此步骤。 否则,需选择其中一个选项来创建 GitHub Actions 工作流。

2.2 寻找合适的 workflows 模板

注意:Vite 官方文档中也提供了提供了一个安装依赖项和使用 npm 构建的工作流程样本,请见 部署静态站点:GitHub Pages

如果使用推荐的工作流,可以点击上图中“GitHub Actions”按钮下的 browse all workflowscreate your own 链接。

如果点击后者 create your own ,GitHub会引导你在该仓库根目录下创建 .github/workflows/ 路径,并添加一个以 .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
# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "main" branch
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

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

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v4

# Runs a single command using the runners shell
- name: Run a one-line script
run: echo Hello, world!

# Runs a set of commands using the runners shell
- name: Run a multi-line script
run: |
echo Add other actions to build,
echo test, and deploy your project.

没错,GitHub Actions 的工作流就是根据上方这样的文件来执行的。通过按规则编辑它,就能按自己的想法自定义一些你想让它执行的步骤。

如果点击前者 browse all workflows ,你就可以在下方页面选择要开始的工作流,这些是 GitHub 为应对不同场景下提供的工作流分类模板:

2024-13 (3)

上方预设的工作流模板大致分为以下几类:

  1. Deployment(部署):如将 Node.js 部署到 Azure Web 应用、部署到 Amazon ECS、部署至阿里云ACK、腾讯 Kubernetes 引擎等。
  2. Security(安全):如CodeQL 分析、强化扫描、SonarCloud、SonarQube等。
  3. Continuous integration(持续集成):简称为CI,如构建并测试 Node.js 项目、发布 Node.js 包等。
  4. Automation(自动化):如欢迎首次为存储库做出贡献的用户、根据更改的文件标记 pull requests、检查过时的 issues 和 pull requests、手动触发的简单 workflow 等。
  5. Pages(页面):如部署 HTML 静态文件、打包 Jekyll 站点、部署 Astro 站点、打包 Hugo 站点、打包 NuxtJS 站点、打包 Next.js 站点等。

如果你选择 Continuous integration(持续集成)模板中的 Node.js 工作流,来通过 npm 构建和测试 Node.js 项目,点击对应的 Configure 按钮,即可获得以下工作流文件模板内容:

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
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs

name: Node.js CI

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
node-version: [18.x, 20.x, 22.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm run build --if-present
- run: npm test

你可以在 workflow 编写页面的右侧,点击 Documentation(文档)选项卡,查看编写规则,并对文件进行适当修改。

2024-13 (4)

如果这些模板还是无法满足你的需求,你还能在 workflow 编写页面的右侧点击 Marketplace(市场)选项卡,用关键字搜索别人上传的 GitHub Actions 脚本,直接复用即可。

2024-13 (5)

比如我要操作的是一个用 Vite 打包的前端项目,并且还想要将打包产物部署到 GitHub Pages,通过搜索 vite 可以找到一个叫做 Vite Github Pages Deployer 的 Actions,完美解决我的需求,点击 View full Marketplace listing 可以查看对应用法详情。

2024-13 (6)

2.3 编写并完善 Actions 文件

以下是 Vite Github Pages Deployer 的示例 workflow:

  1. 在此路径创建一个操作文件:./.github/workflows/vite-github-pages-deploy.yml。因此,本质上是.github在项目根目录创建一个文件夹,然后yml在其中创建一个文件。
  2. 复制下面的代码并将其粘贴到您刚刚创建的操作中,然后保存。
  3. 完成。下次推送到master分支时,或者下次从操作选项卡手动运行时,此操作将运行,并且您的项目将部署到 github 页面。
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
name: Vite Github Pages Deploy

on:
# Runs on pushes targeting the default branch
push:
branches: ["master", "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

concurrency:
group: "pages"
cancel-in-progress: false

jobs:
# Build job
build:
runs-on: ubuntu-latest
environment:
name: demo
url: ${{ steps.deploy_to_pages.outputs.github_pages_url }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Vite Github Pages Deployer
uses: skywarth/vite-github-pages-deployer@master
id: deploy_to_pages

以下是其部分可选的输入参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- name: Vite Github Pages Deployer
# You may pin to the exact commit or the version.
# uses: skywarth/vite-github-pages-deployer@894ef807567d82fa238bd3d47009bd360910e11a
uses: skywarth/vite-github-pages-deployer@v1.4.0
with:
# Public base path string for vite, this affects the routing, history and asset links. Make sure to provide appropriately since Github Pages stores your app in a directory under a subdomain.
public_base_path: # optional, default is
# Which folder do you want your Github Page to use as root directory. Usually it is your build output directory such as ./dist
build_path: # optional, default is ./dist
# Node env that will be used for the installation of dependencies. It is imperative you use an environment that has 'vite' as dependency. Commonly, that is 'dev'.
install_phase_node_env: # optional, default is dev
# Node env that will be used for build phase.
build_phase_node_env: # optional, default is production
# Your preference of package manager: 'npm' and 'yarn' are possible values.
package_manager: # optional, default is npm
# Desired name for the Deployment environment. It is also the exposed artifact name which contains the build output (dist).
artifact_name: # optional, default is github-pages
# Controls the debug mode, boolean, true is for on. When turned on, it'll output certain information on certain steps. Mainly used for development, but use it as you please to inspect your env and variables.
debug_mode: # optional, default is false

根据我要操作的 visionOS 仓库情况对示例 workflow 进行适当修改,并添加一些可选参数,即可得到:

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
# This workflow will deploy Vite app to github pages using actions.
# For more information see: https://github.com/marketplace/actions/vite-github-pages-deployer

name: Deploy visionOS site to Github Pages

# Controls when the workflow will run
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

concurrency:
group: "pages"
cancel-in-progress: false

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
# Build job
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
environment:
# Name could be whatever you wish. It'll be visible publicly under the environments tab.
name: demo
url: ${{ steps.deploy_to_pages.outputs.github_pages_url }}
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Vite Github Pages Deployer
uses: skywarth/vite-github-pages-deployer@v1.4.0
id: deploy_to_pages
with:
# Your preference of package manager: 'npm' and 'yarn' are possible values.
package_manager: # optional, default is npm

上面内容就是我要在 .github/workflows/ 目录下要创建的 workflow 文件内容,即 .yml 为后缀的文件。

该文件命名没有要求,可以叫 vite-github-pages-deploy.ymldeploy.ymlvitejs.yml 等等,只要是保证以 .yml 为后缀即可。GitHub 只要发现 .github/workflows 目录下里面有 .yml 文件,就会自动运行[4]

2.4 在 Vite 中设置正确的 base

这是因为项目在部署后(以 visionOS 仓库为例),GitHub Pages 的访问地址会是 https://barry-flynn.github.io/visionOS

也就是说,不是部署到域名根目录下的,所以要在 vite.config.js 中设置正确的 base,使得页面引用静态资源时不会报错[5-6]

根据 Vite 文档所言,你可以设置为绝对路径(例如 /visionOS/),也可以设置为 ./ 相对路径。

2024-13 (7)

03 补充 Vite 官方工作流程样本

文章写了一大半了,才发现 Vite 官方文档中也提供了提供了一个安装依赖项和使用 npm 构建的工作流程样本,请见 部署静态站点:GitHub Pages

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
# 将静态内容部署到 GitHub Pages 的简易工作流程
name: Deploy static content to Pages

on:
# 仅在推送到默认分支时运行。
push:
branches: ['main']

# 这个选项可以使你手动在 Action tab 页面触发工作流
workflow_dispatch:

# 设置 GITHUB_TOKEN 的权限,以允许部署到 GitHub Pages。
permissions:
contents: read
pages: write
id-token: write

# 允许一个并发的部署
concurrency:
group: 'pages'
cancel-in-progress: true

jobs:
# 单次部署的工作描述
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

当然,由于我使用的是 pnpm 管理的依赖,所以需要稍加修改才能用[8-10]

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# 将静态内容部署到 GitHub Pages 的简易工作流程
# https://cn.vitejs.dev/guide/static-deploy#github-pages

name: Deploy static content to Pages

on:
# 仅在推送到默认分支时运行。
push:
branches: ['main']

# 这个选项可以使你手动在 Action tab 页面触发工作流
workflow_dispatch:

# 设置 GITHUB_TOKEN 的权限,以允许部署到 GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# 允许一个并发的部署
concurrency:
group: 'pages'
cancel-in-progress: true

jobs:
# 单次部署的工作描述
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 9

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

- name: Install dependencies
run: pnpm install

- name: Build
run: pnpm 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

04 当 Vue 采用 history 模式的坑

由于部署成功后,项目的访问地址是 https://barry-flynn.github.io/visionOS/,并且此 Vue 项目路由采用的是 history 模式,这就导致了:

  1. 路由重定向失效
  2. 访问任何子路由都显示 404 页面

我暂时没有找到解决方式,只找到了知乎的一个话题讨论:

于是我暂时使用的是 hash 路由模式,如果你有解决方案,欢迎你随时与我分享,感谢!


参考内容 Reference

[1] GitHub Actions 文档

[2] GitHub Actions 是什么? - 知乎

[3] 使用自定义 GitHub Actions 工作流进行发布

[4] Github-Action-Workflow-概念和基本操作 - CSDN

[5] 部署静态站点:GitHub Pages

[6] Vite 配置-共享选项:base

[7] 使用GitHub Actions和GitHub pages实现前端项目的自动打包部署

[8] pnpm中文网-持续集成:GitHub Actions

[9] github action 实现前端项目自动部署(使用pnpm包管理) - CSDN

[10] 使用github部署Vite打包的项目(使用pnpm包管理) - CSDN