Github Actions 部署项目
前言
GitHub Actions 是一个持续集成和持续交付(CI/CD)平台,可以执行自动化构建和部署。通过创建工作流,方便的将项目部署到生产中。
本教程将从纯静态文件部署、项目打包文件部署、sh 脚本项目部署、全自动项目部署几个方面实现 Github Actions 自动部署项目。
重要提示
本教程中的示例项目代码拉取下来后,请将项目推送到自己的 GitHub 仓库中,以便后续操作步骤能够成功运行。如果是已有项目,请酌情执行部署步骤!
1.纯静态文件部署
引子
纯静态文件部署常用在纯 html 页面且无需编译打包的项目中,入口 index.html
文件在项目根目录,克隆Github 示例项目。
- 项目结构
|- test-static-pages
- index.css
- index.html
- index.js
项目代码
index.html
html<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>测试静态文件部署</title> <link rel="stylesheet" href="index.css" /> </head> <body> 测试静态文件部署 <script src="index.js"></script> </body> </html>
index.js
jsconsole.log("测试静态文件部署");
index.css
css* { color: red; }
配置 Actions:
注意
- 只要在
master
分支上推送代码,都会自动部署项目。因此可以另起一个develop
分支去写开发内容,有需要部署时,将develop
分支合并到master
分支,合并成功后依然会自动部署master
分支。 - 可以在项目的
Actions
页面查看部署日志,观察部署过程。
2.项目打包文件部署
引子
上小节实现了纯静态页面的自动部署,但对于需要编译打包的项目来说,打包好的文件会在 dist
目录下,很明显上小节 Select folder
时没有 /dist
选项【PS:当然把项目打包目录设定为 /docs 去部署也可以】,这就需要用到 Actions
里的 yml
配置。
项目打包文件部署,常用在 dist
文件在本地打包好,提交到 GitHub 上,然后部署的场景中,克隆Github 示例项目,本节所用示例为 vite+vue3 项目,其他框架逻辑一致。
克隆项目【在已有项目中直接跳到第 3 步】:
shgit clone https://github.com/Ele-Cat/test-dist-pages.git
安装依赖&打包
shnpm install
shnpm run build
推送项目到自己的 GitHub 仓库中,注意此时会将
dist
目录也提交上去【.gitignore
文件不忽略dist
目录】配置 Actions:
打开项目:Settings -> Pages;
Source 选择
GitHub Actions
;workflow 选择
Static HTML
→Configure
,会跳转到*/.github/workflows/static.yml
编辑页;修改
static.yml
:yml# Simple workflow for deploying static content to GitHub Pages # 这行代码设置了工作流程的名称为 "Deploy static content to Pages"。 name: Deploy static content to Pages # 这部分定义了触发工作流程执行的事件。它指定当代码推送到名为 "master" 的分支时触发工作流程执行,并且还可以通过 GitHub Actions 界面手动触发工作流程。 on: push: branches: ["master"] workflow_dispatch: # 这部分设置了 GITHUB_TOKEN 的权限,以允许对 GitHub Pages 进行部署。它指定 GITHUB_TOKEN 具有读取仓库内容、写入页面和写入身份令牌的权限。 permissions: contents: read pages: write id-token: write # 这部分定义了并发性设置。它指定一个名为 "pages" 的组,用于限制只能有一个并发的页面部署任务运行,同时取消排队中的运行。但不会取消正在进行中的运行,以确保生产部署完成。 concurrency: group: "pages" cancel-in-progress: false # 这部分定义了一个名为 "deploy" 的任务(job)。该任务在 Ubuntu 最新版本上运行。它包含一系列步骤以执行静态内容的部署过程,具体步骤包括: # Checkout 步骤使用 actions/checkout 动作来获取代码库。 # Setup Pages 步骤使用 actions/configure-pages 动作进行页面配置。 # Upload artifact 步骤使用 actions/upload-pages-artifact 动作将 "./dist" 目录下的文件上传到 GitHub Pages 所需的存储库。 # Deploy to GitHub Pages 步骤使用 actions/deploy-pages 动作执行实际的 GitHub Pages 部署操作,并将操作结果保存在 deployment 变量中,可以通过 ${{steps.deployment.outputs.page_url }} 访问部署后的页面 URL。 jobs: deploy: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Pages uses: actions/configure-pages@v5 - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: # Upload entire repository path: "." path: "./dist" - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4
点击右上角的
Commit changes
后,再点击弹窗的Commit changes
,项目会自动部署到 GitHub Pages 上,访问示例项目;操作步骤如下图:
注意
- 与上小节一样,在推送
master
分支推送任意代码,后续无需任何配置,都会自动触发部署dist
。 - 本节案例场景多用在项目所需依赖为私有部署,在 GitHub 中无法自动
install&build
;如果项目所需依赖可在 GitHub 上完成,更推荐用全自动项目部署的操作。
3.sh 脚本项目部署
引子
上小节中实现的项目部署较为繁琐:
- 开发完成后本地 build;
- build 后提交文件到 GitHub;
- 等待 GitHub Actions 部署。
本节通过
sh
脚本,来实现:
- 项目自动打包并推送
dist
到对应分支;- 自动部署。
虽然只缩减了一小步,但也是大进步 🎉!克隆Github 示例项目,本节所用示例为 vite+vue3 项目,其他框架逻辑一致。
克隆项目【在已有项目中直接跳到第 4 步】:
shgit clone https://github.com/Ele-Cat/test-sh-pages.git
安装依赖
shnpm install
推送项目到自己的 GitHub 仓库中
修改项目根目录
deploy.sh
文件的第21
行代码:sh#!/usr/bin/env sh set -x # 这里是为了看错误日志 # 打包项目 npm run build # 进入打包后的文件夹 cd dist # 初始化一个 Git 仓库,如果在 dist 目录中还没有 Git 仓库的话。 git init # 添加所有更改过的文件到暂存区。 git add -A # 提交暂存区的所有更改,并附上一个提交信息。 git commit -m '🚀自动部署' # 将当前分支强制推送到 GitHub 上的指定分支。 # -f 选项表示强制推送,它会覆盖远程分支上的任何更改。 # 这里的 master:sh-pages 表示将本地的 master 分支推送到远程的 sh-pages 分支。 git push -f https://github.com/Ele-Cat/test-sh-pages.git master:sh-pages
请将
https://github.com/Ele-Cat/test-sh-pages.git
仓库地址修改为自己的仓库地址,master:sh-pages
分支信息修改为自己仓库对应的目标分支。在项目根目录运行命令:
shsh deploy.sh
在 Windows 电脑 的 VSCode 命令行工具中运行
sh deploy.sh
,可能会报sh : 无法将“sh”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。解决办法:在Git Bash
中运行脚本命令。等待脚本运行完成,可以在项目仓库中看到新的
sh-pages
分支。配置 Actions:
- 打开项目:Settings -> Pages;
- Source 默认选择
Deploy from a branch
; - Branch 分支选择
sh-pages
分支【注意这里的sh-pages
分支为第四步推送的分支名称】; - Select folder 默认选择
/(root)
; - 点击 Save 后,项目会自动部署到 GitHub Pages 上,访问示例项目;
- 操作步骤图参考第一小节。
注意
- 本小节部署方式最为灵活,在非
sh-pages
分支提交代码时,不会触发执行项目部署;在需要项目部署时,运行sh deploy.sh
脚本,即可实现自动部署。 - 但是通过 sh 脚本打包、推送、部署,还是需要开发者手动运行命令触发,并非全自动。下小节将介绍如何实现代码提交即触发全自动部署。
4.全自动项目部署
引子
回归“前言”,GitHub Actions 是一个持续集成和持续交付(CI/CD)平台,可以执行自动化构建和部署。我们完全可以通过 Actions 实现代码提交即触发全自动部署,即安装、打包、部署都在 Actions 中完成。
一些基础概念
CICD(持续构建、持续交付)
① CI 持续集成(Continuous Integration)
持续集成:频繁的将代码合并到主分支中,强调通过集成测试反馈给开发一个结果,不管失败还是成功。
持续集成分成三个阶段:
- 持续集成准备阶段:根据软件开发的需要,准备 CI 的一些前置工作
- 集成 CI 工具的代码仓库(Gitlab、Github、Jenkins 等)
- 单元测试或者集成测试的脚本
- 触发 CI 的配置文件,实现各种功能的 Jobs
- 持续集成进行阶段
- 推送代码出发 CI 系统
- 通过 CI 系统监听代码的测试、构建,反馈集成结果
- 通过版本管理系统实现版本的管理
- 接续集成完成阶段:反馈集成结果
② CD 持续交付(Continuous Delivery)
持续交付:主要面向测试人员和产品,可以保证一键部署,常常要交付的内容包括
- 源代码:缺点,代码依赖的环境不容易控制
- 打包的二进制文件或者系统包:存在兼容性问题和环境差异出现的部署失败
- 虚拟机镜像交付:系统隔离最好,但占用系统资源严重
- Docker 交付:容器交付,成本最低,兼容性最好
持续部署:此时要提供一个稳定的版本,包括所需的环境和依赖,主要面向用户提供服务,发生错误要能快速回滚。
CICD 是目前大多数互联网公司选择的一种部署方案,因为它能够灵活配置项目部署过程中的各个阶段。
- 持续集成准备阶段:根据软件开发的需要,准备 CI 的一些前置工作
Workflows(工作流)
工作流是一个可配置的自动化的程序。创建一个工作流,你需要定义一个 YAML 文件,当你的仓库触发某个事件的时候,工作流就会运行,当然也可以手动触发,或者定义一个时间表。一个仓库可以创建多个工作流,每一个工作流都可以执行不同的步骤。
Events(事件)
事件是指仓库触发运行工作流的具体的行为,比如创建一个
pull request
、新建一个issue
、或者推送一个commit
。你也可以使用时间表触发一个工作流,或者通过请求一个 REST API,再或者手动触发。Jobs(任务)
任务是在同一个运行器上执行的一组步骤。一个步骤要么是一个 shell 脚本要么是一个动作。步骤会顺序执行,并彼此独立。因为每一个步骤都在同一个运行器上被执行,所以你可以从一个步骤传递数据到另一个步骤 。
你可以配置一个任务依赖其他任务,默认情况下,任务没有依赖,并行执行。当一个任务需要另外一个任务的时候,它会等到依赖的任务完成再执行。
Actions(动作)
动作是 GitHub Actions 平台的一个自定义的应用,它会执行一个复杂但是需要频繁重复的作业。使用动作可以减少重复代码。比如一个 action 可以实现从 GitHub 拉取你的 git 仓库,为你的构建环境创建合适的工具链等。你可以写自己的动作 ,或者在 GitHub 市场找已经实现好的动作。
Runners(运行器)
一个运行器是一个可以运行工作流的服务。每一个运行器一次只运行一个单独的任务。GitHub 提供 Ubuntu Linux,Microsoft Windows 和 macOS 运行器,每一个工作流都运行在一个独立新建的虚拟机中。如果你需要一个不同的操作系统,你可以自定义运行器。
克隆项目【在已有项目中直接跳到第 2 步】:
shgit clone https://github.com/Ele-Cat/test-auto-pages.git
推送项目到自己的 GitHub 仓库中
如果用的是克隆项目,直接推送即可
如果是自己的全新项目,在项目根目录新增
.github/workflows/auto-deploy.yml
文件:yml# .github/workflows/auto-deploy.yml name: auto deploy 🚀 on: # 监听push操作 push: branches: - master # 这里只配置了master分支,所以只有推送master分支才会触发以下任务 pull_request: # 这个选项可以使你手动在 Action tab 页面触发工作流 workflow_dispatch: permissions: # 允许对仓库的内容进行写操作。包括创建、修改和删除文件、目录以及提交更改等 # 这里只配置了push,所以只有推送master分支才会触发以下任务 contents: write # 允许管理 GitHub Pages 服务并对其进行写操作 pages: write jobs: # 任务ID build-and-deploy: # 运行环境 runs-on: ubuntu-latest concurrency: group: ${{ github.workflow }}-${{ github.ref }} # 步骤 steps: # 官方action,将代码拉取到虚拟机 - name: Checkout uses: actions/checkout@v3 # 安装依赖 - name: Install dependencies run: npm install # 打包 - name: Build application 🔧 run: npm run build # 部署 - name: Deploy 🚀 uses: JamesIves/github-pages-deploy-action@v4 if: github.ref == 'refs/heads/master' with: token: ${{ secrets.PAT }} branch: gh-pages # default: gh-pages folder: dist clean: true # Automatically remove deleted files from the deploy branch
提示
首次推送代码后,会执行一次自动部署且报错,不用担心,这是因为 GitHub Actions 会监听
.github/workflows
目录的.yml
文件,我们在配置了令牌后,就可以成功执行 Actions 了。
创建令牌
- 打开 GitHub:右上角头像 -> Settings【不是仓库的 Settings 哦!】;
- 左侧最下边的 Developer settings 进入;
- 展开 Personal access tokens -> Fine-grained tokens【推荐使用这个,而不是 Tokens(classic),查看原因】;
- 点击右上角的 Generate new token 按钮,进入配置界面;
- 填写 Token name 为
generate for test auto pages
,这个令牌名称不可以跟其他令牌的名称重复; - 选择 Expiration,最多可以选择一年;
- Repository access 选择
Only select repositories
,然后选择需要自动部署的项目仓库; - 将 Permissions 中 Repository permissions 的全部选择都选择
Read and write
,没有该选项的就选择Read-only
; - 点击 Generate token 按钮,会显示一个令牌,复制这个令牌保存好,后续需要用到【如果忘记了令牌,可以在令牌详情重新生成一个,不过用到该令牌的全部项目都需要同步更新】。
将令牌应用在仓库中
- 回到仓库中:Settings -> Security;
- 展开 Secrets and variables,打开 Actions;
- 在 Repository secrets 处绑定令牌,点击
New repository secret
按钮; - 在
Name
填写PAT
【这个变量名在第 2 步的auto-deploy.yml
文件中可自定义】; - 在
Secret
填写 上步创建的令牌; - 点击
Add secret
按钮保存。
运行 Actions:
- 随便推送代码到
master
分支 或 手动运行一次 Actions,为的是让 Actions 再跑一次部署流程; - 打开项目:顶部 Actions【可以看到有一条报错的部署信息,这就是上边说的,我们第 2 步时还没有配置令牌,所以报错了】;
- 点击这条报错 workflow run,进入后点击右上角的
Re-run jobs
->Re-run all jobs
; - 这时候可以点击进入查看部署过程,等待 Complete job 后,我们可以看到仓库新增了一个
gh-pages
分支,且里边的内容就是我们打包后生成的dist
文件夹内容; - 这时候打开项目:Settings -> Pages,就会发现 Build and deployment 已经自动将
gh-pages
分支部署好了,访问示例项目;提示
以后每次推送
master
分支代码后,Actions 都会自动执行安装、打包、部署任务,将最新代码部署到gh-pages
分支;
- 随便推送代码到
总结
- 使用 GitHub Actions 来部署项目,其实就是将打包好的代码【不管是本地打包还是通过 jobs 打包】,部署到仓库的对应分支,并启用 GitHub Pages;
- 教程里的 1、2、4 都是只要提交代码,就会执行部署;3 为运行 sh 脚本才部署;可以根据自己的实际需求选择部署方式;
- 大多数情况下,master 分支是受保护的,我们可以推送代码到开发分支,仅在部署时,合并代码到 master 分支,合并时自动部署;