'How To Set Up GitHub Actions to Publish a Lerna Monorepo
I maintain a lerna/yarn monorepo. I'm in the process of migrating the CI/CD from circle to the new GitHuba Actions publish beta. I've created the following workflow:
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 [email protected]
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
It fails at the Publish Packages step with this message:
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.
Changing the remote to use HTTPS and the github token hasn't helped:
git remote rm origin
git remote add origin "https://$USER_NAME:[email protected]/apollo-elements/apollo-elements.git"
Where GITHUB_PERSONAL_ACCESS_TOKEN is a PAT passed via secrets.
In that case, I received this error:
lerna ERR! ENOREMOTEBRANCH Branch 'master' doesn't exist in remote 'origin'.
How should I set up the project to be able to push tags and commits back to the repository from CD?
Solution 1:[1]
Its now possible to use simpler configuration by using checkout@v2 and 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 "[email protected]"
git config --global user.name "ci@$GITHUB_ACTOR"
- name: Install dependencies
run: yarn install
- name: Publish
run: |
lerna publish --yes
Setup repository secret with below:
NPM_TOKEN is NPM token with publish permission, more info
PUBLISH_PAT is github personal access token with repo permission, more info
Solution 2:[2]
Building on @JeroenKnoops comment, using checkout@v2, a simpler approach can be had:
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 "[email protected]"
git config --global user.name "@$GITHUB_ACTOR"
- run: npx lerna publish --conventional-commits --yes
Note that in this example I have a .npmrc configured which references the NPM_TOKEN environment variable to authenticate:
@myco:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:always-auth=true
//npm.pkg.github.com/:_authToken=${NPM_TOKEN}
Solution 3:[3]
Below is my smallest working setup for publishing with Lerna from GitHub Actions.
This solution is consolidated experience from the answers in this thread and some comments to related issues on GitHub.
Key Points
- Using
actions/checkout@v2to pull the repo. Setfetch-depth: "0"so that it pulls all history and tags for Lerna to detect what packages have changed. - Using
actions/setup-node@v2to set upnpm. Credit to ktutnik's answer - Running
npm whoamito throw and exit ifnpmis misconfigured and can not publish. This will prevent Lerna from creating and pushing tags prematurely. Credit to Benny Powers's answer - Important! If you are using
npm's Automation Token, use--no-verify-accessflag when publishing with Lerna. Otherwise, lerna will fail with 403 because the token will not have enough priveleges to check access via endpoints that Lerna use. Credit to 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 "[email protected]"
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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | ktutnik |
| Solution 2 | |
| Solution 3 | Kirill Taletski |
