Skip to content

Commit

Permalink
feat(release): initial release CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
chengpeiquan committed Feb 15, 2024
1 parent 4c2ca23 commit 8089d04
Show file tree
Hide file tree
Showing 6 changed files with 270 additions and 0 deletions.
3 changes: 3 additions & 0 deletions packages/release/.build/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"bin": true
}
114 changes: 114 additions & 0 deletions packages/release/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# @bassist/release

<p>
<a href='https://www.npmjs.com/package/@bassist/release'>
<img src="https://img.shields.io/npm/v/@bassist/release?color=f43f5e&label=npm" />
</a>
<a href="https://www.npmjs.com/package/@bassist/release" target="__blank">
<img src="https://img.shields.io/npm/dt/@bassist/release?color=f43f5e&label=downloads" />
</a>
<a href="https://github.com/chengpeiquan/bassist/tree/main/packages/release" target="__blank">
<img src="https://img.shields.io/static/v1?label=&message=docs%20%26%20demos&color=f43f5e" />
</a>
<a href="https://github.com/chengpeiquan/bassist" target="__blank">
<img alt="GitHub stars" src="https://img.shields.io/github/stars/chengpeiquan/bassist?style=social" />
</a>
</p>

Simple GitHub release generator by [@chengpeiquan](https://github.com/chengpeiquan) , based on [GitHub CLI](https://cli.github.com/).

If you're tired of having to release every time on GitHub web, you can use this package to make it easier and just run a single command.

## Prerequisite

For the security of your account and to avoid Token leakage, you must first install GitHub CLI and complete the login on it.

See: [GitHub CLI](https://cli.github.com/)

And make sure you have Release permissions on the project's GitHub repository.

There is another requirement, please configure the repository information of `package.json` according to the specifications of npm docs.

See: [repository](https://docs.npmjs.com/cli/v10/configuring-npm/package-json#repository)

e.g.

For single-package repo:

```json
{
"repository": {
"type": "git",
"url": "https://github.com/chengpeiquan/bassist"
}
}
```

For monorepo, you can specify the `directory` in which it lives:

```json
{
"repository": {
"type": "git",
"url": "https://github.com/chengpeiquan/bassist",
"directory": "packages/utils"
}
}
```

Currently supported URL formats are:

- `https://github.com/chengpeiquan/bassist`
- `https://github.com/chengpeiquan/bassist.git`
- `github:chengpeiquan/bassist`

## Usage

This is a CLI tool, you can install it locally and run it through commands such as pnpm exec.

Install it:

```bash
pnpm add -D @bassist/release
```

In your `package.json` :

```json
{
"scripts": {
"gen:release": "pnpm exec release"
}
}
```

Run on command line:

```bash
pnpm gen:release
```

You can view the latest release information on the releases page of your GitHub repository.

## Options

For most projects, the default settings are sufficient. If adjustments are sometimes needed, some options are provided to pass on.

On the command line, options can be passed to the program, e.g. `--preset angular` by option, or `-p angular` by short flag.

| Option | Short Flag | Default Value | Description |
| :-------: | :--------: | :------------: | :--------------------------------------------- |
| branch | b | `main` | The branch where the CHANGELOG file is located |
| changelog | c | `CHANGELOG.md` | The file name of the change log |

Btw: The paths are all based on `process.cwd()` , which is usually run from the root directory of the package (the directory where `package.json` is located).

If there are any running problems, please provide a reproducible example in the [issue](https://github.com/chengpeiquan/bassist/issues) .

## Release Notes

Please refer to [CHANGELOG](https://github.com/chengpeiquan/bassist/blob/main/packages/release/CHANGELOG.md) for details.

## License

MIT License © 2023-PRESENT [chengpeiquan](https://github.com/chengpeiquan)
40 changes: 40 additions & 0 deletions packages/release/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "@bassist/release",
"version": "0.1.0",
"description": "Simple GitHub release generator by @chengpeiquan , based on GitHub CLI.",
"author": "chengpeiquan <[email protected]>",
"license": "MIT",
"homepage": "https://github.com/chengpeiquan/bassist/tree/main/packages/release",
"files": [
"dist"
],
"bin": {
"@bassist/release": "./dist/index.mjs",
"release": "./dist/index.mjs"
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
},
"repository": {
"type": "git",
"url": "https://github.com/chengpeiquan/bassist"
},
"keywords": [
"release",
"release generator",
"generate release",
"github release"
],
"dependencies": {
"@bassist/utils": "workspace:^",
"@withtypes/fs-extra": "^0.1.1",
"@withtypes/minimist": "^0.1.1"
}
}
49 changes: 49 additions & 0 deletions packages/release/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { resolve } from 'node:path'
import { execSync } from 'node:child_process'
import { readJsonSync } from '@withtypes/fs-extra'
import { getNotes } from './utils'
import minimist from '@withtypes/minimist'
import pkg from '../package.json'

async function run() {
const argv = minimist(process.argv.slice(2), {
string: ['_', 'branch', 'changelog'],
alias: {
branch: 'b',
changelog: 'c',
},
})

const { branch = 'main', changelog = 'CHANGELOG.md' } = argv

const cwd = process.cwd()
const pkgPath = resolve(cwd, './package.json')
const json = readJsonSync(pkgPath) || {}

const { version, repository } = json
if (!version) {
throw new Error(`[${pkg.name}] Missing package version`)
}
if (!repository) {
throw new Error(`[${pkg.name}] Missing package repository`)
}

const notes = getNotes({
repository,
branch,
changelog,
})

const releaseArgs = [
'gh --version',
`git tag -a v${version} -m "v${version}"`,
`git push origin v${version}`,
`gh release create v${version} --title "v${version}" --notes "${notes}"`,
]

const cmd = releaseArgs.join(' && ')
execSync(cmd)
}
run().catch((e) => {
console.log(e)
})
52 changes: 52 additions & 0 deletions packages/release/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { isObject } from '@bassist/utils'

const GITHUB_URL = 'https://github.com/'
const DETAILS_LABEL = 'CHANGELOG'

// https://docs.npmjs.com/cli/v10/configuring-npm/package-json#repository
interface Repository {
type: string
url: string
directory: string
}

function getRepo(repository?: Repository) {
if (!repository || !isObject(repository)) return undefined
const { url = '', directory = '' } = repository
if (!url) return undefined

if (url.startsWith('http')) {
const repo = url.endsWith('.git') ? url.replace('.git', '') : url
return { repo, directory }
}

if (url.startsWith('github:')) {
const user = url.replace('github:', '')
const repo = `${GITHUB_URL}${user}`
return { repo, directory }
}

return undefined
}

function getTips(label = DETAILS_LABEL) {
return ['Please refer to', label, 'for details.'].join(' ')
}

interface GetNotesOptions {
repository?: Repository
branch: string
changelog: string
}

export function getNotes({ repository, branch, changelog }: GetNotesOptions) {
const repoInfo = getRepo(repository)
if (!repoInfo) return getTips()

const url = [repoInfo.repo, 'blob', branch, repoInfo.directory, changelog]
.filter((i) => !!i)
.join('/')

const label = `[${DETAILS_LABEL}](${url})`
return getTips(label)
}
12 changes: 12 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8089d04

Please sign in to comment.