From 647bbb5864a53ea8ca37315f2a160336fc0d28a5 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Fri, 23 Dec 2022 15:32:07 -0500 Subject: [PATCH 1/4] chore: end-to-end test setup script --- .github/workflows/setup.yml | 15 ++++ package.json | 1 + script/setup.js | 163 +++++++++++++++++++----------------- script/setup.test.js | 19 +++++ 4 files changed, 123 insertions(+), 75 deletions(-) create mode 100644 .github/workflows/setup.yml create mode 100644 script/setup.test.js diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml new file mode 100644 index 000000000..d0fade8cd --- /dev/null +++ b/.github/workflows/setup.yml @@ -0,0 +1,15 @@ +name: Test Setup Script + +on: + push: + branches: + - main + pull_request: + +jobs: + setup: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/prepare + - run: pnpm run setup:test diff --git a/package.json b/package.json index 9f247b0e0..d015f9b1b 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "lint:spelling": "cspell \"**\" \".github/**/*\"", "prepare": "husky install", "setup": "npx --yes zx --quiet script/setup.js", + "setup:test": "npx --yes zx --quiet script/setup.test.js", "test": "vitest" }, "type": "module", diff --git a/script/setup.js b/script/setup.js index d752e11f4..6eee23157 100644 --- a/script/setup.js +++ b/script/setup.js @@ -42,6 +42,7 @@ try { owner: { type: "string" }, repository: { type: "string" }, title: { type: "string" }, + "skip-api": { type: "boolean" }, }, tokens: true, strict: false, @@ -80,6 +81,11 @@ try { "How would you describe the new package?" ); + const skipApi = await getPrefillOrPromptedValue( + "skip-api", + "Whether to skip calling the GitHub API (effectively making this a local-only change)." + ); + console.log(); console.log(chalk.gray`Hydrating package metadata locally...`); @@ -118,6 +124,7 @@ try { ["JoshuaKGoldberg", owner], ["template-typescript-node-package", repository], [/"setup": ".*",/, ``, "./package.json"], + [/"setup:test": ".*",/, ``, "./package.json"], [ `"version": "${existingPackage.version}"`, `"version": "0.0.0"`, @@ -159,99 +166,105 @@ try { console.log(chalk.gray`✔️ Done.`); + console.log(chalk.gray`✔️ Done.`); console.log(); - console.log(chalk.gray`Hydrating repository labels...`); - const existingLabels = JSON.parse( - (await $`gh label list --json name`).stdout || "[]" - ); - - for (const outcome of outcomeLabels) { - const action = existingLabels.some( - (existing) => existing.name === outcome.name - ) - ? "edit" - : "create"; - await $`gh label ${action} ${outcome.name} --color ${outcome.color} --description ${outcome.description}`; - } + if (skipApi) { + console.log(chalk.gray`➖ Skipping API hydration.`); + } else { + console.log(chalk.gray`Hydrating repository labels...`); + + const existingLabels = JSON.parse( + (await $`gh label list --json name`).stdout || "[]" + ); + + for (const outcome of outcomeLabels) { + const action = existingLabels.some( + (existing) => existing.name === outcome.name + ) + ? "edit" + : "create"; + await $`gh label ${action} ${outcome.name} --color ${outcome.color} --description ${outcome.description}`; + } + console.log(chalk.gray`✔️ Done.`); - console.log(chalk.gray`✔️ Done.`); + console.log(); + console.log(chalk.gray`Hydrating initial repository settings...`); - console.log(); - console.log(chalk.gray`Hydrating initial repository settings...`); - - const octokit = new Octokit({ auth }); - - octokit.rest.repos.update({ - allow_auto_merge: true, - allow_rebase_merge: false, - allow_squash_merge: true, - default_branch: "main", - delete_branch_on_merge: true, - description, - has_wiki: false, - owner, - repo: repository, - }); + const octokit = new Octokit({ auth }); - console.log(); - console.log(chalk.gray`Hydrating branch protection settings...`); - - // Note: keep this inline script in sync with .github/workflows/release.yml! - // Todo: it would be nice to not have two sources of truth... - // https://github.com/JoshuaKGoldberg/template-typescript-node-package/issues/145 - await octokit.request( - `PUT /repos/${owner}/${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, + octokit.rest.repos.update({ + allow_auto_merge: true, + allow_rebase_merge: false, + allow_squash_merge: true, + default_branch: "main", + delete_branch_on_merge: true, + description, + has_wiki: false, owner, repo: 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: "markdown" }, - { context: "package" }, - { context: "packages" }, - { context: "prettier" }, - { context: "prune" }, - { context: "spelling" }, - { context: "test" }, - ], - strict: false, - }, - restrictions: null, - } - ); - - console.log(chalk.gray`✔️ Done.`); + }); + + console.log(); + console.log(chalk.gray`Hydrating branch protection settings...`); + + // Note: keep this inline script in sync with .github/workflows/release.yml! + // Todo: it would be nice to not have two sources of truth... + // https://github.com/JoshuaKGoldberg/template-typescript-node-package/issues/145 + await octokit.request( + `PUT /repos/${owner}/${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, + repo: 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: "markdown" }, + { context: "package" }, + { context: "packages" }, + { context: "prettier" }, + { context: "prune" }, + { context: "spelling" }, + { context: "test" }, + ], + strict: false, + }, + restrictions: null, + } + ); + + console.log(chalk.gray`✔️ Done.`); + } console.log(); console.log(chalk.gray`Removing setup script...`); await fs.rm("./script", { force: true, recursive: true }); + await fs.rm(".github/workflows/setup.yml"); console.log(chalk.gray`✔️ Done.`); } catch (error) { console.log(chalk.red(error.stack)); caughtError = error; } finally { - console.log(); - console.log( - chalk.gray`Removing devDependency packages only used for setup...` - ); - await $`pnpm remove enquirer octokit replace-in-file -D`; - console.log(chalk.gray`✔️ Done.`); + // console.log(); + // console.log( + // chalk.gray`Removing devDependency packages only used for setup...` + // ); + // await $`pnpm remove enquirer octokit replace-in-file -D`; + // console.log(chalk.gray`✔️ Done.`); } console.log(); diff --git a/script/setup.test.js b/script/setup.test.js new file mode 100644 index 000000000..e20e7cbfe --- /dev/null +++ b/script/setup.test.js @@ -0,0 +1,19 @@ +/* global $ */ + +import { strict as assert } from "node:assert"; + +import { promises as fs } from "fs"; + +const description = "New Description Test"; +const owner = "NewOwnerTest"; +const title = "New Title Test"; +const repository = "new-repository-test"; + +await $`pnpm run setup --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-api`; + +const newPackageJson = JSON.parse( + (await fs.readFile("./package.json")).toString() +); + +assert.equal(newPackageJson.description, description); +assert.equal(newPackageJson.name, repository); From 7af9e86b2d369f7ec76a80664db32ba2bd0e560c Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Fri, 23 Dec 2022 15:34:25 -0500 Subject: [PATCH 2/4] Add back finally --- script/setup.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/script/setup.js b/script/setup.js index 6eee23157..be57beeac 100644 --- a/script/setup.js +++ b/script/setup.js @@ -259,12 +259,12 @@ try { console.log(chalk.red(error.stack)); caughtError = error; } finally { - // console.log(); - // console.log( - // chalk.gray`Removing devDependency packages only used for setup...` - // ); - // await $`pnpm remove enquirer octokit replace-in-file -D`; - // console.log(chalk.gray`✔️ Done.`); + console.log(); + console.log( + chalk.gray`Removing devDependency packages only used for setup...` + ); + await $`pnpm remove enquirer octokit replace-in-file -D`; + console.log(chalk.gray`✔️ Done.`); } console.log(); From dda6f2b57c6f9c52d2c39cd3ae5fc413db5e96d4 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Fri, 23 Dec 2022 15:38:00 -0500 Subject: [PATCH 3/4] A couple e2e fixups --- package.json | 2 +- script/{setup.test.js => setup-test-e2e.js} | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) rename script/{setup.test.js => setup-test-e2e.js} (72%) diff --git a/package.json b/package.json index 541d88a29..e913d1561 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "lint:spelling": "cspell \"**\" \".github/**/*\"", "prepare": "husky install", "setup": "npx --yes zx --quiet script/setup.js", - "setup:test": "npx --yes zx --quiet script/setup.test.js", + "setup:test": "npx --yes zx --quiet script/setup-test-e2e.js", "test": "vitest" }, "type": "module", diff --git a/script/setup.test.js b/script/setup-test-e2e.js similarity index 72% rename from script/setup.test.js rename to script/setup-test-e2e.js index e20e7cbfe..d972a4ae2 100644 --- a/script/setup.test.js +++ b/script/setup-test-e2e.js @@ -9,7 +9,9 @@ const owner = "NewOwnerTest"; const title = "New Title Test"; const repository = "new-repository-test"; -await $`pnpm run setup --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-api`; +const result = + await $`pnpm run setup --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-api`; +console.log({ result }); const newPackageJson = JSON.parse( (await fs.readFile("./package.json")).toString() From 3af6eca89f99c023e6eb2a5e863e1e4e194767ac Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Fri, 23 Dec 2022 15:39:31 -0500 Subject: [PATCH 4/4] Moved auth into conditional block --- script/setup.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/script/setup.js b/script/setup.js index be57beeac..2605f7bfd 100644 --- a/script/setup.js +++ b/script/setup.js @@ -23,18 +23,6 @@ try { ); console.log(); - console.log(chalk.gray`Checking gh auth status...`); - let auth; - try { - await $`gh auth status`; - auth = (await $`gh auth token`).toString().trim(); - } catch (error) { - throw new Error(error.stderr); - } - - console.log(chalk.gray`✔️ Done.`); - console.log(); - const { values } = parseArgs({ args: process.argv.slice(2), options: { @@ -172,6 +160,18 @@ try { if (skipApi) { console.log(chalk.gray`➖ Skipping API hydration.`); } else { + console.log(chalk.gray`Checking gh auth status...`); + let auth; + try { + await $`gh auth status`; + auth = (await $`gh auth token`).toString().trim(); + } catch (error) { + throw new Error(error.stderr); + } + + console.log(chalk.gray`✔️ Done.`); + console.log(); + console.log(chalk.gray`Hydrating repository labels...`); const existingLabels = JSON.parse(