diff --git a/.github/workflows/create-release-pr.yml b/.github/workflows/create-release-pr.yml index 87609ee4f96..58c8c4152d2 100644 --- a/.github/workflows/create-release-pr.yml +++ b/.github/workflows/create-release-pr.yml @@ -12,7 +12,9 @@ on: version-number: description: 'A natural version number. eg: 862' required: true - + previous-version-tag: + description: 'Previous release version tag. eg: v7.7.0' + required: true jobs: create-release-pr: runs-on: ubuntu-latest @@ -34,20 +36,21 @@ jobs: # The workaround is to use a personal access token (BUG_REPORT_TOKEN) instead of # the default GITHUB_TOKEN for the checkout action. token: ${{ secrets.BUG_REPORT_TOKEN }} - - name: Get Node.js version - id: nvm - run: echo "NODE_VERSION=$(cat .nvmrc)" >> "$GITHUB_OUTPUT" - - uses: actions/setup-node@v3 + - name: Set up Node.js + uses: actions/setup-node@v3 with: - node-version: ${{ steps.nvm.outputs.NODE_VERSION }} + node-version-file: '.nvmrc' + cache: yarn + - name: Install dependencies + run: yarn --immutable - name: Set Versions id: set-versions shell: bash - run: SEMVER_VERSION=${{ github.event.inputs.semver-version }} VERSION_NUMBER=${{ github.event.inputs.version-number }} yarn create-release + run: SEMVER_VERSION=${{ github.event.inputs.semver-version }} VERSION_NUMBER=${{ github.event.inputs.version-number }} yarn set-version - name: Create Release PR id: create-release-pr shell: bash env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - ./scripts/create-release-pr.sh ${{ github.event.inputs.semver-version }} + ./scripts/create-release-pr.sh ${{ github.event.inputs.previous-version-tag }} ${{ github.event.inputs.semver-version }} \ No newline at end of file diff --git a/package.json b/package.json index aa040250da2..017b7a59983 100644 --- a/package.json +++ b/package.json @@ -78,9 +78,10 @@ "test:merge-coverage": "nyc report --temp-dir ./tests/coverage --report-dir ./tests/merged-coverage/ --reporter json --reporter text --reporter lcovonly", "test:validate-coverage": "nyc check-coverage --nycrc-path ./coverage-thresholds.json -t ./tests/merged-coverage/", "update-changelog": "./scripts/auto-changelog.sh", + "changeset-changelog": "wrap () { node ./scripts/generate-rc-commits.js \"$@\" && ./scripts/changelog-csv.sh }; wrap ", "prestorybook": "rnstl", "deduplicate": "yarn yarn-deduplicate && yarn install", - "create-release": "./scripts/set-versions.sh && yarn update-changelog", + "set-version": "./scripts/set-versions.sh", "add-release-label-to-pr-and-linked-issues": "ts-node ./.github/scripts/add-release-label-to-pr-and-linked-issues.ts", "add-team-label-to-pr": "ts-node ./.github/scripts/add-team-label-to-pr.ts", "run-bitrise-e2e-check": "ts-node ./.github/scripts/bitrise/run-bitrise-e2e-check.ts", @@ -371,6 +372,7 @@ "@metamask/object-multiplex": "^1.1.0", "@metamask/providers": "^13.1.0", "@metamask/test-dapp": "^8.9.0", + "@octokit/rest": "^21.0.0", "@open-rpc/mock-server": "^1.7.5", "@open-rpc/schema-utils-js": "^1.16.2", "@open-rpc/test-coverage": "^2.2.2", @@ -477,6 +479,7 @@ "regenerator-runtime": "0.13.9", "rn-nodeify": "10.3.0", "serve-handler": "^6.1.5", + "simple-git": "^3.22.0", "ts-node": "^10.5.0", "typescript": "~4.8.4", "wdio-cucumberjs-json-reporter": "^4.4.3", @@ -574,4 +577,4 @@ } }, "packageManager": "yarn@1.22.22" -} \ No newline at end of file +} diff --git a/scripts/changelog-csv.sh b/scripts/changelog-csv.sh new file mode 100755 index 00000000000..05ab977b0fc --- /dev/null +++ b/scripts/changelog-csv.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +set -e +set -u +set -o pipefail + +readonly CSV_FILE='commits.csv' + +# Add release branch arg name +RELEASE_BRANCH_NAME="${1}" + +# Temporary file for new entries +NEW_ENTRIES=$(mktemp) + +# Backup file for existing CHANGELOG +CHANGELOG="CHANGELOG.md" +CHANGELOG_BACKUP="$CHANGELOG.bak" + +# Backup existing CHANGELOG.md +cp "$CHANGELOG" "$CHANGELOG_BACKUP" + +# Function to append entry to the correct category in the temp file +append_entry() { + local change_type="$1" + local entry="$2" + # Ensure the "Other" category is explicitly handled + case "$change_type" in + Added|Changed|Fixed) ;; + *) change_type="Other" ;; # Categorize as "Other" if not matching predefined categories + esac + echo "$entry" >> "$NEW_ENTRIES-$change_type" +} + +# Read the CSV file and append entries to temp files based on change type +while IFS=, read -r commit_message author pr_link team change_type +do + pr_id=$(echo "$pr_link" | grep -o '[^/]*$') + entry="- [#$pr_id]($pr_link): $commit_message" + append_entry "$change_type" "$entry" +done < <(tail -n +2 "$CSV_FILE") # Skip the header line + +# Function to insert new entries into CHANGELOG.md after a specific line +insert_new_entries() { + local marker="## Current Main Branch" + local temp_changelog=$(mktemp) + + # Find the line number of the marker + local line_num=$(grep -n "$marker" "$CHANGELOG_BACKUP" | cut -d ':' -f 1) + + # Split the existing CHANGELOG at the marker line + head -n "$line_num" "$CHANGELOG_BACKUP" > "$temp_changelog" + + # Append the release header + echo "" >> "$temp_changelog" + echo "## $RELEASE_BRANCH_NAME - " >> "$temp_changelog" + echo "" >> "$temp_changelog" + + # Append new entries for each change type if they exist + for change_type in Added Changed Fixed Other; do + if [[ -s "$NEW_ENTRIES-$change_type" ]]; then + echo "### $change_type" >> "$temp_changelog" + cat "$NEW_ENTRIES-$change_type" >> "$temp_changelog" + echo "" >> "$temp_changelog" # Add a newline for spacing + fi + done + + # Append the rest of the original CHANGELOG content + tail -n +$((line_num + 1)) "$CHANGELOG_BACKUP" >> "$temp_changelog" + + # Replace the original CHANGELOG with the updated one + mv "$temp_changelog" "$CHANGELOG" +} + +# Trap to ensure cleanup happens +trap 'rm -f "$NEW_ENTRIES-"* "$CHANGELOG_BACKUP"' EXIT + +# Insert new entries into CHANGELOG.md +insert_new_entries + +echo 'CHANGELOG updated' \ No newline at end of file diff --git a/scripts/create-release-pr.sh b/scripts/create-release-pr.sh index c0523b242b7..c0d8157525e 100755 --- a/scripts/create-release-pr.sh +++ b/scripts/create-release-pr.sh @@ -4,7 +4,8 @@ set -e set -u set -o pipefail -NEW_VERSION="${1}" +PREVIOUS_VERSION="${1}" +NEW_VERSION="${2}" RELEASE_BRANCH_PREFIX="release/" if [[ -z $NEW_VERSION ]]; then @@ -13,7 +14,7 @@ if [[ -z $NEW_VERSION ]]; then fi RELEASE_BRANCH_NAME="${RELEASE_BRANCH_PREFIX}${NEW_VERSION}" -RELEASE_BODY="This is the release candidate for version ${NEW_VERSION}." +RELEASE_BODY="This is the release candidate for version ${NEW_VERSION}. The test plan can be found at [commit.csv](https://github.com/MetaMask/metamask-mobile/blob/${RELEASE_BRANCH_NAME}/commits.csv)" git config user.name metamaskbot git config user.email metamaskbot@users.noreply.github.com @@ -30,6 +31,13 @@ git push --set-upstream origin "${RELEASE_BRANCH_NAME}" gh pr create \ --draft \ - --title "${NEW_VERSION}" \ + --title "feat: ${NEW_VERSION}" \ --body "${RELEASE_BODY}" \ --head "${RELEASE_BRANCH_NAME}"; + +#Generate changelog and test plan csv +node ./scripts/generate-rc-commits.mjs "${PREVIOUS_VERSION}" "${RELEASE_BRANCH_NAME}" +./scripts/changelog-csv.sh "${RELEASE_BRANCH_NAME}" +git add ./commits.csv +git commit -am "updated changelog and generated feature test plan" +git push \ No newline at end of file diff --git a/scripts/generate-rc-commits.mjs b/scripts/generate-rc-commits.mjs new file mode 100644 index 00000000000..eac00c504cc --- /dev/null +++ b/scripts/generate-rc-commits.mjs @@ -0,0 +1,158 @@ +// eslint-disable-next-line import/no-nodejs-modules +import fs from 'fs'; +// eslint-disable-next-line import/no-extraneous-dependencies +import simpleGit from 'simple-git'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { Octokit } from '@octokit/rest'; + +// "GITHUB_TOKEN" is an automatically generated, repository-specific access token provided by GitHub Actions. +const githubToken = process.env.GITHUB_TOKEN; +if (!githubToken) { + console.log('GITHUB_TOKEN not found'); + process.exit(1); +} + +// Initialize Octokit with your GitHub token +const octokit = new Octokit({ auth: githubToken}); + +async function getPRLabels(prNumber) { + try { + const { data } = await octokit.pulls.get({ + owner: 'MetaMask', + repo: 'metamask-mobile', + pull_number: prNumber[1], + }); + + const labels = data.labels.map(label => label.name); + + // Check if any label name contains "team" + let teamArray = labels.filter(label => label.toLowerCase().startsWith('team-')); + + if(teamArray.length > 1 && teamArray.includes('team-mobile-platform')) + teamArray = teamArray.filter(item => item !== 'team-mobile-platform'); + + return teamArray || ['Unknown']; + + } catch (error) { + console.error(`Error fetching labels for PR #${prNumber}:`, error); + return ['Unknown']; + } +} + +// Function to filter commits based on unique commit messages and group by teams +async function filterCommitsByTeam(branchA, branchB) { + try { + const git = simpleGit(); + + const logOptions = { + from: branchB, + to: branchA, + format: { + hash: '%H', + author: '%an', + message: '%s', + }, + }; + + const log = await git.log(logOptions); + const commitsByTeam = {}; + + const MAX_COMMITS = 500; // Limit the number of commits to process + + for (const commit of log.all) { + const { author, message, hash } = commit; + if (Object.keys(commitsByTeam).length >= MAX_COMMITS) { + console.error('Too many commits for script to work') + break; + } + + // Extract PR number from the commit message using regex + const prMatch = message.match(/\(#(\d{4,5})\)$/u); + if(prMatch){ + const prLink = prMatch ? `https://github.com/MetaMask/metamask-mobile/pull/${prMatch[1]}` : ''; + const teams = await getPRLabels(prMatch); + + // Initialize the team's commits array if it doesn't exist + if (!commitsByTeam[teams]) { + commitsByTeam[teams] = []; + } + + commitsByTeam[teams].push({ + message, + author, + hash: hash.substring(0, 7), + prLink, + }); + } + } + return commitsByTeam; + } catch (error) { + console.error(error); + return {}; + } +} + +function formatAsCSV(commitsByTeam) { + const csvContent = []; + for (const [team, commits] of Object.entries(commitsByTeam)) { + commits.forEach((commit) => { + const row = [ + escapeCSV(commit.message), + escapeCSV(commit.author), + commit.prLink, + escapeCSV(team), + assignChangeType(commit.message) + ]; + csvContent.push(row.join(',')); + }); + } + csvContent.unshift('Commit Message,Author,PR Link,Team,Change Type'); + + return csvContent; +} + +// Helper function to escape CSV fields +function escapeCSV(field) { + if (field.includes(',') || field.includes('"') || field.includes('\n')) { + return `"${field.replace(/"/g, '""')}"`; // Encapsulate in double quotes and escape existing quotes + } + return field; +} +// Helper function to create change type +function assignChangeType(field) { + if (field.includes('feat')) + return 'Added'; + else if (field.includes('cherry') || field.includes('bump')) + return 'Ops'; + else if (field.includes('chore') || field.includes('test') || field.includes('ci') || field.includes('docs') || field.includes('refactor')) + return 'Changed'; + else if (field.includes('fix')) + return 'Fixed'; + + return 'Unknown'; +} + +async function main() { + const args = process.argv.slice(2); + const fileTitle = 'commits.csv'; + + if (args.length !== 2) { + console.error('Usage: node generate-rc-commits.mjs branchA branchB'); + process.exit(1); + } + + const branchA = args[0]; + const branchB = args[1]; + + const commitsByTeam = await filterCommitsByTeam(branchA, branchB); + + if (Object.keys(commitsByTeam).length === 0) { + console.log('No commits found.'); + } else { + const csvContent = formatAsCSV(commitsByTeam); + fs.writeFileSync(fileTitle, csvContent.join('\n')); + console.log('CSV file ', fileTitle, ' created successfully.'); + } +} + +main(); diff --git a/yarn.lock b/yarn.lock index cc9ca6660dc..d69d41c6f4f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3434,6 +3434,18 @@ "@keystonehq/bc-ur-registry-eth" "^0.6.12" "@ngraveio/bc-ur" "^1.1.6" +"@kwsites/file-exists@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@kwsites/file-exists/-/file-exists-1.1.1.tgz#ad1efcac13e1987d8dbaf235ef3be5b0d96faa99" + integrity sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw== + dependencies: + debug "^4.1.1" + +"@kwsites/promise-deferred@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz#8ace5259254426ccef57f3175bc64ed7095ed919" + integrity sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw== + "@lavamoat/aa@^4.2.0": version "4.2.0" resolved "https://registry.yarnpkg.com/@lavamoat/aa/-/aa-4.2.0.tgz#1262589c77386b1741fe904ebdfe97b959bc8fa4" @@ -5106,6 +5118,11 @@ resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-4.0.0.tgz#40d203ea827b9f17f42a29c6afb93b7745ef80c7" integrity sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA== +"@octokit/auth-token@^5.0.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-5.1.1.tgz#3bbfe905111332a17f72d80bd0b51a3e2fa2cf07" + integrity sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA== + "@octokit/core@^5.0.1": version "5.2.0" resolved "https://registry.yarnpkg.com/@octokit/core/-/core-5.2.0.tgz#ddbeaefc6b44a39834e1bb2e58a49a117672a7ea" @@ -5119,6 +5136,27 @@ before-after-hook "^2.2.0" universal-user-agent "^6.0.0" +"@octokit/core@^6.1.2": + version "6.1.2" + resolved "https://registry.yarnpkg.com/@octokit/core/-/core-6.1.2.tgz#20442d0a97c411612da206411e356014d1d1bd17" + integrity sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg== + dependencies: + "@octokit/auth-token" "^5.0.0" + "@octokit/graphql" "^8.0.0" + "@octokit/request" "^9.0.0" + "@octokit/request-error" "^6.0.1" + "@octokit/types" "^13.0.0" + before-after-hook "^3.0.2" + universal-user-agent "^7.0.0" + +"@octokit/endpoint@^10.0.0": + version "10.1.1" + resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-10.1.1.tgz#1a9694e7aef6aa9d854dc78dd062945945869bcc" + integrity sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q== + dependencies: + "@octokit/types" "^13.0.0" + universal-user-agent "^7.0.2" + "@octokit/endpoint@^9.0.1": version "9.0.5" resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-9.0.5.tgz#e6c0ee684e307614c02fc6ac12274c50da465c44" @@ -5136,6 +5174,15 @@ "@octokit/types" "^13.0.0" universal-user-agent "^6.0.0" +"@octokit/graphql@^8.0.0": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-8.1.1.tgz#3cacab5f2e55d91c733e3bf481d3a3f8a5f639c4" + integrity sha512-ukiRmuHTi6ebQx/HFRCXKbDlOh/7xEV6QUXaE7MJEKGNAncGI/STSbOkl12qVXZrfZdpXctx5O9X1AIaebiDBg== + dependencies: + "@octokit/request" "^9.0.0" + "@octokit/types" "^13.0.0" + universal-user-agent "^7.0.0" + "@octokit/openapi-types@^20.0.0": version "20.0.0" resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-20.0.0.tgz#9ec2daa0090eeb865ee147636e0c00f73790c6e5" @@ -5146,6 +5193,13 @@ resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-22.2.0.tgz#75aa7dcd440821d99def6a60b5f014207ae4968e" integrity sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg== +"@octokit/plugin-paginate-rest@^11.0.0": + version "11.3.0" + resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.0.tgz#f8511b5df06b83e662c54f249a11a0da2213c6c3" + integrity sha512-n4znWfRinnUQF6TPyxs7EctSAA3yVSP4qlJP2YgI3g9d4Ae2n5F3XDOjbUluKRxPU3rfsgpOboI4O4VtPc6Ilg== + dependencies: + "@octokit/types" "^13.5.0" + "@octokit/plugin-paginate-rest@^9.0.0": version "9.2.1" resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.1.tgz#2e2a2f0f52c9a4b1da1a3aa17dabe3c459b9e401" @@ -5153,6 +5207,11 @@ dependencies: "@octokit/types" "^12.6.0" +"@octokit/plugin-request-log@^5.1.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-5.3.0.tgz#4dea4f34316b7075d02796edcb73103266119e61" + integrity sha512-FiGcyjdtYPlr03ExBk/0ysIlEFIFGJQAVoPPMxL19B24bVSEiZQnVGBunNtaAF1YnvE/EFoDpXmITtRnyCiypQ== + "@octokit/plugin-rest-endpoint-methods@^10.0.0": version "10.4.1" resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz#41ba478a558b9f554793075b2e20cd2ef973be17" @@ -5160,6 +5219,13 @@ dependencies: "@octokit/types" "^12.6.0" +"@octokit/plugin-rest-endpoint-methods@^13.0.0": + version "13.2.1" + resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.2.1.tgz#b5e9118b4e76180cee65e03b71bcfcf632ae12d9" + integrity sha512-YMWBw6Exh1ZBs5cCE0AnzYxSQDIJS00VlBqISTgNYmu5MBdeM07K/MAJjy/VkNaH5jpJmD/5HFUvIZ+LDB5jSQ== + dependencies: + "@octokit/types" "^13.5.0" + "@octokit/request-error@^5.1.0": version "5.1.0" resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-5.1.0.tgz#ee4138538d08c81a60be3f320cd71063064a3b30" @@ -5169,6 +5235,13 @@ deprecation "^2.0.0" once "^1.4.0" +"@octokit/request-error@^6.0.1": + version "6.1.1" + resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-6.1.1.tgz#bed1b5f52ce7fefb1077a92bf42124ff36f73f2c" + integrity sha512-1mw1gqT3fR/WFvnoVpY/zUM2o/XkMs/2AszUUG9I69xn0JFLv6PGkPhNk5lbfvROs79wiS0bqiJNxfCZcRJJdg== + dependencies: + "@octokit/types" "^13.0.0" + "@octokit/request@^8.3.0", "@octokit/request@^8.3.1": version "8.4.0" resolved "https://registry.yarnpkg.com/@octokit/request/-/request-8.4.0.tgz#7f4b7b1daa3d1f48c0977ad8fffa2c18adef8974" @@ -5179,6 +5252,26 @@ "@octokit/types" "^13.1.0" universal-user-agent "^6.0.0" +"@octokit/request@^9.0.0": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@octokit/request/-/request-9.1.1.tgz#e836eb69c0fb4b59b6437af7716ca348a1232a52" + integrity sha512-pyAguc0p+f+GbQho0uNetNQMmLG1e80WjkIaqqgUkihqUp0boRU6nKItXO4VWnr+nbZiLGEyy4TeKRwqaLvYgw== + dependencies: + "@octokit/endpoint" "^10.0.0" + "@octokit/request-error" "^6.0.1" + "@octokit/types" "^13.1.0" + universal-user-agent "^7.0.2" + +"@octokit/rest@^21.0.0": + version "21.0.0" + resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-21.0.0.tgz#bde4b657193643b6b691810fe890755a3c67dd9f" + integrity sha512-XudXXOmiIjivdjNZ+fN71NLrnDM00sxSZlhqmPR3v0dVoJwyP628tSlc12xqn8nX3N0965583RBw5GPo6r8u4Q== + dependencies: + "@octokit/core" "^6.1.2" + "@octokit/plugin-paginate-rest" "^11.0.0" + "@octokit/plugin-request-log" "^5.1.0" + "@octokit/plugin-rest-endpoint-methods" "^13.0.0" + "@octokit/types@^12.6.0": version "12.6.0" resolved "https://registry.yarnpkg.com/@octokit/types/-/types-12.6.0.tgz#8100fb9eeedfe083aae66473bd97b15b62aedcb2" @@ -5186,7 +5279,7 @@ dependencies: "@octokit/openapi-types" "^20.0.0" -"@octokit/types@^13.0.0", "@octokit/types@^13.1.0": +"@octokit/types@^13.0.0", "@octokit/types@^13.1.0", "@octokit/types@^13.5.0": version "13.5.0" resolved "https://registry.yarnpkg.com/@octokit/types/-/types-13.5.0.tgz#4796e56b7b267ebc7c921dcec262b3d5bfb18883" integrity sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ== @@ -12392,6 +12485,11 @@ before-after-hook@^2.2.0: resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== +before-after-hook@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-3.0.2.tgz#d5665a5fa8b62294a5aa0a499f933f4a1016195d" + integrity sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A== + big-integer@1.6.x: version "1.6.51" resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" @@ -26287,6 +26385,15 @@ simple-get@^4.0.0, simple-get@^4.0.1: once "^1.3.1" simple-concat "^1.0.0" +simple-git@^3.22.0: + version "3.25.0" + resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-3.25.0.tgz#3666e76d6831f0583dc380645945b97e0ac4aab6" + integrity sha512-KIY5sBnzc4yEcJXW7Tdv4viEz8KyG+nU0hay+DWZasvdFOYKeUZ6Xc25LUHHjw0tinPT7O1eY6pzX7pRT1K8rw== + dependencies: + "@kwsites/file-exists" "^1.1.1" + "@kwsites/promise-deferred" "^1.1.1" + debug "^4.3.5" + simple-plist@^1.1.0: version "1.3.1" resolved "https://registry.yarnpkg.com/simple-plist/-/simple-plist-1.3.1.tgz#16e1d8f62c6c9b691b8383127663d834112fb017" @@ -27874,6 +27981,11 @@ universal-user-agent@^6.0.0: resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== +universal-user-agent@^7.0.0, universal-user-agent@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-7.0.2.tgz#52e7d0e9b3dc4df06cc33cb2b9fd79041a54827e" + integrity sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q== + universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"