diff --git a/cspell.json b/cspell.json index 7ef6db156..bd4bca98d 100644 --- a/cspell.json +++ b/cspell.json @@ -9,6 +9,8 @@ "pnpm-lock.yaml" ], "words": [ + "allcontributors", + "apexskier", "Codecov", "codespace", "commitlint", @@ -20,11 +22,14 @@ "knip", "lcov", "markdownlintignore", + "mtfoley", "npmignore", + "npmjs", "npmpackagejsonlintrc", "outro", "packagejson", "quickstart", + "tada", "tsup", "Unstaged", "wontfix" diff --git a/docs/Creation.md b/docs/Creation.md index f3dcb101d..8eb1ef3ae 100644 --- a/docs/Creation.md +++ b/docs/Creation.md @@ -23,8 +23,8 @@ Hooray! 🥳 You can explicitly provide some or all of the options the script would prompt for as command-line flags. See [Options.md](./Options.md). -For example, running the creation script and skipping all APIs: +For example, running the creation script and skipping all GitHub APIs: ```shell -npx create-typescript-app --mode create --exclude-contributors --skip-github-api +npx create-typescript-app --mode create --skip-all-contributors-api --skip-github-api ``` diff --git a/docs/Initialization.md b/docs/Initialization.md index 5a09e4c8a..b8b87a539 100644 --- a/docs/Initialization.md +++ b/docs/Initialization.md @@ -37,8 +37,8 @@ See [Options.md](./Options.md). `pnpm run initialize` will set `--mode` to `initialize`. -For example, running the initialization script and skipping all APIs: +For example, running the initialization script and skipping all GitHub APIs: ```shell -pnpm run initialize --exclude-contributors --skip-github-api +pnpm run initialize --skip-all-contributors-api --skip-github-api ``` diff --git a/docs/Migration.md b/docs/Migration.md index 9e9a8f9d0..ecb2aa69d 100644 --- a/docs/Migration.md +++ b/docs/Migration.md @@ -16,8 +16,8 @@ npx create-typescript-app You can explicitly provide some or all of the options the script would prompt for as command-line flags. See [Options.md](./Options.md). -For example, running the migration script and skipping all APIs: +For example, running the migration script and skipping all GitHub APIs: ```shell -npx create-typescript-app --mode migrate --exclude-contributors --skip-github-api +npx create-typescript-app --mode migrate --skip-all-contributors-api --skip-github-api ``` diff --git a/docs/Options.md b/docs/Options.md index 1f4408fc5..6a8c7d79e 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -74,8 +74,8 @@ The setup scripts can be directed with CLI flags to opt out tooling portions and The setup scripts normally will prompt you to select how much of the tooling you'd like to enable in a new repository. Alternately, you can bypass that prompt by providing any number of the following CLI flags: +- `--exclude-all-contributors`: Don't add all-contributors to track contributions and display them in a README.md table. - `--exclude-compliance`: Don't add a GitHub Actions workflow to verify that PRs match an expected format. -- `--exclude-contributors`: Don't add all-contributors to track contributions and display them in a README.md table. - `--exclude-lint-json`: Don't apply linting and sorting to `*.json` and `*.jsonc` files. - `--exclude-lint-knip`: Don't add Knip to detect unused files, dependencies, and code exports. - `--exclude-lint-md`: Don't apply linting to `*.md` files. @@ -107,18 +107,18 @@ npx create-typescript-app --exclude-lint-package-json --exclude-lint-packages -- You can prevent the migration script from making some network-based changes using any or all of the following CLI flags: -- `--exclude-contributors` _(`boolean`)_: Skips network calls that fetch all-contributors data from GitHub - - This flag does nothing if `--exclude-contributors` was specified. +- `--skip-all-contributors-api` _(`boolean`)_: Skips network calls that fetch all-contributors data from GitHub + - This flag does nothing if `--skip-all-contributors` was specified. - `--skip-github-api` _(`boolean`)_: Skips calling to GitHub APIs. - `--skip-install` _(`boolean`)_: Skips installing all the new template packages with `pnpm`. For example, providing all three flags will completely skip all network requests: ```shell -npx create-typescript-app --exclude-contributors --skip-github-api --skip-install +npx create-typescript-app --skip-all-contributors-api --skip-github-api --skip-install ``` -> 💡 Tip: To temporarily preview what the script would apply, you can run with all `--skip-*` flags, then `git add -A; git reset --hard HEAD` to completely reset all changes. +> 💡 Tip: To temporarily preview what the script would apply without making changes on GitHub, you can run with all `--skip-*-api` flags, then `git add -A; git reset --hard HEAD` to completely reset all changes. ### Skipping Local Changes diff --git a/script/create-test-e2e.js b/script/create-test-e2e.js index 552ab33c6..7a6092cd1 100644 --- a/script/create-test-e2e.js +++ b/script/create-test-e2e.js @@ -12,7 +12,7 @@ await $`rm -rf ${repository}`; await $({ stdio: "inherit", -})`c8 -o ./coverage-create -r html -r lcov --src src node ./bin/index.js --base everything --mode create --author ${author} --email ${email} --description ${description} --owner ${owner} --title ${title} --repository ${repository} --exclude-contributors --skip-github-api`; +})`c8 -o ./coverage-create -r html -r lcov --src src node ./bin/index.js --base everything --mode create --author ${author} --email ${email} --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-all-contributors-api --skip-github-api`; process.chdir(repository); diff --git a/script/initialize-test-e2e.js b/script/initialize-test-e2e.js index d2fc52403..3d4350eca 100644 --- a/script/initialize-test-e2e.js +++ b/script/initialize-test-e2e.js @@ -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 ./bin/index.js --description ${description} --base everything --mode initialize --owner ${owner} --title ${title} --repository ${repository} --skip-github-api --skip-restore`; +})`node ./bin/index.js --description ${description} --base everything --mode initialize --owner ${owner} --title ${title} --repository ${repository} --skip-all-contributors-api --skip-github-api --skip-restore`; const newPackageJson = JSON.parse( (await fs.readFile("./package.json")).toString(), @@ -49,4 +49,4 @@ await $`pnpm i`; await $`pnpm run build`; await $({ stdio: "inherit", -})`c8 -o ./coverage-initialize -r html -r lcov --src src node ./bin/index.js --base everything --description ${description} --mode initialize --owner ${owner} --title ${title} --repository ${repository} --exclude-contributors --skip-github-api --skip-removal --skip-restore`; +})`c8 -o ./coverage-initialize -r html -r lcov --src src node ./bin/index.js --base everything --description ${description} --mode initialize --owner ${owner} --title ${title} --repository ${repository} --skip-all-contributors-api --skip-github-api --skip-removal --skip-restore`; diff --git a/script/migrate-test-e2e.js b/script/migrate-test-e2e.js index cf2bb2bfa..ad5082343 100644 --- a/script/migrate-test-e2e.js +++ b/script/migrate-test-e2e.js @@ -11,7 +11,7 @@ const title = "Create TypeScript App"; await $({ stdio: "inherit", -})`c8 -o ./coverage-migrate -r html -r lcov --src src node ./bin/index.js --base everything --mode migrate --description ${description} --email-github ${emailGithub} --email-npm ${emailNpm} --owner ${owner} --title ${title} --repository ${repository} --exclude-contributors --skip-github-api --skip-install`; +})`c8 -o ./coverage-migrate -r html -r lcov --src src node ./bin/index.js --base everything --mode migrate --description ${description} --email-github ${emailGithub} --email-npm ${emailNpm} --owner ${owner} --title ${title} --repository ${repository} --skip-all-contributors-api --skip-github-api --skip-install`; const { stdout: gitStatus } = await $`git status`; console.log(`Stdout from running \`git status\`:\n${gitStatus}`); diff --git a/src/create/createRerunSuggestion.test.ts b/src/create/createRerunSuggestion.test.ts index 437d7e994..393e02a01 100644 --- a/src/create/createRerunSuggestion.test.ts +++ b/src/create/createRerunSuggestion.test.ts @@ -13,8 +13,8 @@ const options = { github: "github@email.com", npm: "npm@email.com", }, + excludeAllContributors: true, excludeCompliance: true, - excludeContributors: true, excludeLintJSDoc: true, excludeLintJson: true, excludeLintKnip: true, @@ -45,7 +45,7 @@ describe("createRerunSuggestion", () => { const actual = createRerunSuggestion(options); expect(actual).toMatchInlineSnapshot( - '"npx create-typescript-app --mode create --base everything --access public --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github github@email.com --email-npm npm@email.com --exclude-compliance true --exclude-contributors true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-package-json true --exclude-lint-perfectionist true --mode create --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""', + '"npx create-typescript-app --mode create --base everything --access public --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github github@email.com --email-npm npm@email.com --exclude-all-contributors true --exclude-compliance true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-package-json true --exclude-lint-perfectionist true --mode create --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""', ); }); @@ -60,7 +60,7 @@ describe("createRerunSuggestion", () => { }); expect(actual).toMatchInlineSnapshot( - '"npx create-typescript-app --mode initialize --base everything --access public --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github github@email.com --email-npm npm@email.com --exclude-compliance true --exclude-contributors true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-package-json true --exclude-lint-perfectionist true --logo test/src.png --logo-alt \\"Test alt.\\" --mode initialize --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""', + '"npx create-typescript-app --mode initialize --base everything --access public --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github github@email.com --email-npm npm@email.com --exclude-all-contributors true --exclude-compliance true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-package-json true --exclude-lint-perfectionist true --logo test/src.png --logo-alt \\"Test alt.\\" --mode initialize --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""', ); }); @@ -74,7 +74,7 @@ describe("createRerunSuggestion", () => { }); expect(actual).toMatchInlineSnapshot( - '"npx create-typescript-app --mode initialize --base everything --access public --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github github@email.com --email-npm npm@email.com --exclude-compliance true --exclude-contributors true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-md true --exclude-lint-package-json true --exclude-lint-perfectionist true --exclude-lint-spelling true --mode initialize --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""', + '"npx create-typescript-app --mode initialize --base everything --access public --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github github@email.com --email-npm npm@email.com --exclude-all-contributors true --exclude-compliance true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-md true --exclude-lint-package-json true --exclude-lint-perfectionist true --exclude-lint-spelling true --mode initialize --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""', ); }); }); diff --git a/src/create/createWithOptions.ts b/src/create/createWithOptions.ts index f8324a55d..da5cf56ee 100644 --- a/src/create/createWithOptions.ts +++ b/src/create/createWithOptions.ts @@ -27,7 +27,7 @@ export async function createWithOptions({ github, options }: GitHubAndOptions) { ], ]); - if (!options.excludeContributors) { + if (!options.excludeAllContributors && !options.skipAllContributorsApi) { await withSpinner("Adding contributors to table", async () => { await addToolAllContributors(options.owner); }); diff --git a/src/initialize/initializeWithOptions.ts b/src/initialize/initializeWithOptions.ts index 1a8a63b6b..91fb555a6 100644 --- a/src/initialize/initializeWithOptions.ts +++ b/src/initialize/initializeWithOptions.ts @@ -33,7 +33,7 @@ export async function initializeWithOptions({ ["Resetting Git tags", resetGitTags], ]); - if (!options.excludeContributors) { + if (!options.excludeAllContributors) { await withSpinner("Updating existing contributor details", async () => { await addOwnerAsAllContributor(options.owner); }); diff --git a/src/migrate/migrateWithOptions.ts b/src/migrate/migrateWithOptions.ts index b862a9459..01e4a3291 100644 --- a/src/migrate/migrateWithOptions.ts +++ b/src/migrate/migrateWithOptions.ts @@ -48,7 +48,7 @@ export async function migrateWithOptions({ }); } - if (!options.excludeContributors) { + if (!options.excludeAllContributors && !options.skipAllContributorsApi) { await withSpinner("Detecting existing contributors", async () => detectExistingContributors(github?.auth, options), ); diff --git a/src/shared/options/args.ts b/src/shared/options/args.ts index 157994685..a3a762558 100644 --- a/src/shared/options/args.ts +++ b/src/shared/options/args.ts @@ -7,8 +7,8 @@ export const allArgOptions = { email: { type: "string" }, "email-github": { type: "string" }, "email-npm": { type: "string" }, + "exclude-all-contributors": { type: "boolean" }, "exclude-compliance": { type: "boolean" }, - "exclude-contributors": { type: "boolean" }, "exclude-lint-deprecation": { type: "boolean" }, "exclude-lint-eslint": { type: "boolean" }, "exclude-lint-jsdoc": { type: "boolean" }, @@ -32,6 +32,7 @@ export const allArgOptions = { mode: { type: "string" }, owner: { type: "string" }, repository: { type: "string" }, + "skip-all-contributors-api": { type: "boolean" }, "skip-github-api": { type: "boolean" }, "skip-install": { type: "boolean" }, "skip-removal": { type: "boolean" }, diff --git a/src/shared/options/augmentOptionsWithExcludes.test.ts b/src/shared/options/augmentOptionsWithExcludes.test.ts index 7855426b0..d960959ce 100644 --- a/src/shared/options/augmentOptionsWithExcludes.test.ts +++ b/src/shared/options/augmentOptionsWithExcludes.test.ts @@ -6,15 +6,15 @@ import { augmentOptionsWithExcludes } from "./augmentOptionsWithExcludes.js"; const optionsBase = { access: "public", author: undefined, - base: undefined, + base: "everything", createRepository: undefined, description: "", email: { github: "github@email.com", npm: "npm@email.com", }, + excludeAllContributors: undefined, excludeCompliance: undefined, - excludeContributors: undefined, excludeLintDeprecation: undefined, excludeLintESLint: undefined, excludeLintJSDoc: undefined, @@ -94,8 +94,8 @@ describe("augmentOptionsWithExcludes", () => { expect(actual).toEqual({ ...options, + excludeAllContributors: true, excludeCompliance: true, - excludeContributors: true, excludeLintDeprecation: true, excludeLintESLint: true, excludeLintJSDoc: true, diff --git a/src/shared/options/augmentOptionsWithExcludes.ts b/src/shared/options/augmentOptionsWithExcludes.ts index 2e1c423a9..366deb1f4 100644 --- a/src/shared/options/augmentOptionsWithExcludes.ts +++ b/src/shared/options/augmentOptionsWithExcludes.ts @@ -13,17 +13,17 @@ interface ExclusionDescription { type ExclusionKey = keyof Options & `exclude${string}`; const exclusionDescriptions: Record = { + excludeAllContributors: { + hint: "--exclude-all-contributors", + label: + "Add all-contributors to track contributions and display them in a README.md table.", + }, excludeCompliance: { hint: "--exclude-compliance", label: "Add a GitHub Actions workflow to verify that PRs match an expected format.", uncommon: true, }, - excludeContributors: { - hint: "--exclude-contributors", - label: - "Add all-contributors to track contributions and display them in a README.md table.", - }, excludeLintDeprecation: { hint: "--exclude-lint-deprecation", label: diff --git a/src/shared/options/optionsSchema.ts b/src/shared/options/optionsSchema.ts index 380419061..bc1a25848 100644 --- a/src/shared/options/optionsSchema.ts +++ b/src/shared/options/optionsSchema.ts @@ -19,8 +19,8 @@ export const optionsSchemaShape = { npm: z.string().email(), }) .optional(), + excludeAllContributors: z.boolean().optional(), excludeCompliance: z.boolean().optional(), - excludeContributors: z.boolean().optional(), excludeLintDeprecation: z.boolean().optional(), excludeLintESLint: z.boolean().optional(), excludeLintJSDoc: z.boolean().optional(), @@ -46,6 +46,7 @@ export const optionsSchemaShape = { .optional(), owner: z.string().optional(), repository: z.string().optional(), + skipAllContributorsApi: z.boolean().optional(), skipGitHubApi: z.boolean().optional(), skipInstall: z.boolean().optional(), skipRemoval: z.boolean().optional(), diff --git a/src/shared/options/readOptions.test.ts b/src/shared/options/readOptions.test.ts index e1d3760b2..9be9008f5 100644 --- a/src/shared/options/readOptions.test.ts +++ b/src/shared/options/readOptions.test.ts @@ -11,8 +11,8 @@ const emptyOptions = { createRepository: undefined, description: undefined, email: undefined, + excludeAllContributors: undefined, excludeCompliance: undefined, - excludeContributors: undefined, excludeLintDeprecation: undefined, excludeLintESLint: undefined, excludeLintJSDoc: undefined, @@ -32,6 +32,7 @@ const emptyOptions = { funding: undefined, owner: undefined, repository: undefined, + skipAllContributorsApi: undefined, skipGitHubApi: undefined, skipInstall: undefined, skipRemoval: undefined, diff --git a/src/shared/options/readOptions.ts b/src/shared/options/readOptions.ts index eb01a9db8..a9b81dea3 100644 --- a/src/shared/options/readOptions.ts +++ b/src/shared/options/readOptions.ts @@ -56,8 +56,8 @@ export async function readOptions( npm: values.email ?? values["email-npm"], } : undefined, + excludeAllContributors: values["exclude-all-contributors"], excludeCompliance: values["exclude-compliance"], - excludeContributors: values["exclude-contributors"], excludeLintDeprecation: values["exclude-lint-deprecation"], excludeLintESLint: values["exclude-lint-eslint"], excludeLintJSDoc: values["exclude-lint-jsdoc"], @@ -77,6 +77,7 @@ export async function readOptions( funding: values.funding, owner: values.owner, repository: values.repository, + skipAllContributorsApi: values["skip-all-contributors-api"], skipGitHubApi: values["skip-github-api"], skipInstall: values["skip-install"], skipRemoval: values["skip-removal"], diff --git a/src/shared/types.ts b/src/shared/types.ts index a85730e4e..6b4425468 100644 --- a/src/shared/types.ts +++ b/src/shared/types.ts @@ -40,8 +40,8 @@ export interface Options { createRepository?: boolean; description: string; email: OptionsEmail; + excludeAllContributors?: boolean; excludeCompliance?: boolean; - excludeContributors?: boolean; excludeLintDeprecation?: boolean; excludeLintESLint?: boolean; excludeLintJSDoc?: boolean; @@ -64,6 +64,7 @@ export interface Options { mode: Mode; owner: string; repository: string; + skipAllContributorsApi?: boolean; skipGitHubApi?: boolean; skipInstall?: boolean; skipRemoval?: boolean; diff --git a/src/steps/finalizeDependencies.test.ts b/src/steps/finalizeDependencies.test.ts index 03a379cdb..2d9aff1d6 100644 --- a/src/steps/finalizeDependencies.test.ts +++ b/src/steps/finalizeDependencies.test.ts @@ -26,8 +26,8 @@ const options = { github: "github@email.com", npm: "npm@email.com", }, + excludeAllContributors: undefined, excludeCompliance: undefined, - excludeContributors: undefined, excludeLintJson: undefined, excludeLintKnip: undefined, excludeLintMd: undefined, @@ -71,8 +71,8 @@ describe("finalize", () => { it("installs the base list of commands when all options are enabled", async () => { await finalizeDependencies({ ...options, + excludeAllContributors: true, excludeCompliance: true, - excludeContributors: true, excludeLintJson: true, excludeLintKnip: true, excludeLintMd: true, diff --git a/src/steps/finalizeDependencies.ts b/src/steps/finalizeDependencies.ts index 64796c3f8..030b1acbb 100644 --- a/src/steps/finalizeDependencies.ts +++ b/src/steps/finalizeDependencies.ts @@ -21,7 +21,7 @@ export async function finalizeDependencies(options: Options) { "prettier-plugin-packagejson", "tsup", "typescript", - ...(options.excludeContributors ? [] : ["all-contributors-cli"]), + ...(options.excludeAllContributors ? [] : ["all-contributors-cli"]), ...(options.excludeLintJson ? [] : ["eslint-plugin-jsonc", "jsonc-eslint-parser"]), @@ -68,7 +68,7 @@ export async function finalizeDependencies(options: Options) { await execaCommand(`pnpm add ${devDependencies} -D`); - if (!options.excludeContributors) { + if (!options.excludeAllContributors) { await execaCommand(`npx all-contributors-cli generate`); await removeDependencies( ["all-contributors-cli", "all-contributors-for-repository"], diff --git a/src/steps/updateLocalFiles.test.ts b/src/steps/updateLocalFiles.test.ts index 86e28e949..ba5c386b2 100644 --- a/src/steps/updateLocalFiles.test.ts +++ b/src/steps/updateLocalFiles.test.ts @@ -29,8 +29,8 @@ const options = { github: "github@email.com", npm: "npm@email.com", }, + excludeAllContributors: undefined, excludeCompliance: undefined, - excludeContributors: undefined, excludeLintJson: undefined, excludeLintKnip: undefined, excludeLintMd: undefined, diff --git a/src/steps/writeReadme/generateTopContent.test.ts b/src/steps/writeReadme/generateTopContent.test.ts index e650bf781..d85afee6a 100644 --- a/src/steps/writeReadme/generateTopContent.test.ts +++ b/src/steps/writeReadme/generateTopContent.test.ts @@ -13,8 +13,8 @@ const optionsBase = { github: "github@email.com", npm: "npm@email.com", }, + excludeAllContributors: undefined, excludeCompliance: undefined, - excludeContributors: undefined, excludeLintJson: undefined, excludeLintKnip: undefined, excludeLintMd: undefined, diff --git a/src/steps/writeReadme/generateTopContent.ts b/src/steps/writeReadme/generateTopContent.ts index 1bf43ebf5..1c7d8b597 100644 --- a/src/steps/writeReadme/generateTopContent.ts +++ b/src/steps/writeReadme/generateTopContent.ts @@ -23,7 +23,7 @@ export function generateTopContent(options: Options, existingBadges: string[]) { for (const [badgeLine, existingMatcher] of [ [ - !options.excludeContributors && + !options.excludeAllContributors && ` diff --git a/src/steps/writeReadme/index.test.ts b/src/steps/writeReadme/index.test.ts index 85a168eb7..d45f249cd 100644 --- a/src/steps/writeReadme/index.test.ts +++ b/src/steps/writeReadme/index.test.ts @@ -33,8 +33,8 @@ const options = { github: "github@email.com", npm: "npm@email.com", }, + excludeAllContributors: undefined, excludeCompliance: undefined, - excludeContributors: undefined, excludeLintJson: undefined, excludeLintKnip: undefined, excludeLintMd: undefined, @@ -209,7 +209,7 @@ describe("writeReadme", () => { await writeReadme({ ...options, - excludeContributors: false, + excludeAllContributors: false, }); expect(mockWriteFile.mock.calls).toMatchInlineSnapshot(` diff --git a/src/steps/writeReadme/index.ts b/src/steps/writeReadme/index.ts index 378e453a9..26af70de3 100644 --- a/src/steps/writeReadme/index.ts +++ b/src/steps/writeReadme/index.ts @@ -33,7 +33,7 @@ function generateAllContributorsContent(options: Options) { export async function writeReadme(options: Options) { const allContributorsContent = - !options.excludeContributors && generateAllContributorsContent(options); + !options.excludeAllContributors && generateAllContributorsContent(options); let contents = await readFileSafe("README.md", ""); if (!contents) { await fs.writeFile( diff --git a/src/steps/writing/creation/createESLintRC.test.ts b/src/steps/writing/creation/createESLintRC.test.ts index 16c9bd716..c65c7a001 100644 --- a/src/steps/writing/creation/createESLintRC.test.ts +++ b/src/steps/writing/creation/createESLintRC.test.ts @@ -17,7 +17,7 @@ function fakeOptions(getExcludeValue: (exclusionName: string) => boolean) { ...Object.fromEntries( [ "excludeCompliance", - "excludeContributors", + "excludeAllContributors", "excludeLintDeprecation", "excludeLintESLint", "excludeLintJSDoc", diff --git a/src/steps/writing/creation/dotGitHub/createDevelopment.test.ts b/src/steps/writing/creation/dotGitHub/createDevelopment.test.ts index 9fdbbb403..6166a7f5f 100644 --- a/src/steps/writing/creation/dotGitHub/createDevelopment.test.ts +++ b/src/steps/writing/creation/dotGitHub/createDevelopment.test.ts @@ -13,8 +13,8 @@ const options = { github: "github@email.com", npm: "npm@email.com", }, + excludeAllContributors: undefined, excludeCompliance: undefined, - excludeContributors: undefined, excludeLintJson: undefined, excludeLintKnip: undefined, excludeLintMd: undefined, diff --git a/src/steps/writing/creation/dotGitHub/createWorkflows.test.ts b/src/steps/writing/creation/dotGitHub/createWorkflows.test.ts new file mode 100644 index 000000000..3a15093df --- /dev/null +++ b/src/steps/writing/creation/dotGitHub/createWorkflows.test.ts @@ -0,0 +1,494 @@ +import { describe, expect, it } from "vitest"; + +import { Options } from "../../../../shared/types.js"; +import { createWorkflows } from "./createWorkflows.js"; + +const createOptions = (exclude: boolean) => + ({ + access: "public", + author: undefined, + base: "everything", + description: "Stub description.", + email: { + github: "github@email.com", + npm: "npm@email.com", + }, + excludeAllContributors: exclude, + excludeCompliance: exclude, + excludeLintJson: exclude, + excludeLintKnip: exclude, + excludeLintMd: exclude, + excludeLintPackageJson: exclude, + excludeLintPackages: exclude, + excludeLintPerfectionist: exclude, + excludeLintSpelling: exclude, + excludeLintYml: exclude, + excludeReleases: exclude, + excludeRenovate: exclude, + excludeTests: exclude, + funding: undefined, + logo: undefined, + mode: "create", + owner: "StubOwner", + repository: "stub-repository", + title: "Stub Title", + }) satisfies Options; + +describe("createWorkflows", () => { + it("creates a full set of workflows when all excludes are disabled", () => { + const workflows = createWorkflows(createOptions(false)); + + expect(workflows).toMatchInlineSnapshot(` + { + "build.yml": "jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/prepare + - run: pnpm build + - run: node ./lib/index.js + + name: Build + + on: + pull_request: ~ + push: + branches: + - main + ", + "compliance.yml": "jobs: + compliance: + runs-on: ubuntu-latest + steps: + - uses: mtfoley/pr-compliance-action@main + with: + body-auto-close: false + ignore-authors: |- + allcontributors + allcontributors[bot] + renovate + renovate[bot] + ignore-team-members: false + + name: Compliance + + on: + pull_request: + branches: + - main + types: + - edited + - opened + - reopened + - synchronize + + permissions: + pull-requests: write + ", + "contributors.yml": "jobs: + contributors: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: ./.github/actions/prepare + - env: + GITHUB_TOKEN: \${{ secrets.ACCESS_TOKEN }} + uses: JoshuaKGoldberg/all-contributors-auto-action@v0.3.2 + + name: Contributors + + on: + push: + branches: + - main + ", + "lint-knip.yml": "jobs: + lint_knip: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/prepare + - run: pnpm lint:knip + + name: Lint Knip + + on: + pull_request: ~ + push: + branches: + - main + ", + "lint-markdown.yml": "jobs: + lint_markdown: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/prepare + - run: pnpm lint:md + + name: Lint Markdown + + on: + pull_request: ~ + push: + branches: + - main + ", + "lint-package-json.yml": "jobs: + lint_package_json: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/prepare + - run: pnpm lint:package-json + + name: Lint Package JSON + + on: + pull_request: ~ + push: + branches: + - main + ", + "lint-packages.yml": "jobs: + lint_packages: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/prepare + - run: pnpm lint:packages + + name: Lint Packages + + on: + pull_request: ~ + push: + branches: + - main + ", + "lint-spelling.yml": "jobs: + lint_spelling: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/prepare + - run: pnpm lint:spelling + + name: Lint spelling + + on: + pull_request: ~ + push: + branches: + - main + ", + "lint.yml": "jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/prepare + - run: pnpm lint + + name: Lint + + on: + pull_request: ~ + push: + branches: + - main + ", + "post-release.yml": "jobs: + post_release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - run: echo \\"npm_version=$(npm pkg get version | tr -d '\\"')\\" >> \\"$GITHUB_ENV\\" + - uses: apexskier/github-release-commenter@v1 + with: + GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }} + comment-template: | + :tada: This is included in version {release_link} :tada: + + The release is available on: + + * [GitHub releases](https://github.com/StubOwner/stub-repository/releases/tag/{release_tag}) + * [npm package (@latest dist-tag)](https://www.npmjs.com/package/stub-repository/v/\${{ env.npm_version }}) + + Cheers! 📦🚀 + + name: Post Release + + on: + release: + types: + - published + ", + "pr-review-requested.yml": "jobs: + pr_review_requested: + runs-on: ubuntu-latest + steps: + - uses: actions-ecosystem/action-remove-labels@v1 + with: + labels: 'status: waiting for author' + - if: failure() + run: | + echo \\"Don't worry if the previous step failed.\\" + echo \\"See https://github.com/actions-ecosystem/action-remove-labels/issues/221.\\" + + name: PR Review Requested + + on: + pull_request_target: + types: + - review_requested + + permissions: + pull-requests: write + ", + "prettier.yml": "jobs: + prettier: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/prepare + - run: pnpm format --list-different + + name: Prettier + + on: + pull_request: ~ + push: + branches: + - main + ", + "release.yml": "concurrency: + group: \${{ github.workflow }} + + jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: main + - uses: ./.github/actions/prepare + - run: pnpm build + - run: git config user.name \\"\${GITHUB_ACTOR}\\" + - run: git config user.email \\"\${GITHUB_ACTOR}@users.noreply.github.com\\" + - env: + NPM_TOKEN: \${{ secrets.NPM_TOKEN }} + run: npm config set //registry.npmjs.org/:_authToken $NPM_TOKEN + - name: Delete branch protection on main + uses: actions/github-script@v6.4.1 + with: + github-token: \${{ secrets.ACCESS_TOKEN }} + script: | + try { + await github.request( + \`DELETE /repos/StubOwner/stub-repository/branches/main/protection\`, + ); + } catch (error) { + if (!error.message?.includes?.(\\"Branch not protected\\")) { + throw error; + } + } + - env: + GITHUB_TOKEN: \${{ secrets.ACCESS_TOKEN }} + run: | + if pnpm run should-semantic-release ; then + pnpm release-it --verbose + fi + - if: always() + name: Recreate branch protection on main + uses: actions/github-script@v6.4.1 + with: + github-token: \${{ secrets.ACCESS_TOKEN }} + script: | + github.request( + \`PUT /repos/StubOwner/stub-repository/branches/main/protection\`, + { + allow_deletions: false, + allow_force_pushes: true, + allow_fork_pushes: false, + allow_fork_syncing: true, + block_creations: false, + branch: \\"main\\", + enforce_admins: false, + owner: \\"StubOwner\\", + repo: \\"stub-repository\\", + required_conversation_resolution: true, + required_linear_history: false, + required_pull_request_reviews: null, + required_status_checks: { + checks: [ + { context: \\"build\\" }, + { context: \\"compliance\\" }, + { context: \\"lint\\" }, + { context: \\"lint_knip\\" }, + { context: \\"lint_markdown\\" }, + { context: \\"lint_package_json\\" }, + { context: \\"lint_packages\\" }, + { context: \\"lint_spelling\\" }, + { context: \\"prettier\\" }, + { context: \\"test\\" }, + ], + strict: false, + }, + restrictions: null, + } + ); + + name: Release + + on: + push: + branches: + - main + + permissions: + contents: write + id-token: write + ", + "tsc.yml": "jobs: + type_check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/prepare + - run: pnpm tsc + + name: Type Check + + on: + pull_request: ~ + push: + branches: + - main + ", + } + `); + }); + + it("creates a minimal set of workflows when all options are enabled", () => { + const workflows = createWorkflows(createOptions(true)); + + expect(workflows).toMatchInlineSnapshot(` + { + "build.yml": "jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/prepare + - run: pnpm build + - run: node ./lib/index.js + + name: Build + + on: + pull_request: ~ + push: + branches: + - main + ", + "lint.yml": "jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/prepare + - run: pnpm lint + + name: Lint + + on: + pull_request: ~ + push: + branches: + - main + ", + "pr-review-requested.yml": "jobs: + pr_review_requested: + runs-on: ubuntu-latest + steps: + - uses: actions-ecosystem/action-remove-labels@v1 + with: + labels: 'status: waiting for author' + - if: failure() + run: | + echo \\"Don't worry if the previous step failed.\\" + echo \\"See https://github.com/actions-ecosystem/action-remove-labels/issues/221.\\" + + name: PR Review Requested + + on: + pull_request_target: + types: + - review_requested + + permissions: + pull-requests: write + ", + "prettier.yml": "jobs: + prettier: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/prepare + - run: pnpm format --list-different + + name: Prettier + + on: + pull_request: ~ + push: + branches: + - main + ", + "test.yml": "jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/prepare + - run: pnpm run test --coverage + - name: Codecov + uses: codecov/codecov-action@v3 + with: + github-token: \${{ secrets.GITHUB_TOKEN }} + + name: Test + + on: + pull_request: ~ + push: + branches: + - main + ", + "tsc.yml": "jobs: + type_check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/prepare + - run: pnpm tsc + + name: Type Check + + on: + pull_request: ~ + push: + branches: + - main + ", + } + `); + }); +}); diff --git a/src/steps/writing/creation/dotGitHub/workflows.ts b/src/steps/writing/creation/dotGitHub/createWorkflows.ts similarity index 95% rename from src/steps/writing/creation/dotGitHub/workflows.ts rename to src/steps/writing/creation/dotGitHub/createWorkflows.ts index eea0c5dcc..605c4506f 100644 --- a/src/steps/writing/creation/dotGitHub/workflows.ts +++ b/src/steps/writing/creation/dotGitHub/createWorkflows.ts @@ -56,19 +56,22 @@ export function createWorkflows(options: Options) { uses: "mtfoley/pr-compliance-action@main", with: { "body-auto-close": false, - "ignore-authors": [ - "allcontributors", - "allcontributors[bot]", - "renovate", - "renovate[bot]", - ].join("\n"), + "ignore-authors": + [ + ...(options.excludeAllContributors + ? [] + : ["allcontributors", "allcontributors[bot]"]), + ...(options.excludeRenovate + ? [] + : ["renovate", "renovate[bot]"]), + ].join("\n") || undefined, "ignore-team-members": false, }, }, ], }), }), - ...(!options.excludeContributors && { + ...(!options.excludeAllContributors && { "contributors.yml": createWorkflowFile({ name: "Contributors", on: { diff --git a/src/steps/writing/creation/dotGitHub/index.ts b/src/steps/writing/creation/dotGitHub/index.ts index 5c4700615..876e8f639 100644 --- a/src/steps/writing/creation/dotGitHub/index.ts +++ b/src/steps/writing/creation/dotGitHub/index.ts @@ -1,8 +1,8 @@ import { Options } from "../../../../shared/types.js"; import { createDotGitHubActions } from "./actions.js"; import { createDotGitHubFiles } from "./createDotGitHubFiles.js"; +import { createWorkflows } from "./createWorkflows.js"; import { createDotGitHubIssueTemplate } from "./issueTemplate.js"; -import { createWorkflows } from "./workflows.js"; export async function createDotGitHub(options: Options) { return { diff --git a/src/steps/writing/creation/rootFiles.ts b/src/steps/writing/creation/rootFiles.ts index 1c9e7c034..427755f49 100644 --- a/src/steps/writing/creation/rootFiles.ts +++ b/src/steps/writing/creation/rootFiles.ts @@ -48,7 +48,7 @@ export async function createRootFiles(options: Options) { }), ".nvmrc": `18.18.0\n`, ".prettierignore": formatIgnoreFile([ - ...(options.excludeContributors ? [] : [".all-contributorsrc"]), + ...(options.excludeAllContributors ? [] : [".all-contributorsrc"]), ...(options.excludeTests ? [] : ["coverage/"]), "lib/", "pnpm-lock.yaml", diff --git a/src/steps/writing/creation/writePackageJson.test.ts b/src/steps/writing/creation/writePackageJson.test.ts index dc2d8fb56..ba08f7c81 100644 --- a/src/steps/writing/creation/writePackageJson.test.ts +++ b/src/steps/writing/creation/writePackageJson.test.ts @@ -21,8 +21,8 @@ const options = { github: "github@email.com", npm: "npm@email.com", }, + excludeAllContributors: undefined, excludeCompliance: undefined, - excludeContributors: undefined, excludeLintJson: undefined, excludeLintKnip: undefined, excludeLintMd: undefined, @@ -132,8 +132,8 @@ describe("writePackageJson", () => { const packageJson = await writePackageJson({ ...options, + excludeAllContributors: true, excludeCompliance: true, - excludeContributors: true, excludeLintJson: true, excludeLintKnip: true, excludeLintMd: true,