Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(laverna): automatic support for CI #1017

Merged
merged 3 commits into from Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
111 changes: 57 additions & 54 deletions package-lock.json

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

31 changes: 19 additions & 12 deletions packages/laverna/README.md
Expand Up @@ -4,29 +4,33 @@

If you're familiar with [lerna](https://lerna.js.org), **Laverna** does this: `lerna publish from-package`.

If you're unfamiliar with it: **Laverna** publishes all workspaces that haven't yet been published.
If you're unfamiliar with it: **Laverna** publishes all workspacess wherein the _current_ version hasn't yet been published.

## Features

**Laverna** is a thin wrapper around `npm publish` which:

- Invokes `npm publish` for all workspaces _that haven't yet been published_
- Handles new packages (via a flag)
- Invokes `npm publish` on _all_ workspaces _where the current version has not yet been published_
- Publishes new packages via flag
- Ignores private packages
- Requires a confirmation (by default)
- Requires confirmation (by default)
- Prints all output from `npm publish`, including the output of `npm pack`, to enable review prior to confirmation
- Provides a "dry-run" mode
- Prints all output from `npm publish`, including the output of `npm pack`, to enable review

**Laverna**'s scope is intentionally limited to the above use-case.

## Non-Features

Perhaps more importantly, **Laverna**:

- Builds nothing
- Bumps no versions
- Does not write to `package.json`
- Runs no user-defined scripts
- Retains no state nor cache
- Does not write to `package.json` or lockfiles
- Does not interact with `git` (no tags, no commits, no pushes)
- Does not interact with GitHub (no releases)
- Does not cache anything
- Avails no whims

## Supported Environments

Expand All @@ -46,16 +50,16 @@ npm install @lavamoat/laverna -D
```plain
laverna [options..]

Publish multiple workspaces (that's all)
"Publish multiple workspaces (that's all)"

Options:

--dryRun - Enable dry-run mode
--root=<path> - Path to workspace root (default: current working dir)
--newPkg=<name> - Workspace <name> has never been published (repeatable)
--yes/-y - Skip confirmation prompt
--newPkg=<name> - Workspace <name> should be treated as a new package (repeatable)
--yes/-y - Skip confirmation prompt (default: false; true in CI)

Problems? Visit https://github.com/LavaMoat/lavamoat/issues
Problems? Visit https://github.com/LavaMoat/LavaMoat/issues
```

## Examples
Expand All @@ -78,7 +82,10 @@ If you're publishing a package in a new workspace, you might:

### Automating Publishes

You'll need to figure out how to add `--newPkg` to your CI/CD pipeline. Otherwise, use the `--yes` flag when invoking `laverna`.
If the `CI` environment variable is present, `laverna` will skip the confirmation prompt before final publish (i.e., `--yes` defaults to `true`).

> [!WARNING]
> Publishing via CI can bypass 2FA protections. Use at your own risk!

## API

Expand Down
4 changes: 2 additions & 2 deletions packages/laverna/package.json
Expand Up @@ -4,12 +4,12 @@
"description": "Publish multiple workspaces (that's all)",
"repository": {
"type": "git",
"url": "git+https://github.com/LavaMoat/lavamoat.git",
"url": "git+https://github.com/LavaMoat/LavaMoat.git",
"directory": "packages/laverna"
},
"homepage": "https://github.com/LavaMoat/LavaMoat/blob/main/packages/laverna/README.md",
"bugs": {
"url": "https://github.com/LavaMoat/lavamoat/issues"
"url": "https://github.com/LavaMoat/LavaMoat/issues"
},
"author": "boneskull",
"license": "MIT",
Expand Down
18 changes: 10 additions & 8 deletions packages/laverna/src/cli.js
Expand Up @@ -3,7 +3,7 @@
/* eslint-disable n/shebang */
// @ts-check

const { bold, magenta, gray, italic } = require('kleur')
const { bold, magenta, gray, italic, cyan, underline } = require('kleur')
const util = require('node:util')
const { Laverna } = require('./laverna')
const { ERR } = require('./log-symbols')
Expand Down Expand Up @@ -72,18 +72,18 @@ function main() {
// this should be the only place we write to stdout unless we
// want to start outputting JSON
console.log(`
${bold('laverna')} [options..]
${cyan(bold('laverna'))} ${cyan('[options..]')}

${italic(description)}
"${description}"

Options:

--dryRun - Enable dry-run mode
--root=<path> - Path to workspace root (default: current working dir)
--newPkg=<name> - Workspace <name> has never been published (repeatable)
--yes/-y - Skip confirmation prompt
${bold('--dryRun')} - Enable dry-run mode
${bold('--root=<path>')} - Path to workspace root (default: current working dir)
${bold('--newPkg=<name>')} - Workspace <name> should be treated as a new package (repeatable)
${bold('--yes/-y')} - Skip confirmation prompt (default: false; true ${italic('in CI')})

Problems? Visit ${bugs.url}
Problems? Visit ${underline(bugs.url)}

`)
} else {
Expand All @@ -92,6 +92,8 @@ function main() {
opts.newPkg = [
...new Set([...(opts.newPkg ?? []), ...(opts['new-pkg'] ?? [])]),
]
// must be true in CI; --yes=false is not a thing
opts.yes = Boolean(process.env.CI) || opts.yes

console.error(`📦 ${bold(magenta(name)) + gray('@') + magenta(version)}\n`)
const laverna = new Laverna(opts)
Expand Down
8 changes: 4 additions & 4 deletions packages/laverna/test/snapshots/cli.spec.js.md
Expand Up @@ -11,16 +11,16 @@ Generated by [AVA](https://avajs.dev).
`␊
laverna [options..]␊
Publish multiple workspaces (that's all)␊
"Publish multiple workspaces (that's all)"
Options:␊
--dryRun - Enable dry-run mode␊
--root=<path> - Path to workspace root (default: current working dir)␊
--newPkg=<name> - Workspace <name> has never been published (repeatable)␊
--yes/-y - Skip confirmation prompt␊
--newPkg=<name> - Workspace <name> should be treated as a new package (repeatable)␊
--yes/-y - Skip confirmation prompt (default: false; true in CI)
Problems? Visit https://github.com/LavaMoat/lavamoat/issues␊
Problems? Visit https://github.com/LavaMoat/LavaMoat/issues␊
`
Binary file modified packages/laverna/test/snapshots/cli.spec.js.snap
Binary file not shown.