Skip to content

feat: add create flow and unify bin with --mode #681

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

Merged
merged 29 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
1ce2bfd
[WIP] feat: add create flow and unify bin with --mode
JoshuaKGoldberg Aug 22, 2023
82080e3
Fix unit tests
JoshuaKGoldberg Aug 22, 2023
857e5cf
Fix up unit tests
JoshuaKGoldberg Aug 22, 2023
152dd22
Add --mode to migrate-test-e2e.js
JoshuaKGoldberg Aug 22, 2023
aaf3378
fix: spelling
JoshuaKGoldberg Aug 22, 2023
5d7f9f6
Remove bin and steps in removeSetupScripts too
JoshuaKGoldberg Aug 22, 2023
eeb55e5
Update test snapshots
JoshuaKGoldberg Aug 22, 2023
e725ce4
Test fixes: src/create in remove, and manual outro.calls
JoshuaKGoldberg Aug 22, 2023
28a8f6e
Always upload codecov results
JoshuaKGoldberg Aug 22, 2023
c4f07b1
Start on docs
JoshuaKGoldberg Aug 22, 2023
0734e92
Fix lint:md
JoshuaKGoldberg Aug 22, 2023
cafdba6
Grr, try adding asterisk
JoshuaKGoldberg Aug 22, 2023
1f04615
wip: merge main
JoshuaKGoldberg Aug 22, 2023
2ba25eb
git revert cafdba635c3d36f15181c35cd82167f4db6f2b65
JoshuaKGoldberg Aug 22, 2023
069d04f
Touched up create docs
JoshuaKGoldberg Aug 22, 2023
f678228
Again: ugh, try coverage star
JoshuaKGoldberg Aug 22, 2023
6bdc249
allow bin/index.js to be changed in migrate test
JoshuaKGoldberg Aug 22, 2023
0d009df
Add create:test
JoshuaKGoldberg Aug 22, 2023
cebf5db
Update snapshots
JoshuaKGoldberg Aug 22, 2023
b56d7bd
Touch up creation script
JoshuaKGoldberg Aug 22, 2023
6f96b40
Add author and email to create-test-e2e.js
JoshuaKGoldberg Aug 22, 2023
6ffb7f5
Small e2e touchups
JoshuaKGoldberg Aug 22, 2023
3680e61
Ok I think I got create-test-e2e working now
JoshuaKGoldberg Aug 22, 2023
9c2e21b
Added missing git init, just in case
JoshuaKGoldberg Aug 22, 2023
9f54fa2
Default version to 0.0.0
JoshuaKGoldberg Aug 22, 2023
22cfc28
Also dedupe in create
JoshuaKGoldberg Aug 22, 2023
842741a
Switch creation templte to tsup whoops
JoshuaKGoldberg Aug 22, 2023
2db597a
Add tsup to cspell
JoshuaKGoldberg Aug 22, 2023
1dc18bb
deepEqual, and test run
JoshuaKGoldberg Aug 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions .github/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ pnpm format:write
This package includes several forms of linting to enforce consistent code quality and styling.
Each should be shown in VS Code, and can be run manually on the command-line:

- `pnpm lint` ([ESLint](https://eslint.org) with [typescript-eslint](https://typescript-eslint.io)): Lints JavaScript and TypeScript source files
- `pnpm lint:knip` ([knip](https://github.com/webpro/knip)): Detects unused files, dependencies, and code exports
- `pnpm lint:md` ([Markdownlint](https://github.com/DavidAnson/markdownlint)): Checks Markdown source files
- `pnpm lint:package` ([npm-package-json-lint](https://npmpackagejsonlint.org/)): Lints the `package.json` file
- `pnpm lint:packages` ([pnpm dedupe --check](https://pnpm.io/cli/dedupe)): Checks for unnecessarily duplicated packages in the `pnpm-lock.yml` file
- `pnpm lint:spelling` ([cspell](https://cspell.org)): Spell checks across all source files
- `pnpm lint` ([ESLint](https://eslint.org) with [typescript-eslint](https://typescript-eslint.io)): Lints JavaScript and TypeScript source files

## Testing

Expand Down Expand Up @@ -89,12 +89,32 @@ pnpm tsc --watch

## Setup Scripts

As described in the `README.md` file and `docs/`, this template repository comes with two scripts that can set up an existing or new repository.
As described in the `README.md` file and `docs/`, this template repository comes with three scripts that can set up an existing or new repository.

> **Warning**
> Both setup scripts override many files in the directory they're run in.
> Each setup script overrides many files in the directory they're run in.
> Make sure to save any changes you want to preserve before running them.

### The Creation Script

This template's "creation" script is located in `src/create/`.
You can run it locally with `node bin/index.js --mode create`.
Note that files need to be built with `pnpm run build` beforehand.

#### Testing the Creation Script

You can run the end-to-end test for creation locally on the command-line.
Note that the files need to be built with `pnpm run build` beforehand.

```shell
pnpm run create:test
```

That end-to-end test executes `script/create-test-e2e.js`, which:

1. Runs the creation script to create a new `test-repository` child directory and repository
2. Asserts that commands such as `build` and `lint` each pass

### The Initialization Script

This template's "initialization" script is located in `src/initialize/`.
Expand Down
28 changes: 28 additions & 0 deletions .github/workflows/test-create.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
jobs:
create:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/prepare
- run: pnpm run build
- run: pnpm run create:test
- if: always()
name: Codecov
uses: codecov/codecov-action@v3
with:
files: coverage-create/lcov.info
flags: create
- if: always()
name: Archive code coverage results
uses: actions/upload-artifact@v3
with:
path: coverage-create

name: Test Creation Script

on:
pull_request: ~

push:
branches:
- main
3 changes: 2 additions & 1 deletion .github/workflows/test-initialize.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ jobs:
- uses: ./.github/actions/prepare
- run: pnpm run build
- run: pnpm run initialize:test
- name: Codecov
- if: always()
name: Codecov
uses: codecov/codecov-action@v3
with:
files: coverage-initialize/lcov.info
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/test-migrate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ jobs:
- uses: ./.github/actions/prepare
- run: pnpm run build
- run: pnpm run migrate:test
- name: Codecov
- if: always()
name: Codecov
uses: codecov/codecov-action@v3
with:
files: coverage-migrate/lcov.info
Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
<img alt="TypeScript: Strict 💪" src="https://img.shields.io/badge/typescript-strict_💪-21bb42.svg" />
</p>

Note that this template is early stage, opinionated, and not endorsed by the TypeScript team.
It sets up a _lot_ of tooling out of the box.
Each of the included tools exists for a good reason and provides real value.

If you don't want to use any particular tool, you can always remove it manually.

## Getting Started

First make sure you have the following installed:
Expand All @@ -37,7 +43,8 @@ First make sure you have the following installed:
This repository comes with two scripts to set up an existing or new repository with tooling.
Use the corresponding docs page to get started:

- [Initializing from the template](./docs/Initialization.md): creating a new repository with the [_Use this template_](https://github.com/JoshuaKGoldberg/template-typescript-node-package/generate) button on GitHub
- [Initializing from the template](./docs/InitializationFromTemplate.md): creating a new repository with the [_Use this template_](https://github.com/JoshuaKGoldberg/template-typescript-node-package/generate) button on GitHub _(recommended)_
- [Initializing from the terminal](./docs/InitializationFromTerminal.md): creating a new repository locally on the command-line
- [Migrating an existing repository](./docs/Migration.md): adding this template's tooling on top of an existing repository

## Explainer
Expand Down
4 changes: 4 additions & 0 deletions bin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env node
import { bin } from "../lib/bin/index.js";

process.exitCode = await bin(process.argv.slice(2));
4 changes: 0 additions & 4 deletions bin/migrate.js

This file was deleted.

4 changes: 2 additions & 2 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
codecov:
notify:
after_n_builds: 3
after_n_builds: 4
comment:
after_n_builds: 3
after_n_builds: 4
File renamed without changes.
51 changes: 51 additions & 0 deletions docs/InitializationFromTerminal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Initializing from the Terminal

As a local alternative to [initialization from the template](./InitializationFromTemplate.md), you can run `npx template-typescript-node-package` in your terminal:

```shell
npx template-typescript-node-package
```

The prompt by default will ask you which mode you'd like to run in.
Pass `--mode create` to tell it to create a new repository in a child directory:

```shell
npx template-typescript-node-package --mode create
```

Upon completion, the prompt will suggest commands to get started working in the repository and create a corresponding GitHub repository.
Those commands will roughly run the [The Initialization Script](./InitializationFromTemplate.md#the-initialization-script), but with `npm template-typescript-node-package --mode initialize` instead of `pnpm run initialize`:

```shell
cd repository-name
gh repo create repository-name --public --source=. --remote=origin
npx template-typescript-node-package --mode initialize
git add -A
git commit -m "chore: initial commit ✨"
git push -u origin main
```

## The Creation Script

The creation script will interactively prompt for values to be used in creating the new repository.
Each may provided as a string CLI flag as well:

- `--description`: Sentence case description of the repository (e.g. `A quickstart-friendly TypeScript package with lots of great repository tooling. ✨`)
- `--owner`: GitHub organization or user the repository is underneath (e.g. `JoshuaKGoldberg`)
- `--repository`: The kebab-case name of the repository (e.g. `template-typescript-node-package`)
- `--title`: Title Case title for the repository to be used in documentation (e.g. `Template TypeScript Node Package`)

For example, pre-populating all values:

```shell
npx template-typescript-node-package --mode create --repository "testing-repository" --title "Testing Title" --owner "TestingOwner" --description "Test Description"
```

Then, go through the following two steps to set up required repository tooling on GitHub:

1. Create two tokens in [repository secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets):
- `ACCESS_TOKEN`: A [GitHub PAT](https://github.com/settings/tokens/new) with _repo_ and _workflow_ permissions
- `NPM_TOKEN`: An [npm access token](https://docs.npmjs.com/creating-and-viewing-access-tokens/) with _Automation_ permissions
2. Install the [Codecov GitHub App](https://github.com/marketplace/codecov) and [Renovate GitHub App](https://github.com/marketplace/renovate)

At this point, your new repository should be ready for development! 🥳
3 changes: 1 addition & 2 deletions docs/Migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,9 @@ You can prevent the migration script from making some network-based changes usin
- `--skip-contributors` _(`boolean`)_: Skips detecting existing contributors with [`all-contributors-for-repository`](https://github.com/JoshuaKGoldberg/all-contributors-for-repository)
- `--skip-github-api` _(`boolean`)_: Skips calling to GitHub APIs
- `--skip-install` _(`boolean`)_: Skips installing all the new template packages with `pnpm`
- `--skip-initialize` _(`boolean`)_: Skips running the initialize script at the end of migration

```shell
npx template-typescript-node-package --skip-github-api --skip-initialize --skip-install
npx template-typescript-node-package --skip-github-api --skip-install
```

> Tip: the `--skip-github-api` flag will cause all changes to be limited to your local repository.
Expand Down
1 change: 1 addition & 0 deletions knip.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"$schema": "https://unpkg.com/knip@latest/schema.json",
"entry": [
"src/index.ts!",
"src/guide/index.ts",
"src/initialize/index.ts",
"src/migrate/index.ts",
"script/*e2e.js"
Expand Down
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
},
"type": "module",
"main": "./lib/index.js",
"bin": "./bin/migrate.js",
"bin": "./bin/index.js",
"files": [
"bin/",
"lib/",
Expand All @@ -23,9 +23,10 @@
],
"scripts": {
"build": "tsup",
"create:test": "node script/create-test-e2e.js",
"format": "prettier \"**/*\" --ignore-unknown",
"format:write": "pnpm format --write",
"initialize": "tsx src/initialize/index.ts",
"initialize": "tsx ./src/bin/index.js --mode initialize",
"initialize:test": "node script/initialize-test-e2e.js",
"lint": "eslint . .*js --max-warnings 0 --report-unused-disable-directives",
"lint:knip": "knip",
Expand All @@ -36,7 +37,8 @@
"migrate:test": "node script/migrate-test-e2e.js",
"prepare": "husky install",
"should-semantic-release": "should-semantic-release --verbose",
"test": "vitest"
"test": "vitest",
"tsc": "tsc"
},
"lint-staged": {
"*": "prettier --ignore-unknown --write"
Expand Down
41 changes: 41 additions & 0 deletions script/create-test-e2e.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { $, execaCommand } from "execa";
import { strict as assert } from "node:assert";

const author = "Test Author";
const description = "Test description.";
const email = "test@email.com";
const repository = "test-repository";
const owner = "TestOwner";
const title = "Test Title";

await $`rm -rf ${repository}`;

await $({
stdio: "inherit",
})`c8 -o ./coverage-create -r html -r lcov node ./bin/index.js --mode create --author ${author} --email ${email} --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-contributors --skip-github-api`;

process.chdir(repository);

const failures = [];

for (const command of [
`pnpm i`,
`pnpm run build`,
`pnpm run format --list-different`,
`pnpm run lint`,
`pnpm run lint:md`,
`pnpm run lint:package`,
`pnpm run lint:packages`,
`pnpm run lint:spelling`,
`pnpm run lint:knip`,
`pnpm run test run`,
`pnpm run tsc`,
]) {
const result = await execaCommand(command, { stdio: "inherit" });

if (result.exitCode) {
failures.push({ command, result });
}
}

assert.deepEqual(failures, []);
4 changes: 2 additions & 2 deletions script/initialize-test-e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const repository = "new-repository-test";
// First we run initialize to modifies the local repo, so we can test the changes
await $({
stdio: "inherit",
})`node ./lib/initialize/index.js --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-github-api --skip-restore`;
})`node ./bin/index.js --description ${description} --mode initialize --owner ${owner} --title ${title} --repository ${repository} --skip-github-api --skip-restore`;

const newPackageJson = JSON.parse(
(await fs.readFile("./package.json")).toString(),
Expand Down Expand Up @@ -52,4 +52,4 @@ await $`pnpm i`;
await $`pnpm run build`;
await $({
stdio: "inherit",
})`c8 -o ./coverage-initialize -r html -r lcov node ./lib/initialize/index.js --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-github-api --skip-removal --skip-restore`;
})`c8 -o ./coverage-initialize -r html -r lcov node ./bin/index.js --description ${description} --mode initialize --owner ${owner} --title ${title} --repository ${repository} --skip-github-api --skip-removal --skip-restore`;
3 changes: 2 additions & 1 deletion script/migrate-test-e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const title = "Template TypeScript Node Package";

await $({
stdio: "inherit",
})`c8 -o ./coverage-migrate -r html -r lcov node ./bin/migrate.js --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-github-api --skip-contributors --skip-initialize --skip-install`;
})`c8 -o ./coverage-migrate -r html -r lcov node ./bin/index.js --mode migrate --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-github-api --skip-contributors --skip-install`;

const { stdout: gitStatus } = await $`git status`;
console.log(`Stdout from running \`git status\`:\n${gitStatus}`);
Expand All @@ -25,6 +25,7 @@ if (indexOfUnstagedFilesMessage === -1) {

const filesExpectedToBeChanged = new Set([
".all-contributorsrc",
"bin/index.js",
"README.md",
"knip.jsonc",
"package.json",
Expand Down
Loading