Skip to content

Commit

Permalink
Ci/add full ci workflow (#83)
Browse files Browse the repository at this point in the history
* ci: add action to extract package version from lerna.json

* ci: use lerna and create-pull-request actions

* ci: add release workflow

* ci: replace from-git with from-package options

* ci: add release-drafter config

* docs: add release instructions

* fix: amend typo

* docs: add links
  • Loading branch information
neodmy authored Nov 6, 2023
1 parent b7f0a9c commit 60bc7de
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 4 deletions.
18 changes: 18 additions & 0 deletions .github/actions/extract-lerna-version/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Extract Lerna Version
description: Extracts Lerna version from lerna.json and provides it as an output

outputs:
lerna-version:
value: ${{ steps.extract-version.outputs.lerna-version }}
description: 'The extracted Lerna version'

runs:
using: composite
steps:
- name: Extract Lerna Version
id: extract-version
shell: bash
run: |
LERNA_VERSION=$(jq -r '.version' lerna.json)
echo "Using Lerna version from lerna.json: $LERNA_VERSION"
echo "lerna-version=${LERNA_VERSION}" >> $GITHUB_OUTPUT
55 changes: 55 additions & 0 deletions .github/release-drafter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# https://github.com/marketplace/actions/release-drafter#configuration

name-template: 'v$RESOLVED_VERSION'
tag-template: 'v$RESOLVED_VERSION'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.

# https://github.com/release-drafter/release-drafter#version-resolver
# With the version-resolver option version number incrementing can be
# resolved automatically based on labels of individual pull requests.
version-resolver:
major:
labels:
- 'major'
minor:
labels:
- 'minor'
patch:
labels:
- 'patch'

# https://github.com/release-drafter/release-drafter#categorize-pull-requests
# With the categories option you can categorize pull requests in release
# notes using labels.
categories:
- title: '💥 Breaking changes'
labels:
- 'major'
- title: '🚀 New features'
labels:
- 'minor'
- title: '🧰 Others'
labels:
- 'patch'

# https://github.com/release-drafter/release-drafter#autolabeler
# You can add automatically a label into a pull request, with the autolabeler
# option. Available matchers are files (glob), branch (regex), title (regex)
# and body (regex). Matchers are evaluated independently; the label will be
# set if at least one of the matchers meets the criteria.
autolabeler:
- label: 'major'
title:
- '/^\S+!{1}:{1}\s{1}\S*/i'
- label: 'minor'
title:
- '/^feat:{1}\s{1}\S*/i'
- label: 'patch'
title:
- '/^(build|chore|ci|docs|fix|perf|refactor|revert|style|test):{1}\s{1}\S*/i'

template: |
## What’s Changed
$CHANGES
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ jobs:
- name: Set auth credentials in .npmrc
run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_GUIDESMITHS }}" > .npmrc

- name: Publish packages from git
run: npx lerna publish from-git -y
- name: Publish packages from package
run: npx lerna publish from-package -y
shell: bash
32 changes: 32 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Generate draft release

on:
pull_request:
types:
- closed

permissions:
contents: write

jobs:
test:
if: |
github.event.pull_request.merged == true &&
startsWith(github.head_ref, 'releases/')
runs-on: ubuntu-latest
name: Release
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Extract Lerna Version
id: extract-lerna-version
uses: ./.github/actions/extract-lerna-version

- name: Release
uses: release-drafter/release-drafter@65c5fb495d1e69aa8c08a3317bc44ff8aabe9772 # v5.24.0
with:
tag: "v${{ steps.extract-lerna-version.outputs.lerna-version }}"
version: "v${{ steps.extract-lerna-version.outputs.lerna-version }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
34 changes: 32 additions & 2 deletions .github/workflows/version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,21 @@ on:
workflow_dispatch:
inputs:
version-bump:
description: 'The type of version bump to perform. Must be one of: major, minor, patch, premajor, preminor, prepatch, prerelease'
description: 'The type of version bump to perform.'
required: true
type: choice
options:
- major
- minor
- patch
- premajor
- preminor
- prepatch
- prerelease

permissions:
contents: write
pull-requests: write

jobs:
test:
Expand Down Expand Up @@ -36,7 +46,27 @@ jobs:
shell: bash

- name: Bump version of packages
run: npx lerna version ${{ inputs.version-bump }} --yes
run: npx lerna version ${{ inputs.version-bump }} --yes --no-push --no-git-tag-version
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Extract Lerna Version
id: extract-lerna-version
uses: ./.github/actions/extract-lerna-version

- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
with:
branch: releases/bump-version-v${{ steps.extract-lerna-version.outputs.lerna-version }}
title: releases/bump-version-v${{ steps.extract-lerna-version.outputs.lerna-version }}
author: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
commit-message: "chore: bump version to v${{ steps.extract-lerna-version.outputs.lerna-version }}"
labels: releases
body: |
Bump packages to v${{ steps.extract-lerna-version.outputs.lerna-version }}. A new draft release will be generated on merge.
Auto-generated by [create-pull-request][1] during Version workflow.
[1]: https://github.com/peter-evans/create-pull-request
33 changes: 33 additions & 0 deletions RELEASE_INSTRUCTIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Release Instructions

## TL;DR

1. Trigger the [Version](https://github.com/onebeyond/cuckoojs/actions/workflows/version.yml) workflow specifying the `version-bump`
2. Publish the draft release (press the edit icon of the newly created draft release in [here](https://github.com/onebeyond/cuckoojs/releases))
3. See your packages get published to NPM 😌

## Motivation

This repository uses [Lerna](https://lerna.js.org/docs/introduction) as a tool to handle monorepos. Lerna provides commands [`version`](https://github.com/lerna/lerna/tree/main/libs/commands/version) and [`publish`](https://github.com/lerna/lerna/tree/main/libs/commands/publish), which under normal circumstances should be sufficient for versioning and publishing packages in a monorepo. In brief, the `version` command increments the versions of the monorepo packages, generates a [git tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging), and pushes the modified files (`lerna.json`, `package.json` of the packages, changelog files, etc.) and the git tag. The `publish` command publishes the packages to the corresponding registry.

As mentioned in Lerna's documentation for the [`allow-branch`](https://github.com/lerna/lerna/tree/main/libs/commands/publish) option, it is advisable not to run the `version` command on a branch other than `main`. We agree that allowing versioning on branches can be error-prone. However, in this repository, pushes to `main` are restricted. We also wanted to avoid using person access tokens. This first limitation has led us to opt for an alternative and secure way to increment the version of the packages.

Furthermore, even though Lerna can generate versions based on commit messages following the [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) specification, we have chosen a somewhat more manual but safer approach, at least in our opinion.

Continuing in this line, another limitation of Lerna (at least with our current knowledge of the tool) is that, even though it can generate git tags, it does not allow generating releases on GitHub automatically and synchronized with the package publishing in the corresponding registry.

## Workflows

Due to the reasons mentioned earlier, we have decided to structure the release process in three separate [workflows](./.github/workflows):

- [Version](./.github/workflows/version.yml): This workflow is triggered with a [`workflow_dispatch`](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_dispatch) trigger, where you need to specify the `version-bump` using a choice input. The options correspond to the positional argument [`bump`](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_dispatch) of Lerna's `version` command. Key steps in this workflow include:
- Increasing the version of packages using Lerna's `version`. The `--no-push` option prevents Lerna from pushing the changes, and `--no-git-tag-version` prevents Lerna generating a git tag. Both actions are delegated to subsequent steps and/or workflows.
- Creating a pull request using the [create-pull-request](https://github.com/peter-evans/create-pull-request) action. The generated branch follows the format `releases/bump-version-v*.*.*`, where `*.*.*` is the version generated by Lerna according to the `version-bump` input.
- [Release](./.github/workflows/release.yml): This workflow is triggered when a pull request on a branch whose name follows the format `'releases/'` is merged. Effectively, this means that this workflow is triggered when the pull request generated during the `Version` workflow is merged. Using the [release-drafter](https://github.com/release-drafter/release-drafter) action, a draft release (and a tag) is generated on GitHub with the version determined during the `Version` workflow.
- [Publish](./.github/workflows/publish.yml): This workflow is triggered when a tag with the format `v*.*.*` is pushed. Effectively, this workflow is activated when the release generated in the previous step is published. This workflow uses Lerna's `publish` command with the [`from-package`](https://github.com/lerna/lerna/tree/main/libs/commands/publish#bump-from-package) option. We have experienced some undesired behaviour using the `from-git` option, resulting in no new versions detected during the publication step.

## Acknowledgments

A significant portion of this workflow has been inspired by the [lerna-ci-cd-example](https://github.com/fahslaj/lerna-ci-cd-example) repository by Austin Fahls (@fashlaj) and the very informative (though a bit long 🙏) video [Using Github Actions to Publish your Packages](https://www.youtube.com/watch?v=WwPrvDDuoBY) by Austin and Zachary DeRose (@ZackDeRose). Huge thanks to both.

We recommend you to visit these links. And if their work has also been helpful to you, don't forget to acknowledge their efforts. 😉

0 comments on commit 60bc7de

Please sign in to comment.