diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml new file mode 100644 index 000000000..b90db4145 --- /dev/null +++ b/.github/workflows/bump-version.yml @@ -0,0 +1,100 @@ +name: Bump BitBurner Version + +on: + workflow_dispatch: + inputs: + version: + description: 'Version (format: x.y.z)' + required: true + versionNumber: + description: 'Version Number (for saves migration)' + required: true + changelog: + description: 'Changelog (url that points to RAW markdown)' + default: '' + buildApp: + description: 'Include Application Build' + type: boolean + default: 'true' + required: true + buildDoc: + description: 'Include Documentation Build' + type: boolean + default: 'true' + required: true + prepareRelease: + description: 'Prepare Draft Release' + type: boolean + default: 'true' + required: true + +jobs: + bumpVersion: + name: Bump Version + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - name: Install pandoc dependency + run: sudo apt-get install -y pandoc + - name: Checkout repository + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Use Node.js 16.13.1 + uses: actions/setup-node@v2 + with: + node-version: 16.13.1 + cache: 'npm' + - name: Install NPM dependencies for version updater + working-directory: ./tools/bump-version + run: npm ci + - name: Bump version & update changelogs + working-directory: ./tools/bump-version + run: | + curl ${{ github.event.inputs.changelog }} > changes.md + node index.js --version=${{ github.event.inputs.version }} --versionNumber=${{ github.event.inputs.versionNumber }} < changes.md + - name: Install NPM dependencies for app + if: ${{ github.event.inputs.buildApp == 'true' || github.event.inputs.buildDoc == 'true' }} + run: npm ci + - name: Build Production App + if: ${{ github.event.inputs.buildApp == 'true' }} + run: npm run build + - name: Build Documentation + if: ${{ github.event.inputs.buildDoc == 'true' }} + run: npm run doc + - name: Commit Files + run: | + git config --global user.name "GitHub" + git config --global user.email "noreply@github.com" + git checkout -b bump/v${{ github.event.inputs.version }} + git add -A + echo "Bump version to v${{ github.event.inputs.version }}" > commitmessage.txt + echo "" >> commitmessage.txt + cat ./tools/bump-version/changes.md >> commitmessage.txt + git commit -F commitmessage.txt + git push -u origin bump/v${{ github.event.inputs.version }} + - name: Create Pull Request + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh pr create \ + --base "${{ github.ref_name }}" \ + --head "bump/v${{ github.event.inputs.version }}" \ + --title "Bump version to v${{ github.event.inputs.version }}" \ + --body-file ./tools/bump-version/changes.md + - name: Prepare release + if: ${{ github.event.inputs.prepareRelease == 'true' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + RELEASE_TITLE="$(head -n 1 ./tools/bump-version/changes.md | sed 's/## //')" + RELEASE_TITLE="${RELEASE_TITLE:-v${{ github.event.inputs.version }}}" + gh release create \ + v${{ github.event.inputs.version }} \ + --target dev \ + --title "$RELEASE_TITLE" \ + --notes-file ./tools/bump-version/changes.md \ + --generate-notes \ + --draft diff --git a/.github/workflows/fetch-changes.yml b/.github/workflows/fetch-changes.yml new file mode 100644 index 000000000..594e8a13b --- /dev/null +++ b/.github/workflows/fetch-changes.yml @@ -0,0 +1,44 @@ +name: Fetch Merged Changes +on: + workflow_dispatch: + inputs: + fromCommit: + description: 'From Commit SHA (full-length)' + required: true + toCommit: + description: 'To Commit SHA (full-length, if omitted will use latest)' + +jobs: + fetchChangelog: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Use Node v16.13.1 + uses: actions/setup-node@v2 + with: + node-version: 16.13.1 + cache: 'npm' + - name: Install NPM dependencies + working-directory: ./tools/fetch-changelog + run: npm ci + - name: Fetch Changes from GitHub API + working-directory: ./tools/fetch-changelog + env: + GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + node index.js \ + --from=${{ github.event.inputs.fromCommit }} \ + --to=${{ github.event.inputs.toCommit }} > changes.md + echo + echo "============================================================" + echo + cat changes.md + echo + echo "============================================================" + echo + echo "You may want to go to https://gist.github.com/ to upload the final changelog" + echo "The next step will require an url because we can't easily pass multiline strings to actions" + - uses: actions/upload-artifact@v2 + with: + name: bitburner_changelog___DRAFT.md + path: ./tools/fetch-changelog/changes.md diff --git a/src/SaveObject.tsx b/src/SaveObject.tsx index d9cae146a..eaa997269 100755 --- a/src/SaveObject.tsx +++ b/src/SaveObject.tsx @@ -22,6 +22,7 @@ import { v1APIBreak } from "./utils/v1APIBreak"; import { AugmentationNames } from "./Augmentation/data/AugmentationNames"; import { PlayerOwnedAugmentation } from "./Augmentation/PlayerOwnedAugmentation"; import { LocationName } from "./Locations/data/LocationNames"; +import { SxProps } from "@mui/system"; /* SaveObject.js * Defines the object used to save/load games @@ -371,6 +372,18 @@ function createScamUpdateText(): void { } } +const resets: SxProps = { + "& h1, & h2, & h3, & h4, & p, & a, & ul": { + margin: 0, + color: Settings.theme.primary, + whiteSpace: "initial", + }, + "& ul": { + paddingLeft: "1.5em", + lineHeight: 1.5, + }, +}; + function createNewUpdateText(): void { setTimeout( () => @@ -379,6 +392,7 @@ function createNewUpdateText(): void { "Please report any bugs/issues through the github repository " + "or the Bitburner subreddit (reddit.com/r/bitburner).

" + CONSTANTS.LatestUpdate, + resets, ), 1000, ); @@ -391,6 +405,7 @@ function createBetaUpdateText(): void { "Please report any bugs/issues through the github repository (https://github.com/danielyxie/bitburner/issues) " + "or the Bitburner subreddit (reddit.com/r/bitburner).

" + CONSTANTS.LatestUpdate, + resets, ); } diff --git a/src/ui/React/DialogBox.tsx b/src/ui/React/DialogBox.tsx index cc96d956f..9ae8035f6 100644 --- a/src/ui/React/DialogBox.tsx +++ b/src/ui/React/DialogBox.tsx @@ -1,11 +1,13 @@ import { AlertEvents } from "./AlertManager"; import React from "react"; +import { SxProps } from "@mui/system"; +import { Typography } from "@mui/material"; -export function dialogBoxCreate(txt: string | JSX.Element): void { +export function dialogBoxCreate(txt: string | JSX.Element, styles?: SxProps): void { if (typeof txt !== "string") { AlertEvents.emit(txt); } else { - AlertEvents.emit(); + AlertEvents.emit(); } } diff --git a/tools/README.md b/tools/README.md index e9cb7e57b..b7fa5e55f 100644 --- a/tools/README.md +++ b/tools/README.md @@ -21,12 +21,28 @@ Used to synchronize the achievements info in steamworks to the game's data.json node fetch-steam-achievements-data.js DEVKEYDEVKEYDEVKEYDEVKEY ``` -## Changelog script +## Fetch Changelog -Used to generate a basic git commit log (in markdown) between commit A & commit B +Used to generate a changelog of merged pull requests & commits between A & B. +The key is a personnal access token, from https://github.com/settings/tokens. +It requires the "gist" scope as the result is pushed to a secret gist. **Usage** ```sh -# Will default to HEAD if second is not specified. -./tools/changelog.sh 9a0062b 05cbc25 +cd ./tools/fetch-changelog +npm install +export GITHUB_API_TOKEN=tokenhere # this could go into your .bashrc or .profile etc. +node index.js --from=31ebdbb139981a604bd0e8fc1e364916762e11b9 > ../bump-version/changes.md +``` + +## Bump Version + +Used to update the game's various version identifier. +Requires pandoc installed to convert .md to .rst + +**Usage** +```sh +cd ./tools/bump-version +npm install +node index.js --version=1.10.3 --versionNumber=10 < changes.md ``` diff --git a/tools/bump-version/.gitignore b/tools/bump-version/.gitignore new file mode 100644 index 000000000..4764e2f2e --- /dev/null +++ b/tools/bump-version/.gitignore @@ -0,0 +1,2 @@ +node_modules +*.md diff --git a/tools/bump-version/index.js b/tools/bump-version/index.js new file mode 100644 index 000000000..8464bc189 --- /dev/null +++ b/tools/bump-version/index.js @@ -0,0 +1,118 @@ +// import { Octokit } from "@octokit/rest"; +import commandLineArgs from "command-line-args"; + +import fs from 'fs/promises'; +import { readFileSync } from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import pandoc from 'node-pandoc'; + +// https://github.com/75lb/command-line-args +const optionDefinitions = [ + { name: 'version', alias: 'v', type: String, required: true }, + { name: 'versionNumber', alias: 'n', type: Number }, + { name: 'versionDescription', alias: 'd', type: String }, + { name: 'changelog', alias: 'l', type: String }, +]; + +const cliArgs = commandLineArgs(optionDefinitions); + +const appPaths = {}; +appPaths.root = path.join(path.dirname(fileURLToPath(import.meta.url)), "../.."); +appPaths.mainPackage = path.join(appPaths.root, "./package.json"); +appPaths.electronPackage = path.join(appPaths.root, "./electron/package.json"); +appPaths.constants = path.join(appPaths.root, "./src/Constants.ts"); +appPaths.sphinxConf = path.join(appPaths.root, "./doc/source/conf.py"); +appPaths.sphinxChangelog = path.join(appPaths.root, "./doc/source/changelog.rst"); + +async function main(version, versionNumber, changelog) { + console.log(`Updating app files to match v${version}`); + + const [ major, minor ]= version.split('.'); + const shortVersion = `${major}.${minor}`; + const modifiedMainPackage = (await fs.readFile(appPaths.mainPackage, 'utf8')). + replace(/(^\s*"version":\s)"(.*)",$/m, `$1"${version}",`); + await fs.writeFile(appPaths.mainPackage, modifiedMainPackage); + console.log(`Modified ${appPaths.mainPackage}`); + + const modifiedElectronPackage = (await fs.readFile(appPaths.electronPackage, 'utf8')). + replace(/(^\s*"version":\s)"(.*)",$/m, `$1"${version}",`); + await fs.writeFile(appPaths.electronPackage, modifiedElectronPackage); + console.log(`Modified ${appPaths.electronPackage}`); + + let modifiedConstants = (await fs.readFile(appPaths.constants, 'utf8')). + replace(/(^\s*?VersionString:\s)"(.*)",/m, `$1"${version}",`); + modifiedConstants = modifiedConstants. + replace(/(^\s*?VersionNumber:\s)(.*),/m, `$1${versionNumber},`); + + if (changelog.trim() !== '') { + let htmlChangelog = ''; + try { + htmlChangelog = await transform(changelog, 'html'); + console.log('Converted markdown changelog to html') + } catch (error) { + console.error(error); + } + + const paddedChangelog = htmlChangelog.split('\n'). + map((line) => (line.trim() !== '' ? ' ' + line : '')). + join('\n').replaceAll('`', '\\`'); + + modifiedConstants = modifiedConstants. + replace(/(^\s*?LatestUpdate:\s`\n)(.*)`,$/ms, `$1${paddedChangelog}\n` + "`,"); + } + await fs.writeFile(appPaths.constants, modifiedConstants); + console.log(`Modified ${appPaths.constants}`); + + let modifiedSphinxConfig = (await fs.readFile(appPaths.sphinxConf, 'utf8')). + replace(/(^version = ')(.*)'$/m, `$1${shortVersion}'`); + modifiedSphinxConfig = modifiedSphinxConfig. + replace(/(^release = ')(.*)'$/m, `$1${version}'`); + await fs.writeFile(appPaths.sphinxConf, modifiedSphinxConfig); + console.log(`Modified ${appPaths.sphinxConf}`); + + if (changelog.trim() !== '') { + let modifiedSphinxChangelog = await fs.readFile(appPaths.sphinxChangelog, 'utf8'); + const lines = modifiedSphinxChangelog.split('\n'); + let rstChangelog = ''; + try { + rstChangelog = await transform(changelog, 'rst'); + console.log('Converted markdown changelog to rst') + } catch (error) { + console.error(error); + } + + lines.splice(5, 0, rstChangelog); + modifiedSphinxChangelog = lines.join('\n'); + await fs.writeFile(appPaths.sphinxChangelog, modifiedSphinxChangelog); + console.log(`Modified ${appPaths.sphinxChangelog}`); + } +} + +async function transform(markdown, format) { + return new Promise((resolve, reject) => { + const args = `-f markdown -t ${format}`; + pandoc(markdown, args, (error, rst) => { + if (error) { + reject(error); + } else { + resolve(rst); + } + }); + }); +} + +async function getChangelog() { + // Read from stdin + // https://stackoverflow.com/a/56012724 + try { + return readFileSync(0, 'utf-8').replace('\r\n', '\n'); + } catch (error) { + return ''; + } +} + +getChangelog().then((changes) => { + main(cliArgs.version, cliArgs.versionNumber, changes).then(() => console.log('Done')); +}) + diff --git a/tools/bump-version/package-lock.json b/tools/bump-version/package-lock.json new file mode 100644 index 000000000..d9632a14b --- /dev/null +++ b/tools/bump-version/package-lock.json @@ -0,0 +1,109 @@ +{ + "name": "update-version", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "update-version", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "command-line-args": "^5.2.0", + "node-pandoc": "^0.3.0" + } + }, + "node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/command-line-args": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.0.tgz", + "integrity": "sha512-4zqtU1hYsSJzcJBOcNZIbW5Fbk9BkjCp1pZVhQKoRaWL5J7N4XphDLwo8aWwdQpTugxwu+jf9u2ZhkXiqp5Z6A==", + "dependencies": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, + "node_modules/node-pandoc": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/node-pandoc/-/node-pandoc-0.3.0.tgz", + "integrity": "sha1-1GV3zQpyr0FTU/y4oBF622JC+cg=" + }, + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "engines": { + "node": ">=8" + } + } + }, + "dependencies": { + "array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==" + }, + "command-line-args": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.0.tgz", + "integrity": "sha512-4zqtU1hYsSJzcJBOcNZIbW5Fbk9BkjCp1pZVhQKoRaWL5J7N4XphDLwo8aWwdQpTugxwu+jf9u2ZhkXiqp5Z6A==", + "requires": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + } + }, + "find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "requires": { + "array-back": "^3.0.1" + } + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, + "node-pandoc": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/node-pandoc/-/node-pandoc-0.3.0.tgz", + "integrity": "sha1-1GV3zQpyr0FTU/y4oBF622JC+cg=" + }, + "typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==" + } + } +} diff --git a/tools/bump-version/package.json b/tools/bump-version/package.json new file mode 100644 index 000000000..c40bdde24 --- /dev/null +++ b/tools/bump-version/package.json @@ -0,0 +1,16 @@ +{ + "name": "update-version", + "version": "1.0.0", + "type": "module", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "command-line-args": "^5.2.0", + "node-pandoc": "^0.3.0" + } +} diff --git a/tools/changelog.sh b/tools/changelog.sh deleted file mode 100644 index 11d59b7fa..000000000 --- a/tools/changelog.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -version=${2:-HEAD} -cat >> temp_changelog.md << EOF -# v1.X.X ($version) - -Description Here. - -Compare Commits [on github](https://github.com/danielyxie/bitburner/compare/$1...$version). - ---- - -### Commits -EOF - -git log $1...${version} \ - --pretty=format:'* [`%h`]([https://github.com/danielyxie/bitburner/commit/%H): %s (by %aN on %ad) %n' \ - --date=short \ - --no-merges >> temp_changelog.md - # --reverse >> temp_changelog.md - -rm -f changelog_$1_${version}.md -mv temp_changelog.md changelog_$1_${version}.md diff --git a/tools/fetch-changelog/.gitignore b/tools/fetch-changelog/.gitignore new file mode 100644 index 000000000..3e7196636 --- /dev/null +++ b/tools/fetch-changelog/.gitignore @@ -0,0 +1,3 @@ +node_modules + +*.md diff --git a/tools/fetch-changelog/index.js b/tools/fetch-changelog/index.js new file mode 100644 index 000000000..5aa14d1c7 --- /dev/null +++ b/tools/fetch-changelog/index.js @@ -0,0 +1,240 @@ +import { Octokit } from "@octokit/rest"; +import commandLineArgs from "command-line-args"; + +const owner = "danielyxie"; +const repo = "bitburner" +const basePath = `https://github.com/${owner}/${repo}`; + +const cliArgs = commandLineArgs([ + { name: 'from', alias: 'f', type: String }, + { name: 'to', alias: 't', type: String }, + { name: 'detailed', alias: 'd', type: Boolean } +]); + +class MergeChangelog { + constructor(options) { + this.octokit = new Octokit(options); + } + + async getCommitsSearchResults(query) { + const iterator = this.octokit.paginate.iterator( + this.octokit.rest.search.commits, + { + owner, repo, + q: query, + sort: 'updated', + direction: 'desc', + }, + ); + const searchResults = []; + for await (const response of iterator) { + const entries = response.data.map((entry) => ({ + sha: entry.sha, + url: entry.html_url, + user: { + id: entry.author.id, + login: entry.author.login, + avatar: entry.author.avatar_url, + url: entry.author.html_url, + }, + commit_date: entry.commit.committer.date, + message: entry.commit.message, + })); + searchResults.push(...entries); + } + return searchResults; + } + + async getPullsSearchResults(query) { + const iterator = this.octokit.paginate.iterator( + this.octokit.rest.search.issuesAndPullRequests, + { + owner, repo, + q: query, + sort: 'committer-date', + direction: 'desc', + }, + ); + + const searchResults = []; + for await (const response of iterator) { + const entries = response.data.map((entry) => ({ + id: entry.id, + number: entry.number, + created_at: entry.updated_at, + merged_at: entry.pull_request.merged_at, + url: entry.pull_request.html_url, + title: entry.title, + body: entry.body, + diff: entry.diff_url, + patch: entry.patch_url, + user: { + id: entry.user.id, + login: entry.user.login, + avatar: entry.user.avatar_url, + url: entry.user.html_url, + }, + })); + searchResults.push(...entries); + } + + const pullRequestPromises = []; + for (const entry of searchResults) { + pullRequestPromises.push( + this.octokit.rest.pulls.get({ + owner, repo, + pull_number: entry.number, + }).then((response) => ({ + ...entry, + merge_commit_sha: response.data.merge_commit_sha, + head_commit_sha: response.data.head.sha, + }))); + } + + const pulls = await Promise.all(pullRequestPromises); + return pulls; + } + + async getCommit(sha) { + const response = await this.octokit.rest.git.getCommit({ + owner, repo, + commit_sha: sha, + }); + const commit = { + date: response.data.committer.date, + message: response.data.message, + sha: response.data.sha, + url: response.data.html_url, + } + return commit; + } + + async getPullsMergedBetween(sha_from, sha_to) { + const from = {}; + const to = {}; + from.commit = await this.getCommit(sha_from); + from.date = new Date(from.commit.date); + + if (!sha_to) { + const newest = await this.getLastCommitByBranch('dev'); + to.commit = await this.getCommit(newest) + } else { + to.commit = await this.getCommit(sha_to); + } + + to.date = new Date(to.commit.date); + + const commitQuery = `user:${owner} repo:${repo} merge:false committer-date:"${from.date.toISOString()}..${to.date.toISOString()}"`; + const pullQuery = `user:${owner} repo:${repo} is:pr is:merged merged:"${from.date.toISOString()}..${to.date.toISOString()}"`; + + const commits = await this.getCommitsSearchResults(commitQuery); + const pulls = await this.getPullsSearchResults(pullQuery); + + // We only have the merge commit sha & the HEAD sha in this data, but it can exclude some entries + const pullsCommitSha = pulls. + map((p) => [p.merge_commit_sha, p.head_commit_sha]). + reduce((all, current) => [...all, ...current]); + + let danglingCommits = commits.filter((c) => !pullsCommitSha.includes(c.sha)); + const listPullsPromises = []; + for (const commit of danglingCommits) { + const promise = this.octokit.rest.repos.listPullRequestsAssociatedWithCommit({ + owner, repo, commit_sha: commit.sha + }).then((response) => ({ + ...commit, + nbPulls: response.data.length, + })); + listPullsPromises.push(promise); + } + + const commitsThatAreIncludedInPulls = (await Promise.all(listPullsPromises)). + filter((c) => c.nbPulls > 0). + map((c) => c.sha); + + danglingCommits = danglingCommits. + filter((c) => !commitsThatAreIncludedInPulls.includes(c.sha)); + return { + from, + to, + pulls, + danglingCommits, + pullQuery, + commitQuery, + } + } + + async getLastCommitByBranch(branch) { + const response = await this.octokit.rest.repos.getBranch({ + owner, + repo, + branch, + }); + return response.data.commit.sha; + } + + async getChangelog(from, to, detailedOutput) { + const changes = await this.getPullsMergedBetween(from, to); + const pullLines = changes.pulls.map((line) => this.getPullMarkdown(line, detailedOutput)); + const commitLines = changes.danglingCommits.map((line) => this.getCommitMarkdown(line, detailedOutput)); + commitLines.push(`* Nerf noodle bar.`) + const shortFrom = changes.from.date.toISOString().split('T')[0]; + const shortTo = changes.to.date.toISOString().split('T')[0] + const shortFromSha = changes.from.commit.sha.slice(0, 7); + const shortToSha = changes.to.commit.sha.slice(0, 7); + const title = `## [draft] v1.x.x - ${shortFrom} to ${shortTo}`; + let log = ` +${title} + +#### Information + +Modifications included between **${shortFrom}** and **${shortTo}** (\`${shortFromSha}\` to \`${shortToSha}\`). + +*[See Pull Requests on GitHub](https://github.com/search?q=${encodeURIComponent(changes.pullQuery)})* + +#### Merged Pull Requests + +${pullLines.join('\n')} + +`; + + if (commitLines.length > 0) { + log += ` +#### Other Changes + +${commitLines.join('\n')} +`; + } + return { + log: log.trim(), + changes: changes, + }; + } + + getPullMarkdown(pr, detailedOutput) { + if (!detailedOutput) { + return `* ` + + `${pr.title} (by @${pr.user.login})` + + ` #[${pr.number}](${pr.url})`; + } else { + return `* [${pr.merge_commit_sha.slice(0, 7)}](${basePath}/commit/${pr.merge_commit_sha}) | ` + + `${pr.title} ([@${pr.user.login}](${pr.user.url}))` + + ` PR #[${pr.number}](${pr.url})`; + } + } + + getCommitMarkdown(commit, detailedOutput) { + if (!detailedOutput) { + return `* ` + + `${commit.message} (by @${commit.user.login})` + + ` - [${commit.sha.slice(0, 7)}](${commit.url})`; + } else { + return `* [${commit.sha.slice(0, 7)}](${commit.url}) | ` + + `${commit.message} ([@${commit.user.login}](${commit.user.url}))`; + } + } +} + +const api = new MergeChangelog({ auth: process.env.GITHUB_API_TOKEN }); +api.getChangelog(cliArgs.from, cliArgs.to, cliArgs.detailed).then((data) => { + console.log(data.log); +}); diff --git a/tools/fetch-changelog/package-lock.json b/tools/fetch-changelog/package-lock.json new file mode 100644 index 000000000..b4a7062e0 --- /dev/null +++ b/tools/fetch-changelog/package-lock.json @@ -0,0 +1,465 @@ +{ + "name": "fetch-changelog", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "fetch-changelog", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@octokit/rest": "^18.12.0", + "command-line-args": "^5.2.0" + } + }, + "node_modules/@octokit/auth-token": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", + "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", + "dependencies": { + "@octokit/types": "^6.0.3" + } + }, + "node_modules/@octokit/core": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz", + "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==", + "dependencies": { + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.0", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "dependencies": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/graphql": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", + "dependencies": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz", + "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz", + "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==", + "dependencies": { + "@octokit/types": "^6.34.0" + }, + "peerDependencies": { + "@octokit/core": ">=2" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz", + "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==", + "dependencies": { + "@octokit/types": "^6.34.0", + "deprecation": "^2.3.1" + }, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/request": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", + "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", + "dependencies": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "dependencies": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "node_modules/@octokit/rest": { + "version": "18.12.0", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz", + "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==", + "dependencies": { + "@octokit/core": "^3.5.1", + "@octokit/plugin-paginate-rest": "^2.16.8", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^5.12.0" + } + }, + "node_modules/@octokit/types": { + "version": "6.34.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz", + "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==", + "dependencies": { + "@octokit/openapi-types": "^11.2.0" + } + }, + "node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/before-after-hook": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", + "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==" + }, + "node_modules/command-line-args": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.0.tgz", + "integrity": "sha512-4zqtU1hYsSJzcJBOcNZIbW5Fbk9BkjCp1pZVhQKoRaWL5J7N4XphDLwo8aWwdQpTugxwu+jf9u2ZhkXiqp5Z6A==", + "dependencies": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + }, + "dependencies": { + "@octokit/auth-token": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", + "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", + "requires": { + "@octokit/types": "^6.0.3" + } + }, + "@octokit/core": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz", + "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==", + "requires": { + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.0", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "requires": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/graphql": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", + "requires": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/openapi-types": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz", + "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==" + }, + "@octokit/plugin-paginate-rest": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz", + "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==", + "requires": { + "@octokit/types": "^6.34.0" + } + }, + "@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "requires": {} + }, + "@octokit/plugin-rest-endpoint-methods": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz", + "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==", + "requires": { + "@octokit/types": "^6.34.0", + "deprecation": "^2.3.1" + } + }, + "@octokit/request": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", + "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", + "requires": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "requires": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/rest": { + "version": "18.12.0", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz", + "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==", + "requires": { + "@octokit/core": "^3.5.1", + "@octokit/plugin-paginate-rest": "^2.16.8", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^5.12.0" + } + }, + "@octokit/types": { + "version": "6.34.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz", + "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==", + "requires": { + "@octokit/openapi-types": "^11.2.0" + } + }, + "array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==" + }, + "before-after-hook": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", + "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==" + }, + "command-line-args": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.0.tgz", + "integrity": "sha512-4zqtU1hYsSJzcJBOcNZIbW5Fbk9BkjCp1pZVhQKoRaWL5J7N4XphDLwo8aWwdQpTugxwu+jf9u2ZhkXiqp5Z6A==", + "requires": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + } + }, + "deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, + "find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "requires": { + "array-back": "^3.0.1" + } + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==" + }, + "universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + } +} diff --git a/tools/fetch-changelog/package.json b/tools/fetch-changelog/package.json new file mode 100644 index 000000000..1b6eb595d --- /dev/null +++ b/tools/fetch-changelog/package.json @@ -0,0 +1,16 @@ +{ + "name": "fetch-changelog", + "version": "1.0.0", + "type": "module", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "@octokit/rest": "^18.12.0", + "command-line-args": "^5.2.0" + } +}