说明
需求
- main 分支发布主要版本
- LTS 分支发布修订版本
- 成员日常通过 PR 提交对代码库的变更
搭建 Publish workFlow
1. 明确项目的参与者权限
- Admin: 最高权限,可以对项目进行设置,且提交代码到 main 分支,不需要提 pr
- Member: 成员权限(读写),除了不能用 setting 其他都可以,提交代码到 main 分支,需要提 pr
- 外部协作者:最低参与权限
2. Github 的受保护分支
受保护分支主要用来规范对某个分支的提交操作规范,例如:main 分支不能直接提交代码,要通过提交 pr 审核通过后才能合并, 审核时还要通过 GitHub Action 的测试
3. publish action 中实际做了什么
- yarn install 下载依赖或者使用缓存的依赖
- yarn lerna test:all --stream 执行全量的 test
- yarn lerna:build 执行所有子 package 的 build 脚本,生成 dist 文件用于发布
- build 同时会触发 eslint 校验
- 生成 d.ts 文件的同时会进行 tsc 的校验
- yarn lerna:publish 发布private 不为 true 的 子 package
- publish 前需要先设置 git Identity (身份设置)否则无法进行 push 操作
- 根据 commit-msg 生成距离上一个版本的 changelog 并写入文件
- 会发布 包 到指定 npm 仓库,因此需要
--legacy-auth ${{ secrets.NPM_SECRET }}
来做 npm 的身份认证(NPM_SECRET 是 Base64 后的 username:password , 不是 npm token) - 如果 lerna 使用的是集中版本号(fixed)则会产生一个 version Tag ,如果使用的是独立版本号,则每一个子 package 都会生成一个 version Tag
- 通过
--create-release github
给项目自动生成 release ,release 内容与 changelog 类似 (同样会根据 lerna 是否使用独立版本号,生成的 release 也会有不同) - push 版本变更后的代码到 main 主分支上
publish:
needs: [setup, test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
persist-credentials: false
fetch-depth: "0"
- name: restore node_modules
uses: actions/cache@v2
with:
path: '**/node_modules'
key: modules-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
modules-${{ hashFiles('**/yarn.lock') }}
modules-
- name: Git Identity
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/$GITHUB_REPOSITORY
env:
GITHUB_TOKEN: ${{ secrets.GH_PUSH_TOKERN }}
- name: build
run: yarn lerna:build
- name: publish
run: yarn lerna:publish --yes --legacy-auth ${{ secrets.NPM_SECRET }} --message "chore(release):publish %v" --create-release github ${{ github.event.inputs.parameter_for_publish }} ${{ github.event.inputs.version }}
env:
GITHUB_TOKEN: ${{ secrets.GH_PUSH_TOKERN }}
GH_TOKEN: ${{ secrets.GH_PUSH_TOKERN }}
NODE_AUTH_TOKEN: ${{ secrets.GH_PUSH_TOKERN }}
4. 在 Github Action 中触发 git push 应该怎么实现
1. GITHUB_TOKEN 问题
Github Action 中默认无法触发 git push 即使是 Admin 权限的管理员,这是因为lerna publish 中 git push 需要用到
GITHUB_TOKEN
这个 环境变量
这个环境变量是 Github Action 默认提供的 GITHUB_TOKEN 权限,但是仅提供部分权限,想要获得 push 的权限,需要具有 Admin 权限的管理员按照如下操作生成一个新的 GH_PUSH_TOKERN
- 用 Admin 权限账户创建个人访问令牌 按照说明选择 tokern 的权限,选中后生成 token , 将token 复制下来备用
- 进入项目中 Settings => Secrets => New repository secret 创建一个 secret ,随便起一个名字,然后将刚才复制的 token 作为值填入
- 保存后生成一个 secret (假如命名为 GH_PUSH_TOKERN) ,我们在 Github Action 脚本中将 GITHUB_TOKEN 环境变量设置为这个secret 即可
- name: publish
run: yarn lerna:publish --yes --legacy-auth ${{ secrets.NPM_SECRET }} --message "chore(release):publish %v" --create-release github ${{ github.event.inputs.parameter_for_publish }} ${{ github.event.inputs.version }}
env:
GITHUB_TOKEN: ${{ secrets.GH_PUSH_TOKERN }}
GH_TOKEN: ${{ secrets.GH_PUSH_TOKERN }}
NODE_AUTH_TOKEN: ${{ secrets.GH_PUSH_TOKERN }}
2. actions/checkout@v2 的问题
actions/checkout@v2 是 Github Action 的一个常用的插件,用来帮助我们拉取代码,但是使用 actions/checkout@v2 拉取代码后他的 auth token 会留在本地的 git 配置中,这种设置可以帮助我们在后续脚本中使用 git 需要通过身份认证的命令,但是 push 因为是需要权限的,使用 actions/checkout@v2 留下来的 auth token 是不行的,查看 因此我们需要做如下配置:
steps:
- uses: actions/checkout@v2
with:
persist-credentials: false
fetch-depth: "0"
- name: Git Identity
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/$GITHUB_REPOSITORY
env:
GITHUB_TOKEN: ${{ secrets.GH_PUSH_TOKERN }}
- name: publish
run: yarn lerna:publish --yes --legacy-auth ${{ secrets.NPM_SECRET }}
env:
GITHUB_TOKEN: ${{ secrets.GH_PUSH_TOKERN }}
3. Admin 角色的问题
以上使得 git push 在 Github Action 中可执行,主要都是在 在 Admin 管理员提供 token 的前提下实现,但是要保证 Admin 管理员提交代码到 main 分支是不需要提 pr 的,否则依然会没有权限,我们给 main 分支做如下的分支策略:
编辑 main 分支的分支策略
取消对 Admin 权限的分支保护策略