From c367de24a8924f731227c386d1bd67e6b59dacf1 Mon Sep 17 00:00:00 2001 From: Martin Fournier Date: Fri, 21 Jan 2022 14:46:55 -0500 Subject: [PATCH 1/3] Add tool & workflow to fetch changelog Rewrote the changelog script to use primarily merged pull requests between "commit A" and "commit B". It uses the GitHub rest api. The resulting data is pushed to a draft gist. Manual usage is in the README. Also adds a GitHub workflow action to run the tool on demand, through the GitHub action's interface. --- .github/workflows/fetch-changes.yml | 44 +++ tools/README.md | 12 +- tools/changelog.sh | 23 -- tools/fetch-changelog/.gitignore | 3 + tools/fetch-changelog/index.js | 240 ++++++++++++ tools/fetch-changelog/package-lock.json | 465 ++++++++++++++++++++++++ tools/fetch-changelog/package.json | 16 + 7 files changed, 776 insertions(+), 27 deletions(-) create mode 100644 .github/workflows/fetch-changes.yml delete mode 100644 tools/changelog.sh create mode 100644 tools/fetch-changelog/.gitignore create mode 100644 tools/fetch-changelog/index.js create mode 100644 tools/fetch-changelog/package-lock.json create mode 100644 tools/fetch-changelog/package.json 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/tools/README.md b/tools/README.md index e9cb7e57b..fb62f846f 100644 --- a/tools/README.md +++ b/tools/README.md @@ -21,12 +21,16 @@ 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 ``` 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" + } +} From c4ddb5ef643a885a68e9e6add549896318c05490 Mon Sep 17 00:00:00 2001 From: Martin Fournier Date: Sat, 22 Jan 2022 06:52:57 -0500 Subject: [PATCH 2/3] Add tool to bump version & create PR This includes a tool to update the various files in the repo that need to change when a version increments. It also includes a workflow to trigger the action manually, passing it a version & a changelog url. It'll update the values, build the app, build the doc, make a commit in a branch, and create a pull request to merge this stuff back into dev. --- .github/workflows/bump-version.yml | 100 +++++++++++++++++++++++ tools/README.md | 12 +++ tools/bump-version/.gitignore | 2 + tools/bump-version/index.js | 118 +++++++++++++++++++++++++++ tools/bump-version/package-lock.json | 109 +++++++++++++++++++++++++ tools/bump-version/package.json | 16 ++++ 6 files changed, 357 insertions(+) create mode 100644 .github/workflows/bump-version.yml create mode 100644 tools/bump-version/.gitignore create mode 100644 tools/bump-version/index.js create mode 100644 tools/bump-version/package-lock.json create mode 100644 tools/bump-version/package.json 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/tools/README.md b/tools/README.md index fb62f846f..b7fa5e55f 100644 --- a/tools/README.md +++ b/tools/README.md @@ -34,3 +34,15 @@ 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" + } +} From 8a2cad6c4a54bfccf2ee11373a331644fee309c0 Mon Sep 17 00:00:00 2001 From: Martin Fournier Date: Tue, 25 Jan 2022 08:16:48 -0500 Subject: [PATCH 3/3] Reset styles for html changelogs in getUpdateText Adds an optional sxProps to the DialogBox component. --- src/SaveObject.tsx | 15 +++++++++++++++ src/ui/React/DialogBox.tsx | 6 ++++-- 2 files changed, 19 insertions(+), 2 deletions(-) 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(); } }