如何设置 GitHub 操作来发布 Lerna Monorepo
How To Set Up GitHub Actions to Publish a Lerna Monorepo
我维护着一个 lerna/yarn monorepo。我正在将 CI/CD 从 circle 迁移到新的 Gigitha Actions 发布测试版。我创建了以下工作流程:
name: CD
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Checkout master
run: git checkout master
- name: Install rsync
run: sudo apt install rsync
- name: Install yarn
run: |
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update
sudo apt-get install yarn
- name: Install Packages
run: yarn install
- name: Test
run: yarn test
- name: Upload coverage results to Code Climate
run: sh ./scripts/upload-coverage.sh
env:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
- name: Authenticate with Registry
run: echo "registry=//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Configure CI Git User
run: |
git config --global user.email octobot@github.com
git config --global user.name GitHub Actions
- name: Publish package
run: yarn deploy --yes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build Docs
run: yarn docs
- name: Deploy Docs
run: |
echo "apolloelements.dev" > docs/CNAME
npx gh-pages --dist docs
它在发布包步骤失败并显示以下消息:
lerna info git Pushing tags...
lerna ERR! Error: Command failed: git push --follow-tags --no-verify origin master
lerna ERR! fatal: could not read Username for 'https://github.com': No such device or address
lerna ERR!
lerna ERR! at makeError (/home/runner/work/apollo-elements/apollo-elements/node_modules/execa/index.js:174:9)
lerna ERR! at Promise.all.then.arr (/home/runner/work/apollo-elements/apollo-elements/node_modules/execa/index.js:278:16)
lerna ERR! Error: Command failed: git push --follow-tags --no-verify origin master
lerna ERR! fatal: could not read Username for 'https://github.com': No such device or address
lerna ERR!
lerna ERR! at makeError (/home/runner/work/apollo-elements/apollo-elements/node_modules/execa/index.js:174:9)
lerna ERR! at Promise.all.then.arr (/home/runner/work/apollo-elements/apollo-elements/node_modules/execa/index.js:278:16)
lerna ERR! lerna Command failed: git push --follow-tags --no-verify origin master
lerna ERR! lerna fatal: could not read Username for 'https://github.com': No such device or address
lerna ERR! lerna
error Command failed with exit code 128.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
将远程更改为使用 HTTPS 和 github 令牌没有帮助:
git remote rm origin
git remote add origin "https://$USER_NAME:$GITHUB_PERSONAL_ACCESS_TOKEN@github.com/apollo-elements/apollo-elements.git"
其中 GITHUB_PERSONAL_ACCESS_TOKEN
是通过秘密传递的 PAT。
在那种情况下,我收到了这个错误:
lerna ERR! ENOREMOTEBRANCH Branch 'master' doesn't exist in remote 'origin'.
我应该如何设置项目才能将标签从 CD 推送回存储库?
更新:
这个配置实际上是端到端的。此配置的主要功能是:
- 使用
git remote set-url origin https://$GITHUB_ACTOR:$GITHUB_PAT@github.com/bennypowers/apollo-elements
设置遥控器
GITHUB_ACTOR
由 runner 提供,GITHUB_PAT
是一个 Github Personal Access Token set in the repository's secrets.
- 用
git checkout "${GITHUB_REF:11}" && git pull
重新检查和拉动
- 注销 yarn,因为
lerna
出于某种原因无法处理 yarn。
- 使用下面显示的特定的、挑剔的
.npmrc
设置,因为这是一个范围包。
- 运行
npm whoami
设置授权后。
如果身份验证被破坏,这将抛出
lerna publish
将为您的每个包推送标签,并且可能还会写入 CHANGELOG.md 和 package.json 文件,即使它由于错误的身份验证而没有发布。
运行 npm whoami
在这里检查您实际上可以在 运行 lerna
之前发布,避免手动恢复 repo 状态的麻烦。
- 将
GITHUB_TOKEN
、GH_TOKEN
和 NPM_TOKEN
传递给 lerna publish
name: CD
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v1
- name: Configure CI Git User
run: |
git config --global user.name '@bennypowers'
git config --global user.email 'bennypowers@users.noreply.github.com'
git remote set-url origin https://$GITHUB_ACTOR:$GITHUB_PAT@github.com/bennypowers/apollo-elements
env:
GITHUB_PAT: ${{ secrets.GITHUB_PAT }}
- name: Checkout and pull branch
run: git checkout "${GITHUB_REF:11}" && git pull
- name: Install Packages
run: yarn install
- name: Authenticate with Registry
run: |
yarn logout
echo "@apollo-elements:registry=http://registry.npmjs.org/" > .npmrc
echo "registry=http://registry.npmjs.org/" >> .npmrc
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc
npm whoami
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Publish package
run: lerna publish --yes --message 'chore: release new versions'
env:
GH_TOKEN: ${{ secrets.GITHUB_PAT }}
GITHUB_TOKEN: ${{ secrets.GITHUB_PAT }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
注意上面的配置删除了一些不相关的步骤。参见 the complete workflow 未编辑版本
原始答案:
在 Whosebug 用户@rmunn 的帮助下,我找到了这个解决方案:
- name: Configure CI Git User
run: |
git remote rm origin
git remote add origin "https://$USER_NAME:$GITHUB_PAT@github.com/apollo-elements/apollo-elements.git"
git fetch
git config --global user.email octobot@github.com
git config --global user.name GitHub Actions
env:
USER_NAME: ${{ secrets.DEPLOYING_USER_NAME }}
GITHUB_PAT: ${{ secrets.GITHUB_PAT }}
其中 GITHUB_PAT
是具有 repo
范围的个人访问令牌,保存在秘密中。
需要 git fetch
才能在更改后的遥控器上设置本地分支。需要个人访问令牌才能推送回存储库。
基于@JeroenKnoops 评论,使用checkout@v2
,可以有一个更简单的方法:
name: lerna publish
on:
push:
branches:
- master
jobs:
publish:
runs-on: ubuntu-latest
env:
NPM_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Read node version
run: echo ::set-output name=nodever::$(cat .nvmrc)
id: nvm
- name: Setup node
uses: actions/setup-node@v1
with:
node-version: '${{ steps.nvm.outputs.nodever }}'
registry-url: https://npm.pkg.github.com/
- name: Configure Git User
run: |
git config --global user.email "ci@example.com"
git config --global user.name "@$GITHUB_ACTOR"
- run: npx lerna publish --conventional-commits --yes
请注意,在此示例中,我配置了一个 .npmrc
,它引用 NPM_TOKEN
环境变量进行身份验证:
@myco:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:always-auth=true
//npm.pkg.github.com/:_authToken=${NPM_TOKEN}
现在可以通过 checkout@v2
和 setup-node@v2
使用更简单的配置
jobs:
build:
runs-on: ubuntu-latest
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
steps:
# 1. provide Personal Access Token for checkout@v2
- name: Checkout
uses: actions/checkout@v2
with:
submodules: recursive
token: ${{ secrets.PUBLISH_PAT }}
# 2. setup .npmrc it uses NODE_AUTH_TOKEN
- name: Setup .npmrc file for publish
uses: actions/setup-node@v2
with:
node-version: '12.x'
registry-url: 'https://registry.npmjs.org'
# 3. configure git user used to push tag
- name: Configure Git User
run: |
git config --global user.email "ci@your-site.com"
git config --global user.name "ci@$GITHUB_ACTOR"
- name: Install dependencies
run: yarn install
- name: Publish
run: |
lerna publish --yes
设置 repository secret 如下:
NPM_TOKEN
是具有 publish
权限的 NPM 令牌,more info
PUBLISH_PAT
是具有 repo
权限的 github 个人访问令牌,more info
下面是我从 GitHub Actions 使用 Lerna 发布的最小工作设置。
此解决方案综合了此线程中的答案和 GitHub 上相关问题的一些评论的经验。
要点
- 使用
actions/checkout@v2
拉回购。设置 fetch-depth: "0"
以便它为 Lerna 提取所有历史记录和标签以检测哪些包已更改。
- 使用
actions/setup-node@v2
设置npm
。感谢 ktutnik 的回答
- 运行
npm whoami
如果 npm
配置错误且无法发布,则抛出并退出。这将防止 Lerna 过早地创建和推送标签。感谢 Benny Powers 的回答
- 重要! 如果您正在使用
npm
的自动化令牌,请在使用 Lerna 发布时使用 --no-verify-access
标志。否则,lerna 将失败并返回 403,因为令牌将没有足够的权限来检查通过 Lerna 使用的端点的访问。感谢 dyladan's comment on GitHub
CI
name: Lerna CI
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # set this token manually
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: "0" # pulls all history and tags for Lerna to detect what packages changed.
token: ${{ secrets.GITHUB_TOKEN }} # this token is available by default
# setup .npmrc using NODE_AUTH_TOKEN
- name: Setup .npmrc file for publish
uses: actions/setup-node@v2
with:
node-version: '12.x'
registry-url: 'https://registry.npmjs.org'
- name: Configure Git User
run: |
git config --global user.email "lerna-ci@jitsu.com"
git config --global user.name "lerna-ci@$GITHUB_ACTOR"
- name: Check if able to publish changes
run: npm whoami # will throw and exit if npm is not ready to publish
- name: Install dependencies
run: yarn install
- name: Publish
run: lerna publish --no-verify-access # the flag is needed if NPM_TOKEN is an Automation Token
我维护着一个 lerna/yarn monorepo。我正在将 CI/CD 从 circle 迁移到新的 Gigitha Actions 发布测试版。我创建了以下工作流程:
name: CD
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Checkout master
run: git checkout master
- name: Install rsync
run: sudo apt install rsync
- name: Install yarn
run: |
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update
sudo apt-get install yarn
- name: Install Packages
run: yarn install
- name: Test
run: yarn test
- name: Upload coverage results to Code Climate
run: sh ./scripts/upload-coverage.sh
env:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
- name: Authenticate with Registry
run: echo "registry=//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Configure CI Git User
run: |
git config --global user.email octobot@github.com
git config --global user.name GitHub Actions
- name: Publish package
run: yarn deploy --yes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build Docs
run: yarn docs
- name: Deploy Docs
run: |
echo "apolloelements.dev" > docs/CNAME
npx gh-pages --dist docs
它在发布包步骤失败并显示以下消息:
lerna info git Pushing tags...
lerna ERR! Error: Command failed: git push --follow-tags --no-verify origin master
lerna ERR! fatal: could not read Username for 'https://github.com': No such device or address
lerna ERR!
lerna ERR! at makeError (/home/runner/work/apollo-elements/apollo-elements/node_modules/execa/index.js:174:9)
lerna ERR! at Promise.all.then.arr (/home/runner/work/apollo-elements/apollo-elements/node_modules/execa/index.js:278:16)
lerna ERR! Error: Command failed: git push --follow-tags --no-verify origin master
lerna ERR! fatal: could not read Username for 'https://github.com': No such device or address
lerna ERR!
lerna ERR! at makeError (/home/runner/work/apollo-elements/apollo-elements/node_modules/execa/index.js:174:9)
lerna ERR! at Promise.all.then.arr (/home/runner/work/apollo-elements/apollo-elements/node_modules/execa/index.js:278:16)
lerna ERR! lerna Command failed: git push --follow-tags --no-verify origin master
lerna ERR! lerna fatal: could not read Username for 'https://github.com': No such device or address
lerna ERR! lerna
error Command failed with exit code 128.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
将远程更改为使用 HTTPS 和 github 令牌没有帮助:
git remote rm origin
git remote add origin "https://$USER_NAME:$GITHUB_PERSONAL_ACCESS_TOKEN@github.com/apollo-elements/apollo-elements.git"
其中 GITHUB_PERSONAL_ACCESS_TOKEN
是通过秘密传递的 PAT。
在那种情况下,我收到了这个错误:
lerna ERR! ENOREMOTEBRANCH Branch 'master' doesn't exist in remote 'origin'.
我应该如何设置项目才能将标签从 CD 推送回存储库?
更新:
这个配置实际上是端到端的。此配置的主要功能是:
- 使用
git remote set-url origin https://$GITHUB_ACTOR:$GITHUB_PAT@github.com/bennypowers/apollo-elements
设置遥控器GITHUB_ACTOR
由 runner 提供,GITHUB_PAT
是一个 Github Personal Access Token set in the repository's secrets. - 用
git checkout "${GITHUB_REF:11}" && git pull
重新检查和拉动
- 注销 yarn,因为
lerna
出于某种原因无法处理 yarn。 - 使用下面显示的特定的、挑剔的
.npmrc
设置,因为这是一个范围包。 - 运行
npm whoami
设置授权后。 如果身份验证被破坏,这将抛出lerna publish
将为您的每个包推送标签,并且可能还会写入 CHANGELOG.md 和 package.json 文件,即使它由于错误的身份验证而没有发布。 运行npm whoami
在这里检查您实际上可以在 运行lerna
之前发布,避免手动恢复 repo 状态的麻烦。 - 将
GITHUB_TOKEN
、GH_TOKEN
和NPM_TOKEN
传递给lerna publish
name: CD
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v1
- name: Configure CI Git User
run: |
git config --global user.name '@bennypowers'
git config --global user.email 'bennypowers@users.noreply.github.com'
git remote set-url origin https://$GITHUB_ACTOR:$GITHUB_PAT@github.com/bennypowers/apollo-elements
env:
GITHUB_PAT: ${{ secrets.GITHUB_PAT }}
- name: Checkout and pull branch
run: git checkout "${GITHUB_REF:11}" && git pull
- name: Install Packages
run: yarn install
- name: Authenticate with Registry
run: |
yarn logout
echo "@apollo-elements:registry=http://registry.npmjs.org/" > .npmrc
echo "registry=http://registry.npmjs.org/" >> .npmrc
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc
npm whoami
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Publish package
run: lerna publish --yes --message 'chore: release new versions'
env:
GH_TOKEN: ${{ secrets.GITHUB_PAT }}
GITHUB_TOKEN: ${{ secrets.GITHUB_PAT }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
注意上面的配置删除了一些不相关的步骤。参见 the complete workflow 未编辑版本
原始答案:
在 Whosebug 用户@rmunn 的帮助下,我找到了这个解决方案:
- name: Configure CI Git User
run: |
git remote rm origin
git remote add origin "https://$USER_NAME:$GITHUB_PAT@github.com/apollo-elements/apollo-elements.git"
git fetch
git config --global user.email octobot@github.com
git config --global user.name GitHub Actions
env:
USER_NAME: ${{ secrets.DEPLOYING_USER_NAME }}
GITHUB_PAT: ${{ secrets.GITHUB_PAT }}
其中 GITHUB_PAT
是具有 repo
范围的个人访问令牌,保存在秘密中。
需要 git fetch
才能在更改后的遥控器上设置本地分支。需要个人访问令牌才能推送回存储库。
基于@JeroenKnoops 评论,使用checkout@v2
,可以有一个更简单的方法:
name: lerna publish
on:
push:
branches:
- master
jobs:
publish:
runs-on: ubuntu-latest
env:
NPM_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Read node version
run: echo ::set-output name=nodever::$(cat .nvmrc)
id: nvm
- name: Setup node
uses: actions/setup-node@v1
with:
node-version: '${{ steps.nvm.outputs.nodever }}'
registry-url: https://npm.pkg.github.com/
- name: Configure Git User
run: |
git config --global user.email "ci@example.com"
git config --global user.name "@$GITHUB_ACTOR"
- run: npx lerna publish --conventional-commits --yes
请注意,在此示例中,我配置了一个 .npmrc
,它引用 NPM_TOKEN
环境变量进行身份验证:
@myco:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:always-auth=true
//npm.pkg.github.com/:_authToken=${NPM_TOKEN}
现在可以通过 checkout@v2
和 setup-node@v2
jobs:
build:
runs-on: ubuntu-latest
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
steps:
# 1. provide Personal Access Token for checkout@v2
- name: Checkout
uses: actions/checkout@v2
with:
submodules: recursive
token: ${{ secrets.PUBLISH_PAT }}
# 2. setup .npmrc it uses NODE_AUTH_TOKEN
- name: Setup .npmrc file for publish
uses: actions/setup-node@v2
with:
node-version: '12.x'
registry-url: 'https://registry.npmjs.org'
# 3. configure git user used to push tag
- name: Configure Git User
run: |
git config --global user.email "ci@your-site.com"
git config --global user.name "ci@$GITHUB_ACTOR"
- name: Install dependencies
run: yarn install
- name: Publish
run: |
lerna publish --yes
设置 repository secret 如下:
NPM_TOKEN
是具有 publish
权限的 NPM 令牌,more info
PUBLISH_PAT
是具有 repo
权限的 github 个人访问令牌,more info
下面是我从 GitHub Actions 使用 Lerna 发布的最小工作设置。
此解决方案综合了此线程中的答案和 GitHub 上相关问题的一些评论的经验。
要点
- 使用
actions/checkout@v2
拉回购。设置fetch-depth: "0"
以便它为 Lerna 提取所有历史记录和标签以检测哪些包已更改。 - 使用
actions/setup-node@v2
设置npm
。感谢 ktutnik 的回答 - 运行
npm whoami
如果npm
配置错误且无法发布,则抛出并退出。这将防止 Lerna 过早地创建和推送标签。感谢 Benny Powers 的回答 - 重要! 如果您正在使用
npm
的自动化令牌,请在使用 Lerna 发布时使用--no-verify-access
标志。否则,lerna 将失败并返回 403,因为令牌将没有足够的权限来检查通过 Lerna 使用的端点的访问。感谢 dyladan's comment on GitHub
CI
name: Lerna CI
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # set this token manually
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: "0" # pulls all history and tags for Lerna to detect what packages changed.
token: ${{ secrets.GITHUB_TOKEN }} # this token is available by default
# setup .npmrc using NODE_AUTH_TOKEN
- name: Setup .npmrc file for publish
uses: actions/setup-node@v2
with:
node-version: '12.x'
registry-url: 'https://registry.npmjs.org'
- name: Configure Git User
run: |
git config --global user.email "lerna-ci@jitsu.com"
git config --global user.name "lerna-ci@$GITHUB_ACTOR"
- name: Check if able to publish changes
run: npm whoami # will throw and exit if npm is not ready to publish
- name: Install dependencies
run: yarn install
- name: Publish
run: lerna publish --no-verify-access # the flag is needed if NPM_TOKEN is an Automation Token