diff --git a/.changeset/config.json b/.changeset/config.json index 2d5ade70dcb..1646a33836b 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,6 +1,6 @@ { "$schema": "https://unpkg.com/@changesets/config@1.1.0/schema.json", - "changelog": ["@changesets/changelog-github", { "repo": "firebase/firebase-js-sdk"}], + "changelog": ["../repo-scripts/changelog-generator", { "repo": "firebase/firebase-js-sdk"}], "commit": false, "linked": [], "access": "public", diff --git a/package.json b/package.json index 8c8b9402310..7470b849037 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,8 @@ "lint": "lerna run --scope @firebase/* --scope rxfire lint", "size-report": "node scripts/report_binary_size.js", "api-report": "lerna run --scope @firebase/*-exp api-report", - "docgen:exp": "node scripts/exp/docgen.js" + "docgen:exp": "node scripts/exp/docgen.js", + "postinstall": "yarn --cwd repo-scripts/changelog-generator build" }, "repository": { "type": "git", @@ -57,7 +58,8 @@ "workspaces": [ "packages/*", "packages-exp/*", - "integration/*" + "integration/*", + "repo-scripts/*" ], "devDependencies": { "@changesets/changelog-github": "0.2.6", diff --git a/repo-scripts/changelog-generator/.eslintrc.js b/repo-scripts/changelog-generator/.eslintrc.js new file mode 100644 index 00000000000..ca80aa0f69a --- /dev/null +++ b/repo-scripts/changelog-generator/.eslintrc.js @@ -0,0 +1,26 @@ +/** + * @license + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module.exports = { + extends: '../../config/.eslintrc.js', + parserOptions: { + project: 'tsconfig.json', + // to make vscode-eslint work with monorepo + // https://github.com/typescript-eslint/typescript-eslint/issues/251#issuecomment-463943250 + tsconfigRootDir: __dirname + } +}; diff --git a/repo-scripts/changelog-generator/README.md b/repo-scripts/changelog-generator/README.md new file mode 100644 index 00000000000..a5d605b7973 --- /dev/null +++ b/repo-scripts/changelog-generator/README.md @@ -0,0 +1,3 @@ +# @firebase/changelog-generator + +It works as a plugin for @changesets/cli to generate changelog entries(via running `changeset version`). diff --git a/repo-scripts/changelog-generator/index.ts b/repo-scripts/changelog-generator/index.ts new file mode 100644 index 00000000000..d23b90c3aec --- /dev/null +++ b/repo-scripts/changelog-generator/index.ts @@ -0,0 +1,110 @@ +/** + * @license + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ChangelogFunctions } from '@changesets/types'; +import { getInfo } from '@changesets/get-github-info'; +import fetch from 'node-fetch'; + +const changelogFunctions: ChangelogFunctions = { + getDependencyReleaseLine: async ( + changesets, + dependenciesUpdated, + options + ) => { + if (!options.repo) { + throw new Error( + 'Please provide a repo to this changelog generator like this:\n"changelog": ["@changesets/changelog-github", { "repo": "org/repo" }]' + ); + } + if (dependenciesUpdated.length === 0) return ''; + + const changesetLink = `- Updated dependencies [${( + await Promise.all( + changesets.map(async cs => { + if (cs.commit) { + let { links } = await getInfo({ + repo: options.repo, + commit: cs.commit + }); + return links.commit; + } + }) + ) + ) + .filter(_ => _) + .join(', ')}]:`; + + const updatedDepenenciesList = dependenciesUpdated.map( + dependency => ` - ${dependency.name}@${dependency.newVersion}` + ); + + return [changesetLink, ...updatedDepenenciesList].join('\n'); + }, + getReleaseLine: async (changeset, type, options) => { + if (!options || !options.repo) { + throw new Error( + 'Please provide a repo to this changelog generator like this:\n"changelog": ["@changesets/changelog-github", { "repo": "org/repo" }]' + ); + } + const [firstLine, ...futureLines] = changeset.summary + .split('\n') + .map(l => l.trimRight()); + + if (changeset.commit) { + let { pull: pullNumber, links } = await getInfo({ + repo: options.repo, + commit: changeset.commit + }); + + let fixedIssueLink = null; + // If the summary didn't mention any issue, we will look at the PR body to try to generate one automatically + if (!/issues\/[\d+]/i.test(changeset.summary) && pullNumber) { + fixedIssueLink = await getFixedIssueLink(pullNumber, options.repo); + } + + return `\n\n- ${links.commit}${ + links.pull === null ? '' : ` ${links.pull}` + }${ + fixedIssueLink === null ? '' : ` ${fixedIssueLink}` + } - ${firstLine}\n${futureLines.map(l => ` ${l}`).join('\n')}`; + } else { + return `\n\n- ${firstLine}\n${futureLines.map(l => ` ${l}`).join('\n')}`; + } + } +}; + +const fixedIssueRegex = /(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved) [^\s]*(#|issues\/)([\d]+)/i; +async function getFixedIssueLink( + prNumber: number, + repo: string +): Promise { + const { body }: { body: string } = await fetch( + `https://api.github.com/repos/${repo}/pulls/${prNumber}?access_token=${process.env.GITHUB_TOKEN}`, + { + method: 'GET' + } + ).then(data => data.json()); + + const match = fixedIssueRegex.exec(body); + if (!match) { + return ''; + } + const issueNumber = match[3]; + return `(fixes [#${issueNumber}](https://github.com/firebase/firebase-js-sdk/issues/${issueNumber}))`; +} + +exports.default = changelogFunctions; diff --git a/repo-scripts/changelog-generator/package.json b/repo-scripts/changelog-generator/package.json new file mode 100644 index 00000000000..7a5331741f4 --- /dev/null +++ b/repo-scripts/changelog-generator/package.json @@ -0,0 +1,43 @@ +{ + "name": "@firebase/changelog-generator", + "version": "0.1.0", + "private": true, + "description": "A package for generating changelog", + "author": "Firebase (https://firebase.google.com/)", + "main": "dist/index.js", + "files": [ + "dist" + ], + "scripts": { + "lint": "eslint -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'", + "lint:fix": "eslint --fix -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'", + "build": "tsc", + "build:dev": "tsc -w", + "test": "yarn type-check", + "prepare": "yarn build" + }, + "dependencies": { + "@changesets/types": "3.1.0", + "@changesets/get-github-info": "0.4.3", + "node-fetch": "2.6.0", + "@types/node-fetch": "2.5.7" + }, + "license": "Apache-2.0", + "devDependencies": { + "typescript": "3.9.6" + }, + "repository": { + "directory": "repo-scripts/changelog-generator", + "type": "git", + "url": "https://github.com/firebase/firebase-js-sdk.git" + }, + "bugs": { + "url": "https://github.com/firebase/firebase-js-sdk/issues" + }, + "nyc": { + "extension": [ + ".ts" + ], + "reportDir": "./coverage/node" + } +} diff --git a/repo-scripts/changelog-generator/tsconfig.json b/repo-scripts/changelog-generator/tsconfig.json new file mode 100644 index 00000000000..35a1f5fcced --- /dev/null +++ b/repo-scripts/changelog-generator/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "strict": true, + "outDir": "dist", + "lib": [ + "ESNext" + ], + "module": "CommonJS", + "moduleResolution": "node", + "esModuleInterop": true, + "resolveJsonModule": true, + "target": "es5", + "typeRoots": [ + "../../node_modules/@types" + ] + } +} \ No newline at end of file diff --git a/scripts/exp/docgen.js b/scripts/exp/docgen.js index af6cb23b1fc..96d4f63696b 100644 --- a/scripts/exp/docgen.js +++ b/scripts/exp/docgen.js @@ -38,7 +38,7 @@ async function generateDocs() { fs.mkdirSync(tmpDir); } - // TODO: Throw error if path doesn't exist, once all packages add markdown support. + // TODO: Throw error if path doesn't exist once all packages add markdown support. const apiJsonDirectories = ( await mapWorkspaceToPackages([ `${projectRoot}/packages/*`, diff --git a/yarn.lock b/yarn.lock index a8923b24a96..d76b22c3bd6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1141,7 +1141,7 @@ fs-extra "^7.0.1" semver "^5.4.1" -"@changesets/get-github-info@^0.4.3": +"@changesets/get-github-info@0.4.3", "@changesets/get-github-info@^0.4.3": version "0.4.3" resolved "https://registry.npmjs.org/@changesets/get-github-info/-/get-github-info-0.4.3.tgz#ed3c3ca76dcbaf4c98aa950a20fc5438da1a2f2c" integrity sha512-hMtNDn4Kp2wDUohYipBIH3qGMxONZ3wEoaGtrflXHCSu57iulBcOSQ1oHRYSCJ9pO87dYQHA2XRUfrZUnqRfKA== @@ -1219,16 +1219,16 @@ fs-extra "^7.0.1" p-filter "^2.1.0" +"@changesets/types@3.1.0", "@changesets/types@^3.1.0": + version "3.1.0" + resolved "https://registry.npmjs.org/@changesets/types/-/types-3.1.0.tgz#68957af45a0be29f0908e20a990ecf382282e1f1" + integrity sha512-czOfaaxr5aGnNwVRgWr3n2CKoc3iRTfrHM4wUHQ+rBlLKKk9NzGwZ2EPsXkp4CUw4hWHGEOi8hdeIfDTWKrWgg== + "@changesets/types@^3.0.0": version "3.0.0" resolved "https://registry.npmjs.org/@changesets/types/-/types-3.0.0.tgz#3804662aa455c1622282ec3253cf6ddd309eee65" integrity sha512-9Mh/JqkX3nkjfu53ESM3UjFmR2meOo4Zw+Tp4vnon0XYtMurk7KjZG5L+J0fD3+Qx0A2FFTZrgydPwiHR4GrXQ== -"@changesets/types@^3.1.0": - version "3.1.0" - resolved "https://registry.npmjs.org/@changesets/types/-/types-3.1.0.tgz#68957af45a0be29f0908e20a990ecf382282e1f1" - integrity sha512-czOfaaxr5aGnNwVRgWr3n2CKoc3iRTfrHM4wUHQ+rBlLKKk9NzGwZ2EPsXkp4CUw4hWHGEOi8hdeIfDTWKrWgg== - "@changesets/write@^0.1.3": version "0.1.3" resolved "https://registry.npmjs.org/@changesets/write/-/write-0.1.3.tgz#00ae575af50274773d7493e77fb96838a08ad8ad" @@ -2620,6 +2620,14 @@ resolved "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz#b17f16cf933597e10d6d78eae3251e692ce8b0ce" integrity sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w== +"@types/node-fetch@2.5.7": + version "2.5.7" + resolved "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c" + integrity sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + "@types/node@*", "@types/node@>= 8": version "13.11.0" resolved "https://registry.npmjs.org/@types/node/-/node-13.11.0.tgz#390ea202539c61c8fa6ba4428b57e05bc36dc47b" @@ -4858,7 +4866,7 @@ combine-source-map@^0.8.0, combine-source-map@~0.8.0: lodash.memoize "~3.0.3" source-map "~0.5.3" -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -7090,6 +7098,15 @@ form-data@^2.5.0: combined-stream "^1.0.6" mime-types "^2.1.12" +form-data@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" + integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -14195,7 +14212,6 @@ symbol-observable@^1.1.0: "sync-promise@git+https://github.com/brettz9/sync-promise.git#full-sync-missing-promise-features": version "1.0.1" - uid "25845a49a00aa2d2c985a5149b97c86a1fcdc75a" resolved "git+https://github.com/brettz9/sync-promise.git#25845a49a00aa2d2c985a5149b97c86a1fcdc75a" syntax-error@^1.1.1: @@ -15509,7 +15525,6 @@ websocket-extensions@>=0.1.1: "websql@git+https://github.com/brettz9/node-websql.git#configurable-secure2": version "1.0.0" - uid "5149bc0763376ca757fc32dc74345ada0467bfbb" resolved "git+https://github.com/brettz9/node-websql.git#5149bc0763376ca757fc32dc74345ada0467bfbb" dependencies: argsarray "^0.0.1"