Skip to content

Commit

Permalink
chore: convert to monorepo
Browse files Browse the repository at this point in the history
  • Loading branch information
boneskull committed Sep 27, 2023
1 parent 973a0ce commit 57af516
Show file tree
Hide file tree
Showing 168 changed files with 324 additions and 510 deletions.
12 changes: 6 additions & 6 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@ extends:
- 'prettier'

ignorePatterns:
- 'node_modules/**/*'
- 'coverage/**/*'
- 'dist/**/*'
- '__snapshots__/**/*'
- '**/node_modules/**/*'
- '**/coverage/**/*'
- '**/dist/**/*'
- '**/__snapshots__/**/*'

overrides:
- files:
- 'bin/**/*'
- 'packages/midnight-smoker/bin/**/*'
parserOptions:
sourceType: 'module'
- env:
mocha: true
files:
- 'test/**/*'
- 'packages/*/test/**/*'
rules:
'@typescript-eslint/no-unused-vars': 'off'

Expand Down
6 changes: 3 additions & 3 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__snapshots__
dist
test/**/fixture/**
packages/*/__snapshots__
packages/*/dist
packages/*/test/**/fixture/**
4 changes: 2 additions & 2 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "7.0.3"
}
"packages/midnight-smoker": "7.0.3"
}
203 changes: 2 additions & 201 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,208 +2,9 @@

> Run smoke tests against packages as they would be published
## Motivation
## Packages

This thing helps prevent you from publishing something which passes all the tests, but is misconfigured or fails when a consumer tries to install or run it.

Examples of things that would be a problem:

- Missing files in published package
- `devDepenencies` which should be `dependencies`
- Weirdo `exports` configuration
- Wonky lifecycle scripts

`midnight-smoker` is intended to run in a pre-publish lifecycle script and/or in your CI pipeline.

## Example Usage

<!-- x-release-please-start-version -->

```bash
npx midnight-smoker test:smoke # runs script "test:smoke" from `package.json`

💨 midnight-smoker v5.1.0
✔ Packed 1 unique package using npm@latest…
✔ Installed 1 unique package from tarball
✔ Successfully ran 4 checks
✔ Successfully ran 1 script
✔ Lovey-dovey! 💖
```

<!-- x-release-please-end -->

`midnight-smoker` is compatible with npm workspaces and stuff.

## What It Does

In a nutshell, `midnight-smoker`:

1. Packs your workspace(s) into tarballs
2. Installs the resulting tarballs into a temp dir using shallow installs (no deduping or hoisting) for isolation. This installs only _production_ dependencies (assuming no `npm-shrinkwrap.json`), and transitive dependencies from one workspace will not be visible to any other.
3. In each installed package directory, performs a [series of checks](#builtin-checks) and/or runs scripts of your choosing.

## Usage

### Custom Scripts

Depending on your setup, one of the following should get you started. But also you should [read more](#waitwhat-should-my-custom-script-do) about what your custom script should do. And if you _really_ want to do some heavy lifting, see [the thing about adding dev tools](#but-i-need-a-dev-tool-to-run-my-script).

#### For Single-Package Repos

Add two scripts to your `package.json`. The first script will run `smoker <second-script>`.

```json
{
"scripts": {
"test:smoke": "smoker smoke",
"smoke": "node ./some-script.js"
}
}
```

#### For Repos Using Workspaces

Add a script to your **root** `package.json`:

```json
{
"scripts": {
"test:smoke": "smoker --all smoke"
}
}
```

The `--all` flag tells `midnight-smoker` to run the `smoke` script in all workspaces. For each workspace, add a `smoke` script, changing the behavior as needed:

```json
{
"scripts": {
"smoke": "node ./some-script.js"
}
}
```

If the `smoke` script should only exist in _some_ of those workspaces, then use `smoker --all --loose smoke`, and the missing scripts will be conveniently ignored.

#### Using Specific Package Managers

`midnight-smoker` supports running scripts against _multiple, specific_ package managers.

By default, it will use the latest version of `npm` to pack, install, and run the scripts. However, you can provide the `--pm` option to use a different package manager _or additional package managers._

Example:

```bash
# run the "smoke" script against the latest version of yarn@1.x.x, the latest npm,
# and npm v6.14.18.
midnight-smoker --pm yarn@1 --pm npm@latest --pm npm@6.14.18 smoke
```

> For the curious: `midnight-smoker` uses [`corepack`](https://github.com/nodejs/corepack) and supports the same versions as its `corepack` dependency. The strategy for consuming `corepack` may change in the future, if needed; ideally we could rely on the system `corepack` (since it ships with Node.js), but that's not currently possible.
>
> If present, the `packageManager` field in `package.json` will be ignored.
##### pnpm Support

As of `midnight-smoker` v4.0.0, only `yarn` and `npm` are supported. `pnpm` support is planned for a future release.

### Builtin Checks

By default, `midnight-smoker` will run a suite of checks against each installed package:

- `no-banned-files`: Asserts no sensitive files get published--things like private keys and other naughty secrets; supports custom filenames
- `no-missing-entry-point`: Asserts that a CJS package has a "traditional" entry point (`main` is defined and points to an existing file _or_ one of `index.js`, `index.json` or `index.node` exists);
- `no-missing-exports`: Asserts that the `exports` field, if present, points to an existing file or files; checks conditional exports for proper file types (ESM, CJS, or `.d.ts` in the case of `types`); asserts the `default` conditional export, if present, is _last_ in the object; optionally disallows glob patterns in subpath exports
- `no-missing-pkg-files`: Asserts that a `bin` field--if present--refers to an existing file; supports custom fields

These can be disabled entirely via the `--no-checks` option, and further configured via the `rules` property of a [config file](#config-files).

In lieu of actual documentation on the options, please see the `RuleConfig` type in `midnight-smoker`'s type declarations.

### Wait—What Should My Custom Script Do?

The bare minimum would be checking that the entry point can be run:

```json
{
"main": "dist/index.js",
"scripts": {
"test:smoke": "smoker run-entry-point",
"run-entry-point": "node ."
}
}
```

Otherwise:

- If your package distributes an executable, you might want to run that instead, and give it some common arguments (assuming it depends on your entry point). _Or_ you could go BUCK WILD and run it a bunch of different ways.
- If your package is lazy-loading its dependencies--like if you have a `require()` or `await import()` within some function that isn't called at startup--you may need to do more work than this.
- If your package skulks around in `node_modules` or otherwise has a _special relationship_ with package management or module resolution, you really ought to consider [running against multiple package managers](#using-specific-package-managers).

### But I Need a Dev Tool To Run My Script

OK--_fine_--but this is not necessarily recommended, because the result is not what a consumer would get. How much does that matter? You decide--any additional packages won't leak transitive dependencies either.

Provide the `--add <thing>` option to `midnight-smoker`, where `thing` is anything `npm install <thing>` could install:

```json
{
"scripts": {
"test:smoke": "smoker --add ts-node smoke",
"smoke": "ts-node ./some-script.ts"
},
"devDependencies": {
"ts-node": "10.9.1"
}
}
```

If unspecified in `--add`, `midnight-smoker` will use the version of the dependency in the package's `devDependencies`/`dependencies`/`optionalDependencies`/`peerDepedenencies` (in that order). If it does not appear in any of these fields, it will just pull down the `latest` tag of the dependency.

`--add` can be provided multiple times.

> PRO TIP: You should just add the thing to your `devDependencies` if it isn't there. That is smart. That is cool.
### Config Files

> [**JSON Schema**](/schema/midnight-smoker.schema.json)
I know what you're thinking: "I just don't have enough config files!" `midnight-smoker` solves this problem by giving you the opportunity to add another one. Config files are supported via a `smoker` field in `package.json`, or one of:

- `.smokerrc.(json|js|cjs|mjs)`
- `smoker.config.(json|js|cjs|mjs)`
- `.config/smokerrc.(json|js|cjs|mjs)`
- `.config/smoker.config.(json|js|cjs|mjs)`

## Installation

It's recommended to install `midnight-smoker` as a dev dependency:

```bash
npm install midnight-smoker --save-dev
```

## Requirements

- Node.js versions supported: `^16.20.0 || ^18.0.0 || ^20.0.0`
- Minimum `npm` version supported (if using `npm`): `v7.0.0`

While odd-numbered Node.js releases _may_ work, they are not tested on and not officially supported.

## Resources

- GitHub Action: [**node-js-production-test-action**](https://github.com/marketplace/actions/node-js-production-test-action)

> It's probably a better idea to just add `midnight-smoker` as a dev dep and run it instead of using this action, since it may trail behind the latest version of `midnight-smoker`.
## Acknowledgements

- [ban-sensitive-files](https://github.com/bahmutov/ban-sensitive-files) for the file list
- [ESLint](https://eslint.org/) for the "rule" concept & config

## Notes

That song sucks.
- [midnight-smoker](./packages/midnight-smoker) - the main thing

## License

Expand Down
Loading

0 comments on commit 57af516

Please sign in to comment.