diff --git a/development/auto-changelog.js b/development/auto-changelog.js deleted file mode 100755 index 455bf5beb..000000000 --- a/development/auto-changelog.js +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env node -const fs = require('fs').promises; - -const path = require('path'); -const { version } = require('../app/manifest/_base.json'); -const { updateChangelog } = require('./lib/changelog/updateChangelog'); -const { unreleased } = require('./lib/changelog/constants'); - -const REPO_URL = 'https://github.com/MetaMask/metamask-extension'; - -const command = 'yarn update-changelog'; - -const helpText = `Usage: ${command} [--rc] [-h|--help] -Update CHANGELOG.md with any changes made since the most recent release. - -Options: - --rc Add new changes to the current release header, rather than to the - '${unreleased}' section. - -h, --help Display this help and exit. - -New commits will be added to the "${unreleased}" section (or to the section for the -current release if the '--rc' flag is used) in reverse chronological order. Any -commits for PRs that are represented already in the changelog will be ignored. - -If the '--rc' flag is used and the section for the current release does not yet -exist, it will be created. -`; - -async function main() { - const args = process.argv.slice(2); - let isReleaseCandidate = false; - - for (const arg of args) { - if (arg === '--rc') { - isReleaseCandidate = true; - } else if (['--help', '-h'].includes(arg)) { - console.log(helpText); - process.exit(0); - } else { - console.error( - `Unrecognized argument: ${arg}\nTry '${command} --help' for more information.\n`, - ); - process.exit(1); - } - } - - const changelogFilename = path.resolve(__dirname, '..', 'CHANGELOG.md'); - const changelogContent = await fs.readFile(changelogFilename, { - encoding: 'utf8', - }); - - const newChangelogContent = await updateChangelog({ - changelogContent, - currentVersion: version, - repoUrl: REPO_URL, - isReleaseCandidate, - }); - - await fs.writeFile(changelogFilename, newChangelogContent); - - console.log('CHANGELOG updated'); -} - -main().catch((error) => { - console.error(error); - process.exit(1); -}); diff --git a/development/lib/changelog/changelog.js b/development/lib/changelog/changelog.js deleted file mode 100644 index b16dca200..000000000 --- a/development/lib/changelog/changelog.js +++ /dev/null @@ -1,305 +0,0 @@ -const semver = require('semver'); - -const { orderedChangeCategories, unreleased } = require('./constants'); - -const changelogTitle = '# Changelog'; -const changelogDescription = `All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).`; - -// Stringification helpers - -function stringifyCategory(category, changes) { - const categoryHeader = `### ${category}`; - if (changes.length === 0) { - return categoryHeader; - } - const changeDescriptions = changes - .map((description) => `- ${description}`) - .join('\n'); - return `${categoryHeader}\n${changeDescriptions}`; -} - -function stringifyRelease(version, categories, { date, status } = {}) { - const releaseHeader = `## [${version}]${date ? ` - ${date}` : ''}${ - status ? ` [${status}]` : '' - }`; - const categorizedChanges = orderedChangeCategories - .filter((category) => categories[category]) - .map((category) => { - const changes = categories[category]; - return stringifyCategory(category, changes); - }) - .join('\n\n'); - if (categorizedChanges === '') { - return releaseHeader; - } - return `${releaseHeader}\n${categorizedChanges}`; -} - -function stringifyReleases(releases, changes) { - const stringifiedUnreleased = stringifyRelease( - unreleased, - changes[unreleased], - ); - const stringifiedReleases = releases.map(({ version, date, status }) => { - const categories = changes[version]; - return stringifyRelease(version, categories, { date, status }); - }); - - return [stringifiedUnreleased, ...stringifiedReleases].join('\n\n'); -} - -function withTrailingSlash(url) { - return url.endsWith('/') ? url : `${url}/`; -} - -function getCompareUrl(repoUrl, firstRef, secondRef) { - return `${withTrailingSlash(repoUrl)}compare/${firstRef}...${secondRef}`; -} - -function getTagUrl(repoUrl, tag) { - return `${withTrailingSlash(repoUrl)}releases/tag/${tag}`; -} - -function stringifyLinkReferenceDefinitions(repoUrl, releases) { - const orderedReleases = releases - .map(({ version }) => version) - .sort((a, b) => semver.gt(a, b)); - - // The "Unreleased" section represents all changes made since the *highest* - // release, not the most recent release. This is to accomodate patch releases - // of older versions that don't represent the latest set of changes. - // - // For example, if a library has a v2.0.0 but the v1.0.0 release needed a - // security update, the v1.0.1 release would then be the most recent, but the - // range of unreleased changes would remain `v2.0.0...HEAD`. - const unreleasedLinkReferenceDefinition = `[${unreleased}]: ${getCompareUrl( - repoUrl, - `v${orderedReleases[0]}`, - 'HEAD', - )}`; - - // The "previous" release that should be used for comparison is not always - // the most recent release chronologically. The _highest_ version that is - // lower than the current release is used as the previous release, so that - // patch releases on older releases can be accomodated. - const releaseLinkReferenceDefinitions = releases - .map(({ version }) => { - if (version === orderedReleases[orderedReleases.length - 1]) { - return `[${version}]: ${getTagUrl(repoUrl, `v${version}`)}`; - } - const versionIndex = orderedReleases.indexOf(version); - const previousVersion = orderedReleases - .slice(versionIndex) - .find((releaseVersion) => { - return semver.gt(version, releaseVersion); - }); - return `[${version}]: ${getCompareUrl( - repoUrl, - `v${previousVersion}`, - `v${version}`, - )}`; - }) - .join('\n'); - return `${unreleasedLinkReferenceDefinition}\n${releaseLinkReferenceDefinitions}${ - releases.length > 0 ? '\n' : '' - }`; -} - -/** - * @typedef {import('./constants.js').Unreleased} Unreleased - * @typedef {import('./constants.js').ChangeCategories ChangeCategories} - */ -/** - * @typedef {import('./constants.js').Version} Version - */ -/** - * Release metadata. - * @typedef {Object} ReleaseMetadata - * @property {string} date - An ISO-8601 formatted date, representing the - * release date. - * @property {string} status -The status of the release (e.g. 'WITHDRAWN', 'DEPRECATED') - * @property {Version} version - The version of the current release. - */ - -/** - * Category changes. A list of changes in a single category. - * @typedef {Array} CategoryChanges - */ - -/** - * Release changes, organized by category - * @typedef {Record} ReleaseChanges - */ - -/** - * Changelog changes, organized by release and by category. - * @typedef {Record} ChangelogChanges - */ - -/** - * A changelog that complies with the ["keep a changelog" v1.1.0 guidelines]{@link https://keepachangelog.com/en/1.0.0/}. - * - * This changelog starts out completely empty, and allows new releases and - * changes to be added such that the changelog remains compliant at all times. - * This can be used to help validate the contents of a changelog, normalize - * formatting, update a changelog, or build one from scratch. - */ -class Changelog { - /** - * Construct an empty changelog - * - * @param {Object} options - * @param {string} options.repoUrl - The GitHub repository URL for the current project - */ - constructor({ repoUrl }) { - this._releases = []; - this._changes = { [unreleased]: {} }; - this._repoUrl = repoUrl; - } - - /** - * Add a release to the changelog - * - * @param {Object} options - * @param {boolean} [options.addToStart] - Determines whether the release is - * added to the top or bottom of the changelog. This defaults to 'true' - * because new releases should be added to the top of the changelog. This - * should be set to 'false' when parsing a changelog top-to-bottom. - * @param {string} [options.date] - An ISO-8601 formatted date, representing the - * release date. - * @param {string} [options.status] - The status of the release (e.g. - * 'WITHDRAWN', 'DEPRECATED') - * @param {Version} options.version - The version of the current release, - * which should be a [semver]{@link https://semver.org/spec/v2.0.0.html}- - * compatible version. - */ - addRelease({ addToStart = true, date, status, version }) { - if (!version) { - throw new Error('Version required'); - } else if (semver.valid(version) === null) { - throw new Error(`Not a valid semver version: '${version}'`); - } else if (this._changes[version]) { - throw new Error(`Release already exists: '${version}'`); - } - - this._changes[version] = {}; - const newRelease = { version, date, status }; - if (addToStart) { - this._releases.unshift(newRelease); - } else { - this._releases.push(newRelease); - } - } - - /** - * Add a change to the changelog - * - * @param {Object} options - * @param {boolean} [options.addToStart] - Determines whether the change is - * added to the top or bottom of the list of changes in this category. This - * defaults to 'true' because changes should be in reverse-chronological - * order. This should be set to 'false' when parsing a changelog top-to- - * bottom. - * @param {string} options.category - The category of the change. - * @param {string} options.description - The description of the change. - * @param {Version} [options.version] - The version this change was released - * in. If this is not given, the change is assumed to be unreleased. - */ - addChange({ addToStart = true, category, description, version }) { - if (!category) { - throw new Error('Category required'); - } else if (!orderedChangeCategories.includes(category)) { - throw new Error(`Unrecognized category: '${category}'`); - } else if (!description) { - throw new Error('Description required'); - } else if (version !== undefined && !this._changes[version]) { - throw new Error(`Specified release version does not exist: '${version}'`); - } - - const release = version - ? this._changes[version] - : this._changes[unreleased]; - - if (!release[category]) { - release[category] = []; - } - if (addToStart) { - release[category].unshift(description); - } else { - release[category].push(description); - } - } - - /** - * Migrate all unreleased changes to a release section. - * - * Changes are migrated in their existing categories, and placed above any - * pre-existing changes in that category. - * - * @param {Version} version - The release version to migrate unreleased - * changes to. - */ - migrateUnreleasedChangesToRelease(version) { - const releaseChanges = this._changes[version]; - if (!releaseChanges) { - throw new Error(`Specified release version does not exist: '${version}'`); - } - - const unreleasedChanges = this._changes[unreleased]; - - for (const category of Object.keys(unreleasedChanges)) { - if (releaseChanges[category]) { - releaseChanges[category] = [ - ...unreleasedChanges[category], - ...releaseChanges[category], - ]; - } else { - releaseChanges[category] = unreleasedChanges[category]; - } - } - this._changes[unreleased] = {}; - } - - /** - * Gets the metadata for all releases. - * @returns {Array} The metadata for each release. - */ - getReleases() { - return this._releases; - } - - /** - * Gets the changes in the given release, organized by category. - * @param {Version} version - The version of the release being retrieved. - * @returns {ReleaseChanges} The changes included in the given released. - */ - getReleaseChanges(version) { - return this._changes[version]; - } - - /** - * Gets all changes that have not yet been released - * @returns {ReleaseChanges} The changes that have not yet been released. - */ - getUnreleasedChanges() { - return this._changes[unreleased]; - } - - /** - * The stringified changelog, formatted according to [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - * @returns {string} The stringified changelog. - */ - toString() { - return `${changelogTitle} -${changelogDescription} - -${stringifyReleases(this._releases, this._changes)} - -${stringifyLinkReferenceDefinitions(this._repoUrl, this._releases)}`; - } -} - -module.exports = Changelog; diff --git a/development/lib/changelog/constants.js b/development/lib/changelog/constants.js deleted file mode 100644 index c2b8ae008..000000000 --- a/development/lib/changelog/constants.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Version string - * @typedef {string} Version - A [SemVer]{@link https://semver.org/spec/v2.0.0.html}- - * compatible version string. - */ - -/** - * Change categories. - * - * Most of these categories are from [Keep a Changelog]{@link https://keepachangelog.com/en/1.0.0/}. - * The "Uncategorized" category was added because we have many changes from - * older releases that would be difficult to categorize. - * - * @typedef {Record} ChangeCategories - * @property {'Added'} Added - for new features. - * @property {'Changed'} Changed - for changes in existing functionality. - * @property {'Deprecated'} Deprecated - for soon-to-be removed features. - * @property {'Fixed'} Fixed - for any bug fixes. - * @property {'Removed'} Removed - for now removed features. - * @property {'Security'} Security - in case of vulnerabilities. - * @property {'Uncategorized'} Uncategorized - for any changes that have not - * yet been categorized. - */ - -/** - * @type {ChangeCategories} - */ -const changeCategories = { - Added: 'Added', - Changed: 'Changed', - Deprecated: 'Deprecated', - Fixed: 'Fixed', - Removed: 'Removed', - Security: 'Security', - Uncategorized: 'Uncategorized', -}; - -/** - * Change categories in the order in which they should be listed in the - * changelog. - * - * @type {Array} - */ -const orderedChangeCategories = [ - 'Uncategorized', - 'Added', - 'Changed', - 'Deprecated', - 'Removed', - 'Fixed', - 'Security', -]; - -/** - * The header for the section of the changelog listing unreleased changes. - * @typedef {'Unreleased'} Unreleased - */ - -/** - * @type {Unreleased} - */ -const unreleased = 'Unreleased'; - -module.exports = { - changeCategories, - orderedChangeCategories, - unreleased, -}; diff --git a/development/lib/changelog/parseChangelog.js b/development/lib/changelog/parseChangelog.js deleted file mode 100644 index 228da3635..000000000 --- a/development/lib/changelog/parseChangelog.js +++ /dev/null @@ -1,84 +0,0 @@ -const Changelog = require('./changelog'); -const { unreleased } = require('./constants'); - -function truncated(line) { - return line.length > 80 ? `${line.slice(0, 80)}...` : line; -} - -/** - * Constructs a Changelog instance that represents the given changelog, which - * is parsed for release and change informatino. - * @param {Object} options - * @param {string} options.changelogContent - The changelog to parse - * @param {string} options.repoUrl - The GitHub repository URL for the current - * project. - * @returns {Changelog} A changelog instance that reflects the changelog text - * provided. - */ -function parseChangelog({ changelogContent, repoUrl }) { - const changelogLines = changelogContent.split('\n'); - const changelog = new Changelog({ repoUrl }); - - const unreleasedHeaderIndex = changelogLines.indexOf(`## [${unreleased}]`); - if (unreleasedHeaderIndex === -1) { - throw new Error(`Failed to find ${unreleased} header`); - } - const unreleasedLinkReferenceDefinition = changelogLines.findIndex((line) => { - return line.startsWith(`[${unreleased}]: `); - }); - if (unreleasedLinkReferenceDefinition === -1) { - throw new Error(`Failed to find ${unreleased} link reference definition`); - } - - const contentfulChangelogLines = changelogLines - .slice(unreleasedHeaderIndex + 1, unreleasedLinkReferenceDefinition) - .filter((line) => line !== ''); - - let mostRecentRelease; - let mostRecentCategory; - for (const line of contentfulChangelogLines) { - if (line.startsWith('## [')) { - const results = line.match( - /^## \[(\d+\.\d+\.\d+)\](?: - (\d\d\d\d-\d\d-\d\d))?(?: \[(\w+)\])?/u, - ); - if (results === null) { - throw new Error(`Malformed release header: '${truncated(line)}'`); - } - mostRecentRelease = results[1]; - mostRecentCategory = undefined; - const date = results[2]; - const status = results[3]; - changelog.addRelease({ - addToStart: false, - date, - status, - version: mostRecentRelease, - }); - } else if (line.startsWith('### ')) { - const results = line.match(/^### (\w+)$\b/u); - if (results === null) { - throw new Error(`Malformed category header: '${truncated(line)}'`); - } - mostRecentCategory = results[1]; - } else if (line.startsWith('- ')) { - if (mostRecentCategory === undefined) { - throw new Error(`Category missing for change: '${truncated(line)}'`); - } - const description = line.slice(2); - changelog.addChange({ - addToStart: false, - category: mostRecentCategory, - description, - version: mostRecentRelease, - }); - } else if (mostRecentRelease === null) { - continue; - } else { - throw new Error(`Unrecognized line: '${truncated(line)}'`); - } - } - - return changelog; -} - -module.exports = { parseChangelog }; diff --git a/development/lib/changelog/updateChangelog.js b/development/lib/changelog/updateChangelog.js deleted file mode 100644 index b94d6caf1..000000000 --- a/development/lib/changelog/updateChangelog.js +++ /dev/null @@ -1,171 +0,0 @@ -const assert = require('assert').strict; -const runCommand = require('../runCommand'); -const { parseChangelog } = require('./parseChangelog'); -const { changeCategories } = require('./constants'); - -async function getMostRecentTag() { - const [mostRecentTagCommitHash] = await runCommand('git', [ - 'rev-list', - '--tags', - '--max-count=1', - ]); - const [mostRecentTag] = await runCommand('git', [ - 'describe', - '--tags', - mostRecentTagCommitHash, - ]); - assert.equal(mostRecentTag[0], 'v', 'Most recent tag should start with v'); - return mostRecentTag; -} - -async function getCommits(commitHashes) { - const commits = []; - for (const commitHash of commitHashes) { - const [subject] = await runCommand('git', [ - 'show', - '-s', - '--format=%s', - commitHash, - ]); - - let prNumber; - let description = subject; - - // Squash & Merge: the commit subject is parsed as ` (#)` - if (subject.match(/\(#\d+\)/u)) { - const matchResults = subject.match(/\(#(\d+)\)/u); - prNumber = matchResults[1]; - description = subject.match(/^(.+)\s\(#\d+\)/u)[1]; - // Merge: the PR ID is parsed from the git subject (which is of the form `Merge pull request - // # from `, and the description is assumed to be the first line of the body. - // If no body is found, the description is set to the commit subject - } else if (subject.match(/#\d+\sfrom/u)) { - const matchResults = subject.match(/#(\d+)\sfrom/u); - prNumber = matchResults[1]; - const [firstLineOfBody] = await runCommand('git', [ - 'show', - '-s', - '--format=%b', - commitHash, - ]); - description = firstLineOfBody || subject; - } - // Otherwise: - // Normal commits: The commit subject is the description, and the PR ID is omitted. - - commits.push({ prNumber, description }); - } - return commits; -} - -function getAllChangeDescriptions(changelog) { - const releases = changelog.getReleases(); - const changeDescriptions = Object.values( - changelog.getUnreleasedChanges(), - ).flat(); - for (const release of releases) { - changeDescriptions.push( - ...Object.values(changelog.getReleaseChanges(release.version)).flat(), - ); - } - return changeDescriptions; -} - -function getAllLoggedPrNumbers(changelog) { - const changeDescriptions = getAllChangeDescriptions(changelog); - - const prNumbersWithChangelogEntries = []; - for (const description of changeDescriptions) { - const matchResults = description.match(/^\[#(\d+)\]/u); - if (matchResults === null) { - continue; - } - const prNumber = matchResults[1]; - prNumbersWithChangelogEntries.push(prNumber); - } - - return prNumbersWithChangelogEntries; -} - -/** - * @typedef {import('./constants.js').Version} Version - */ - -/** - * Update a changelog with any commits made since the last release. Commits for - * PRs that are already included in the changelog are omitted. - * @param {Object} options - * @param {string} options.changelogContent - The current changelog - * @param {Version} options.currentVersion - The current version - * @param {string} options.repoUrl - The GitHub repository URL for the current - * project. - * @param {boolean} options.isReleaseCandidate - Denotes whether the current - * project is in the midst of release preparation or not. If this is set, any - * new changes are listed under the current release header. Otherwise, they - * are listed under the 'Unreleased' section. - * @returns - */ -async function updateChangelog({ - changelogContent, - currentVersion, - repoUrl, - isReleaseCandidate, -}) { - const changelog = parseChangelog({ changelogContent, repoUrl }); - - // Ensure we have all tags on remote - await runCommand('git', ['fetch', '--tags']); - const mostRecentTag = await getMostRecentTag(); - const commitsHashesSinceLastRelease = await runCommand('git', [ - 'rev-list', - `${mostRecentTag}..HEAD`, - ]); - const commits = await getCommits(commitsHashesSinceLastRelease); - - const loggedPrNumbers = getAllLoggedPrNumbers(changelog); - const newCommits = commits.filter( - ({ prNumber }) => !loggedPrNumbers.includes(prNumber), - ); - - const hasUnreleasedChanges = changelog.getUnreleasedChanges().length !== 0; - if ( - newCommits.length === 0 && - (!isReleaseCandidate || hasUnreleasedChanges) - ) { - return undefined; - } - - // Ensure release header exists, if necessary - if ( - isReleaseCandidate && - !changelog - .getReleases() - .find((release) => release.version === currentVersion) - ) { - changelog.addRelease({ version: currentVersion }); - } - - if (isReleaseCandidate && hasUnreleasedChanges) { - changelog.migrateUnreleasedChangesToRelease(currentVersion); - } - - const newChangeEntries = newCommits.map(({ prNumber, description }) => { - if (prNumber) { - const prefix = `[#${prNumber}](${repoUrl}/pull/${prNumber})`; - return `${prefix}: ${description}`; - } - return description; - }); - - for (const description of newChangeEntries.reverse()) { - changelog.addChange({ - version: isReleaseCandidate ? currentVersion : undefined, - category: changeCategories.Uncategorized, - description, - }); - } - - return changelog.toString(); -} - -module.exports = { updateChangelog }; diff --git a/development/lib/runCommand.js b/development/lib/runCommand.js deleted file mode 100644 index 2d92ffe99..000000000 --- a/development/lib/runCommand.js +++ /dev/null @@ -1,79 +0,0 @@ -const spawn = require('cross-spawn'); - -/** - * Run a command to completion using the system shell. - * - * This will run a command with the specified arguments, and resolve when the - * process has exited. The STDOUT stream is monitored for output, which is - * returned after being split into lines. All output is expected to be UTF-8 - * encoded, and empty lines are removed from the output. - * - * Anything received on STDERR is assumed to indicate a problem, and is tracked - * as an error. - * - * @param {string} command - The command to run - * @param {Array} [args] - The arguments to pass to the command - * @returns {Array} Lines of output received via STDOUT - */ -async function runCommand(command, args) { - const output = []; - let mostRecentError; - let errorSignal; - let errorCode; - const internalError = new Error('Internal'); - try { - await new Promise((resolve, reject) => { - const childProcess = spawn(command, args, { encoding: 'utf8' }); - childProcess.stdout.setEncoding('utf8'); - childProcess.stderr.setEncoding('utf8'); - - childProcess.on('error', (error) => { - mostRecentError = error; - }); - - childProcess.stdout.on('data', (message) => { - const nonEmptyLines = message.split('\n').filter((line) => line !== ''); - output.push(...nonEmptyLines); - }); - - childProcess.stderr.on('data', (message) => { - mostRecentError = new Error(message.trim()); - }); - - childProcess.once('exit', (code, signal) => { - if (code === 0) { - return resolve(); - } - errorCode = code; - errorSignal = signal; - return reject(internalError); - }); - }); - } catch (error) { - /** - * The error is re-thrown here in an `async` context to preserve the stack trace. If this was - * was thrown inside the Promise constructor, the stack trace would show a few frames of - * Node.js internals then end, without indicating where `runCommand` was called. - */ - if (error === internalError) { - let errorMessage; - if (errorCode !== null && errorSignal !== null) { - errorMessage = `Terminated by signal '${errorSignal}'; exited with code '${errorCode}'`; - } else if (errorSignal !== null) { - errorMessage = `Terminaled by signal '${errorSignal}'`; - } else if (errorCode === null) { - errorMessage = 'Exited with no code or signal'; - } else { - errorMessage = `Exited with code '${errorCode}'`; - } - const improvedError = new Error(errorMessage); - if (mostRecentError) { - improvedError.cause = mostRecentError; - } - throw improvedError; - } - } - return output; -} - -module.exports = runCommand; diff --git a/package.json b/package.json index b1919e12d..630a835c4 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,10 @@ "name": "metamask-crx", "version": "0.0.0", "private": true, + "repository": { + "type": "git", + "url": "https://github.com/MetaMask/metamask-extension" + }, "scripts": { "setup": "yarn install && yarn setup:postinstall", "setup:postinstall": "yarn patch-package && yarn allow-scripts", @@ -57,7 +61,7 @@ "storybook": "start-storybook -p 6006 -c .storybook --static-dir ./app ./storybook/images", "storybook:build": "build-storybook -c .storybook -o storybook-build --static-dir ./app ./storybook/images", "storybook:deploy": "storybook-to-ghpages --existing-output-dir storybook-build --remote storybook --branch master", - "update-changelog": "node ./development/auto-changelog.js", + "update-changelog": "auto-changelog update", "generate:migration": "./development/generate-migration.sh", "lavamoat:auto": "lavamoat ./development/build/index.js --writeAutoPolicy", "lavamoat:debug": "lavamoat ./development/build/index.js --writeAutoPolicyDebug" @@ -205,6 +209,7 @@ "@babel/preset-react": "^7.0.0", "@babel/register": "^7.5.5", "@lavamoat/allow-scripts": "^1.0.4", + "@metamask/auto-changelog": "^1.0.0", "@metamask/eslint-config": "^6.0.0", "@metamask/eslint-config-jest": "^6.0.0", "@metamask/eslint-config-mocha": "^6.0.0", diff --git a/yarn.lock b/yarn.lock index 45ef9ce55..de031caa7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2619,6 +2619,16 @@ prop-types "^15.7.2" react-is "^16.8.0" +"@metamask/auto-changelog@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@metamask/auto-changelog/-/auto-changelog-1.0.0.tgz#ca6a71d1b983cf08b715bdcd8e240d746974d0c7" + integrity sha512-3Bcm+JsEmNllPi7kRtzS6EAjYTzz+Isa4QFq2DQ4DFwIsv2HUxdR+KNU2GJ1BdX4lbPcQTrpTdaPgBZ9G4NhLA== + dependencies: + cross-spawn "^7.0.3" + diff "^5.0.0" + semver "^7.3.5" + yargs "^17.0.1" + "@metamask/contract-metadata@^1.19.0", "@metamask/contract-metadata@^1.22.0", "@metamask/contract-metadata@^1.23.0": version "1.25.0" resolved "https://registry.yarnpkg.com/@metamask/contract-metadata/-/contract-metadata-1.25.0.tgz#442ace91fb40165310764b68d8096d0017bb0492" @@ -9185,6 +9195,11 @@ diff@^4.0.2: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +diff@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + diffie-hellman@^5.0.0: version "5.0.2" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e" @@ -27561,6 +27576,19 @@ yargs@^16.0.0, yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yargs@^17.0.1: + version "17.0.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.0.1.tgz#6a1ced4ed5ee0b388010ba9fd67af83b9362e0bb" + integrity sha512-xBBulfCc8Y6gLFcrPvtqKz9hz8SO0l1Ni8GgDekvBX2ro0HRQImDGnikfc33cgzcYUSncapnNcZDjVFIH3f6KQ== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + yargs@^7.1.0: version "7.1.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.1.tgz#67f0ef52e228d4ee0d6311acede8850f53464df6"