最近对 CI/CD 有点兴趣,也希望用 CI/CD 来简化我的一些工作,刚好 github 提供了 github actions
供用户使用,因此开展了下列的实践
需求
我有个项目是 github-pages-project
,使用的框架是 vue3,每次我修改了代码,都会手动执行 yarn build 的操作,然后复制生成的 dist 文件夹里面的内容,覆盖我另一个项目 <username>.github.io
里面的内容,再提交到远程,以此完成 github pages 内容的更新
希望的是,当 push 代码后,自动将 build 后的 dist 文件夹里面的内容自动推送到 <username>.github.io
实现
在项目根目录下,创建 .github/workflows
文件夹(如果还不存在),并在其中创建一个新的 YAML 文件(例如 deploy.yml
)
先实现简单的,在 GitHub Actions 中,on
是用于定义工作流触发条件的关键字。通过 on
,你可以指定在什么事件发生时触发工作流。例如,代码推送、拉取请求、新标签创建等。我们通过 on
设置 push
时触发
actions/checkout@v2
是 GitHub Actions 中一个常用的操作(action)。它的主要作用是将仓库的代码签出到 GitHub Actions 运行器(Runner)上,以便后续的构建、测试和部署步骤能够访问和操作这些代码
actions/setup-node@v2
是 GitHub Actions 中一个常用的操作(action),用于在运行器(Runner)上设置 Node.js 环境。这个操作帮助你在工作流中指定需要的 Node.js 版本,并配置相应的环境,以便后续的步骤能够运行 Node.js 应用程序或脚本
上述两步在前端项目中基本上是必要的
然后很容易看懂了,yarn install
和 yarn build
分别是安装和构建命令
name: Build and Deploy
on:
push:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '20.11.1'
- name: Install dependencies
run: yarn install
- name: Build project
run: yarn build
比较麻烦的是将 dist 文件夹下的代码上传到另一个仓库,第一个问题是权限,我们可以使用 Personal Access Token(简称 PAT),创建步骤是 GitHub > Settings > Developer settings > Personal access tokens,生成一个新的 token,选择 repo 权限,这个 token 就是 PAT,然后使用这个 token ,我们就可以做提交的步骤了
PAT 为了安全,通常并不能明文显示,当然,如果你的项目是 private 的,可以明文,但明文终究不是好的实践;将敏感信息存储在 GitHub Secrets 中是一个最佳实践,进入你的 GitHub 仓库 > Settings。在左侧栏中点击 Secrets and variables
,然后选择 Actions
。点击 New repository secret
,名称为 PERSONAL_TOKEN,并粘贴刚生成的 token,在 yml 中可通过 ${{ secrets.PERSONAL_TOKEN }} 安全地引用该 token
另一个问题是默认的分支,有些可能是 master,有些可能是 main,因此在初始化时指定分支名称为 main
github-actions[bot]
是一个特殊的用户账号,由 GitHub 专门为 GitHub Actions 创建和管理。它的主要作用是代表 GitHub Actions 在你的仓库中执行自动化任务。这个用户账号自动生成,并且在运行工作流时具有特定的权限和标识
由于是 github pages 项目,因此我可以直接 --force
,如果你是其他类型的项目,这方面切记要谨慎设置
- name: Push to another repository
env:
PERSONAL_TOKEN: ${{ secrets.PERSONAL_TOKEN }}
USER_NAME: your-username
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
cd dist
git init -b main
git add .
git commit -m 'Deploy from GitHub Actions'
git push --force "https://${{ env.USER_NAME }}:${{ env.PERSONAL_TOKEN }}@github.com/${{ env.USER_NAME }}/${{ env.USER_NAME }}.github.io.git" main
验证
在 github-pages-project
的网址上看到上方有个 Actions 的 tab,可以看到每次提交是否执行成功,如果执行失败,也能看到报错。在 <username>.github.io
上可以看到确实提交成功了。打开 https://<username>.github.io
,看到代码已成功更改,说明实践成功
android 出 build
如果是 android 或 iOS 项目,github 也提供了 github release 以供实践,在 Code tab 下,你可以看到右边有个 release 的入口,你可以手动上传生成的 apk,同样也可以配置 github actions 来实现自动出 build
下面是一个 flutter 项目的配置文件 release.yml
,flutter 生成的 apk 路径与其他 android 项目不同,可根据需要配置路径,同样用到了 PERSONAL_TOKEN ,这个 env 变量可以用前面生成的,但需要每个项目都设置一次
name: Build and Release
on:
push:
branches:
- main
jobs:
build-and-release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: "3.24.0" # 根据需要设置 Flutter 版本
- name: Install dependencies
run: flutter pub get
- name: Build APK
run: flutter build apk --release
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.PERSONAL_TOKEN }}
VERSION_NAME: "v1.0.0" # 根据项目情况配置
with:
tag_name: ${{ env.VERSION_NAME }}
release_name: "Release ${{ env.VERSION_NAME }}"
body: "自动创建的 Release"
draft: false
prerelease: false
- name: Upload APK to Release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.PERSONAL_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: build/app/outputs/flutter-apk/app-release.apk
asset_name: app-release.apk
asset_content_type: application/vnd.android.package-archive