From 7912802c14a81d2714d19b94db737d4bd5793afd Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Tue, 20 Nov 2018 15:35:16 -0400 Subject: [PATCH 01/41] docs: update documentation to target Linux support (#287 #354 #537 #552 #592 #605 #656 #667 #836 #838 #839 #843 #864 #910 #956 #984 #1079) --- .github/ISSUE_TEMPLATE/bug_report.yaml | 4 - .github/ISSUE_TEMPLATE/installation-issue.md | 21 +++ README.md | 161 +++++++++++++------ docs/installation.md | 15 ++ docs/known-issues.md | 62 +++++++ docs/process/publishing-linux-releases.md | 154 ++++++++++++++++++ 6 files changed, 364 insertions(+), 53 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/installation-issue.md create mode 100644 docs/process/publishing-linux-releases.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index f71cfe29e20..758ddff8beb 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -1,10 +1,6 @@ name: 🐛 Bug Report description: File a bug report body: - - type: markdown - attributes: - value: | - Thanks for filing a bug report! This issue tracker is for [GitHub Desktop](https://desktop.github.com). Please search the issue tracker to see if there is an existing issue for the problem you are experiencing. If you are experiencing issues with the Linux fork of GitHub Desktop please open an issue [in its repository](https://github.com/shiftkey/desktop). If you are experiencing issues with github.com please [contact GitHub Support](https://support.github.com/). - type: textarea id: the-problem attributes: diff --git a/.github/ISSUE_TEMPLATE/installation-issue.md b/.github/ISSUE_TEMPLATE/installation-issue.md new file mode 100644 index 00000000000..0d2175f7faa --- /dev/null +++ b/.github/ISSUE_TEMPLATE/installation-issue.md @@ -0,0 +1,21 @@ +--- +name: "\U0001F4BB Installation issue" +about: Report a problem when installing the application +title: '' +labels: '' +assignees: '' + +--- + +### Operating System/Distribution + +Which distribution of Linux are you using? + +### Installer + +Which version of the app? +Which installer type? + +### What happened? + +Provide as much detail as possible. Error messages or output are extremely useful. diff --git a/README.md b/README.md index 27a7e9d105f..17d59fe50b4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# [GitHub Desktop](https://desktop.github.com) +# [GitHub Desktop](https://desktop.github.com) - The Linux Fork + +[![CI](https://github.com/shiftkey/desktop/actions/workflows/ci.yml/badge.svg)](https://github.com/shiftkey/desktop/actions/workflows/ci.yml) [GitHub Desktop](https://desktop.github.com/) is an open-source [Electron](https://www.electronjs.org/)-based GitHub app. It is written in [TypeScript](https://www.typescriptlang.org) and @@ -16,81 +18,142 @@ uses [React](https://reactjs.org/). /> -## Where can I get it? +## What is this repository for? + +This repository contains specific patches on top of the upstream +`desktop/desktop` repository to support Linux usage. + +It also publishes [releases](https://github.com/shiftkey/desktop/releases) for various Linux distributions: + + - AppImage (`.AppImage`) + - Debian (`.deb`) + - RPM (`.rpm`) + +## Installation via package manager + +You can use your operating system's package manager to install `github-desktop` and +keep it up to date on Debian and RPM-based distributions. + +### Debian/Ubuntu + +There are two APT package feeds available, both hosted in the US. You only need +to add one or the other here, as both of these are generated based on the +releases from this repository. + +#### [@shiftkey](https://github.com/shiftkey) package feed + +```sh +wget -qO - https://apt.packages.shiftkey.dev/gpg.key | gpg --dearmor | sudo tee /usr/share/keyrings/shiftkey-packages.gpg > /dev/null +sudo sh -c 'echo "deb [arch=amd64 signed-by=/usr/share/keyrings/shiftkey-packages.gpg] https://apt.packages.shiftkey.dev/ubuntu/ any main" > /etc/apt/sources.list.d/shiftkey-packages.list' +``` + +#### [@mwt](https://github.com/mwt) package feed + +```sh +wget -qO - https://mirror.mwt.me/shiftkey-desktop/gpgkey | gpg --dearmor | sudo tee /usr/share/keyrings/mwt-desktop.gpg > /dev/null +sudo sh -c 'echo "deb [arch=amd64 signed-by=/usr/share/keyrings/mwt-desktop.gpg] https://mirror.mwt.me/shiftkey-desktop/deb/ any main" > /etc/apt/sources.list.d/mwt-desktop.list' +``` + +#### Installation + +Once you have a feed configured, run this command to install the application: + +```sh +sudo apt update && sudo apt install github-desktop +``` + +### Red Hat/CentOS/Fedora + +There are two RPM package feeds available, both hosted in the US. You only need +to add one or the other here, as both of these are generated based on the +releases from this repository. + +#### [@shiftkey](https://github.com/shiftkey) package feed + +```sh +sudo rpm --import https://rpm.packages.shiftkey.dev/gpg.key +sudo sh -c 'echo -e "[shiftkey-packages]\nname=GitHub Desktop\nbaseurl=https://rpm.packages.shiftkey.dev/rpm/\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=https://rpm.packages.shiftkey.dev/gpg.key" > /etc/yum.repos.d/shiftkey-packages.repo' +``` + +#### [@mwt](https://github.com/mwt) package feed + +```sh +sudo rpm --import https://mirror.mwt.me/shiftkey-desktop/gpgkey +sudo sh -c 'echo -e "[mwt-packages]\nname=GitHub Desktop\nbaseurl=https://mirror.mwt.me/shiftkey-desktop/rpm\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=https://mirror.mwt.me/shiftkey-desktop/gpgkey" > /etc/yum.repos.d/mwt-packages.repo' +``` -Download the official installer for your operating system: +#### Installation - - [macOS](https://central.github.com/deployments/desktop/desktop/latest/darwin) - - [macOS (Apple silicon)](https://central.github.com/deployments/desktop/desktop/latest/darwin-arm64) - - [Windows](https://central.github.com/deployments/desktop/desktop/latest/win32) - - [Windows machine-wide install](https://central.github.com/deployments/desktop/desktop/latest/win32?format=msi) +Once you have a feed configured, run this command to install the application: -Linux is not officially supported; however, you can find installers created for Linux from a fork of GitHub Desktop in the [Community Releases](https://github.com/desktop/desktop#community-releases) section. +```sh +# if yum is your package manager +sudo yum install github-desktop -### Beta Channel +# if dnf is your package manager +sudo dnf install github-desktop -Want to test out new features and get fixes before everyone else? Install the -beta channel to get access to early builds of Desktop: +# if zypper is your package manager +sudo zypper ref && sudo zypper in github-desktop +``` - - [macOS](https://central.github.com/deployments/desktop/desktop/latest/darwin?env=beta) - - [macOS (Apple silicon)](https://central.github.com/deployments/desktop/desktop/latest/darwin-arm64?env=beta) - - [Windows](https://central.github.com/deployments/desktop/desktop/latest/win32?env=beta) - - [Windows (ARM64)](https://central.github.com/deployments/desktop/desktop/latest/win32-arm64?env=beta) +#### OpenSUSE -The release notes for the latest beta versions are available [here](https://desktop.github.com/release-notes/?env=beta). +There are two RPM package feeds available, both hosted in the US. You only need +to add one or the other here, as both of these are generated based on the +releases from this repository. -### Past Releases -You can find past releases at https://desktop.githubusercontent.com. After installation of a past version, the auto update functionality will attempt to download the latest version. +#### [@shiftkey](https://github.com/shiftkey) package feed -### Community Releases +```sh +sudo rpm --import https://rpm.packages.shiftkey.dev/gpg.key +sudo sh -c 'echo -e "[shiftkey-packages]\nname=GitHub Desktop\nbaseurl=https://rpm.packages.shiftkey.dev/rpm/\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=https://rpm.packages.shiftkey.dev/gpg.key" > /etc/zypp/repos.d/shiftkey-packages.repo' +``` -There are several community-supported package managers that can be used to -install GitHub Desktop: - - Windows users can install using [winget](https://docs.microsoft.com/en-us/windows/package-manager/winget/) `c:\> winget install github-desktop` or [Chocolatey](https://chocolatey.org/) `c:\> choco install github-desktop` - - macOS users can install using [Homebrew](https://brew.sh/) package manager: - `$ brew install --cask github` +#### [@mwt](https://github.com/mwt) package feed -Installers for various Linux distributions can be found on the -[`shiftkey/desktop`](https://github.com/shiftkey/desktop) fork. +```sh +sudo rpm --import https://mirror.mwt.me/shiftkey-desktop/gpgkey +sudo sh -c 'echo -e "[mwt-packages]\nname=GitHub Desktop\nbaseurl=https://mirror.mwt.me/shiftkey-desktop/rpm\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=https://mirror.mwt.me/shiftkey-desktop/gpgkey" > /etc/zypp/repos.d/mwt-packages.repo' +``` -## Is GitHub Desktop right for me? What are the primary areas of focus? +#### Installation -[This document](https://github.com/desktop/desktop/blob/development/docs/process/what-is-desktop.md) describes the focus of GitHub Desktop and who the product is most useful for. +```sh +sudo zypper ref && sudo zypper in github-desktop +``` -## I have a problem with GitHub Desktop -Note: The [GitHub Desktop Code of Conduct](https://github.com/desktop/desktop/blob/development/CODE_OF_CONDUCT.md) applies in all interactions relating to the GitHub Desktop project. +## Other Distributions -First, please search the [open issues](https://github.com/desktop/desktop/issues?q=is%3Aopen) -and [closed issues](https://github.com/desktop/desktop/issues?q=is%3Aclosed) -to see if your issue hasn't already been reported (it may also be fixed). +### Arch Linux -There is also a list of [known issues](https://github.com/desktop/desktop/blob/development/docs/known-issues.md) -that are being tracked against Desktop, and some of these issues have workarounds. +Arch Linux users can install GitHub Desktop from the [AUR](https://aur.archlinux.org/packages/github-desktop-bin/). -If you can't find an issue that matches what you're seeing, open a [new issue](https://github.com/desktop/desktop/issues/new/choose), -choose the right template and provide us with enough information to investigate -further. +`gnome-keyring` is required and the daemon must be launched either at login or when the X server is started. Normally this is handled by a display manager, but in other cases following the instructions found on the [Arch Wiki](https://wiki.archlinux.org/index.php/GNOME/Keyring#Using_the_keyring_outside_GNOME) will fix the issue of not being able to save login credentials. -## The issue I reported isn't fixed yet. What can I do? +### Cross-Distribution Packages -If nobody has responded to your issue in a few days, you're welcome to respond to it with a friendly ping in the issue. Please do not respond more than a second time if nobody has responded. The GitHub Desktop maintainers are constrained in time and resources, and diagnosing individual configurations can be difficult and time consuming. While we'll try to at least get you pointed in the right direction, we can't guarantee we'll be able to dig too deeply into any one person's issue. +GitHub Desktop is also available cross-platform as a [Flatpak](https://github.com/flathub/io.github.shiftey.Desktop) and [AppImage](https://appimage.github.io/GitHubDesktop/). -## How can I contribute to GitHub Desktop? +### deb-get -The [CONTRIBUTING.md](./.github/CONTRIBUTING.md) document will help you get setup and -familiar with the source. The [documentation](docs/) folder also contains more -resources relevant to the project. +Debian/Ubuntu users can also install directly from this repository using [`deb-get`](https://github.com/wimpysworld/deb-get): `deb-get install github-desktop`. -If you're looking for something to work on, check out the [help wanted](https://github.com/desktop/desktop/issues?q=is%3Aissue+is%3Aopen+label%3A%22help%20wanted%22) label. +## Known issues -## Building Desktop +If you're having troubles with Desktop, please refer to the [Known issues](docs/known-issues.md#linux) +document for guidance and workarounds for common limitations. -To setup your development environment for building Desktop, check out: [`setup.md`](./docs/contributing/setup.md). +If your package manager is still trying to reach PackageCloud, refer to the +[cleanup instructions](docs/known-issues.md#the-packagecloud-package-feed-is-no-longer-working) +for details about migrating away. -## More Resources +## More information -See [desktop.github.com](https://desktop.github.com) for more product-oriented +Please check out the [README](https://github.com/desktop/desktop#github-desktop) +on the upstream [GitHub Desktop project](https://github.com/desktop/desktop) and +[desktop.github.com](https://desktop.github.com) for more product-oriented information about GitHub Desktop. See our [getting started documentation](https://docs.github.com/en/desktop/overview/getting-started-with-github-desktop) for more information on how to set up, authenticate, and configure GitHub Desktop. diff --git a/docs/installation.md b/docs/installation.md index 6681d22a00b..e931a69ab89 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -13,6 +13,15 @@ On Windows you have two options: - Download the `GitHubDesktopSetup.exe` and run it to install it for the current user. - Download the `GitHubDesktopSetup.msi` and run it to install a machine-wide version of GitHub Desktop - each logged-in user will then be able to run GitHub Desktop from the program at `%PROGRAMFILES(x86)\GitHub Desktop Installer\desktop.exe`. +### Linux + +On Linux there are four different package formats available, depending on your +distribution: + + - AppImage (`.AppImage`) + - Debian (`.deb`) + - RPM (`.rpm`) + ## Data Directories GitHub Desktop will create directories to manage the files and data it needs to function. If you manage a network of computers and want to install GitHub Desktop, here is more information about how things work. @@ -25,6 +34,12 @@ GitHub Desktop will create directories to manage the files and data it needs to - `%LOCALAPPDATA%\GitHubDesktop\` - contains the latest versions of the app, and some older versions if the user has updated from a previous version. - `%APPDATA%\GitHub Desktop\` - this directory contains user-specific data which the application requires to run, and is created on launch if it doesn't exist. Log files are also stored in this location. +### Linux + +This varies based on the installer chosen: + + - AppImage, Debian and RPM: `~/.config/GitHub Desktop/` + ## Log Files GitHub Desktop will generate logs as part of its normal usage, to assist with troubleshooting. They are located in the data directory that GitHub Desktop uses (see above) under a `logs` subdirectory, organized by date using the format `YYYY-MM-DD.desktop.production.log`, where `YYYY-MM-DD` is the day the log was created. diff --git a/docs/known-issues.md b/docs/known-issues.md index 2a8d7b89cbe..58987489f63 100644 --- a/docs/known-issues.md +++ b/docs/known-issues.md @@ -11,6 +11,10 @@ - [I get a black screen when launching Desktop](#i-get-a-black-screen-when-launching-desktop) - [Failed to open CA file after an update](#failed-to-open-ca-file-after-an-update) - [Authentication errors due to modified registry entries](#authentication-errors-due-to-modified-registry-entries) +- [Linux](#linux) + - [I get a white screen when launching Desktop](#i-get-a-white-screen-when-launching-desktop) + - [I cannot access repositories under my organization](#i-cannot-access-repositories-under-my-organization) + - [My shell/terminal is not detected and is stuck on "GNOME Terminal"](#my-shellterminal-is-not-detected-and-is-stuck-on-gnome-terminal) # Known Issues @@ -225,3 +229,61 @@ Related issue: [#15217](https://github.com/desktop/desktop/issues/15217) If you see an error that says "Not enough resources are available to process this command" when signing in to GitHub Desktop, it's likely that you have too many credentials stored in Windows Credentials Manager. **Workaround:** open the Credential Manager application, click on Windows Credentials and go through the list to see if there are some you can delete. + +## Linux + +### The PackageCloud package feed is no longer working + +The PackageCloud feed has been closed down. If you are seeing errors about this you should remove the configuration for this feed and refer to the [README](https://github.com/shiftkey/desktop#repositories) +for the new settings. + +#### APT configuration + +``` +sudo rm /etc/apt/trusted.gpg.d/shiftkey-desktop.asc +sudo rm /etc/apt/sources.list.d/packagecloud-shiftkey-desktop.list +``` + +#### RPM configuration + +``` +sudo rm /etc/apt/sources.list.d/packagecloud-shiftkey-desktop.list +``` + +### I get a white screen when launching Desktop + +Electron enables hardware accelerated graphics by default, but some graphics cards have issues with hardware acceleration which means the application will launch successfully but it will be a white screen. If you are running GitHub Desktop within virtualization software like Parallels Desktop, hardware accelerated graphics may not be available. + +**Workaround:** if you set the `GITHUB_DESKTOP_DISABLE_HARDWARE_ACCELERATION` environment variable to any value and launch Desktop again it will disable hardware acceleration on launch, so the application is usable. + +### I cannot access repositories under my organization + +The GitHub Desktop application is an OAuth application, but this fork does not +have the same permissions as the app does on Windows and macOS, which manifests +in a couple of different ways: + + - the "Clone a Repository" view does not show all organization repositories + - pushes to a repository owned by an organization may be rejected with a + generic error message + +The root cause of this is organizations by default will have "OAuth App access +restrictions" enabled, which blocks the GitHub Desktop development app that is +used by this fork. + +**Workaround:** ask your organization admin to [approve access](https://docs.github.com/en/organizations/restricting-access-to-your-organizations-data/approving-oauth-apps-for-your-organization) +to the GitHub Desktop development app. + +If you have not requested the GitHub Desktop development app for this organization, [follow these instructions first](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-your-membership-in-organizations/requesting-organization-approval-for-oauth-apps). + +### My shell/terminal is not detected and is stuck on GNOME Terminal + +On non-GNOME desktop's the GitHub Desktop application may not correctly set the +environment's shell, despite the shell being selected in the application settings. + +Attempting to launch the shell from the application will show the error +"cannot read property 'path' of undefined". + +**Workarounds:** + +- Option 1: install a second different terminal, switch to it, then switch to the terminal you want to use, and then uninstall the second terminal. +- Option 2: open the application's developer tools and step through the JS calls to correctly set the shell. Further details at https://github.com/shiftkey/desktop/issues/344#issuecomment-1001287110 diff --git a/docs/process/publishing-linux-releases.md b/docs/process/publishing-linux-releases.md new file mode 100644 index 00000000000..76a5648b68a --- /dev/null +++ b/docs/process/publishing-linux-releases.md @@ -0,0 +1,154 @@ +# Publishing Linux Releases + +This document outlines the steps I take once a release has been published from +the main GitHub Desktop project. + +This document assumes you have these remotes configured: + +``` +$ git remote -v +origin https://github.com/shiftkey/desktop (fetch) +origin https://github.com/shiftkey/desktop (push) +upstream https://github.com/desktop/desktop (fetch) +upstream https://github.com/desktop/desktop (push) +``` + +Ensure that `development` and `linux` are up-to-date: + +``` +$ git fetch --all +$ git checkout development +$ git reset upstream/development --hard +$ git push origin development +$ git checkout linux +$ git reset origin/linux --hard +$ git rebase development linux +``` + +We want to ensure our changes work against the current branch, so take some time +to rebase the changes and force push `linux` once you're done. + +``` +$ git push origin linux --force-with-lease +``` + +Wait for the continuous integration tests to pass. If `linux` is not passing the +continuous integration tests we need to investigate and identify why things are +no longer working. + +### 1. Create a branch from the release tag + +Each release tag from the upstream project matches the format `release-X.Y.Z` +where `X.Y.Z` are version numbers. We should create a corresponding branch in +this repository named `linux-release-X.Y.Z` as a starting point for the next +Linux release. + +On the command line, this looks like this (using the `2.1.3` release as an +example): + +``` +$ git checkout -b linux-release-2.1.3 release-2.1.3 +$ git push origin linux-release-2.1.3 -u +``` + +### 2. Open pull request to apply the necessary patches to the new branch + +The first step to cutting a release is to backport the latest fixes to the +release branch: + +``` +$ git checkout -b apply-changes-2.1.3 linux +$ git submodule update +$ git rebase --onto linux-release-2.1.3 development apply-changes-2.1.3 +``` + +Work through the conflicts reported until the branch is cleanly applied to the +previous release. + +When the branch is ready to go, push the branch to the remote: + +``` +$ git push origin apply-changes-2.1.3 -u +``` + +Open a pull request that targets `linux-release-2.1.3`. Review the changes and +ensure the tests pass. + +### 3. Approve and merge PR + +If we're satisifed with the pull request, we can merge the pull request to +update the release branch. + +Ensure **rebase and merge** is used here, as we want to preserve the commit +history as-is without introducing merge commits. + +If there are additional changes that need to go into the release, make sure to +include them + +### 4. Tag the release + +Ensure you are on the latest version that passes all tests: + +``` +$ git checkout linux-release-2.1.3 +$ git pull +``` + +We need to bump the version here to indicate this is not the exact same version +as the original release. The convention we follow is `release-X.Y.Z-linuxA` +where `A` is an auto-incrementing number (starting from 1). + +Update the `version` field in `app/package.json` to this new version. For +example, updating to the first release of `2.1.3` would look like this: + +```diff +diff --git a/app/package.json b/app/package.json +index fbbbb976f..3baaf9e33 100644 +--- a/app/package.json ++++ b/app/package.json +@@ -3,7 +3,7 @@ + "productName": "GitHub Desktop", + "bundleID": "com.github.GitHubClient", + "companyName": "GitHub, Inc.", +- "version": "2.1.0", ++ "version": "2.1.3-linux1", + "main": "./main.js", + "repository": { + "type": "git", +``` + +Commit and push this change to ensure we still pass the CI suite: + +``` +$ git commit -am "bump version for release" +$ git push +``` + +With this passing CI, we can tag this version to indicate this is what we are +releasing: + +``` +$ git tag release-2.1.3-linux1 +``` + +With those things in place, push the changes to the branch as well as the new +tag: + +``` +$ git push --follow-tags +``` + +### 5. Publish to GitHub + +After the tagged build completes, it will have the installers available as +artifacts. Over on Azure Pipelines - switch to the Releases tab and run "Publish +to Beta Channel" with the Snap release disabled +([**#204**](https://github.com/shiftkey/desktop/issues/202) is the tracking +issue for re-enabling that). + +When that is done, there should be a draft release available assigned to the tag +from earlier. Edit the release to add the release notes and checksums. + +**TODO:** it'd be great to have some sort of script to generate the release +notes from the changelog in this "markdown + sections" format, which would save +a lot of manual effort. From 270cb2a75a363d6b2b93d099411ac21c0ffa3f9c Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Thu, 1 Nov 2018 18:06:04 -0300 Subject: [PATCH 02/41] feat(tooling): add electron-builder config to repository (#254 #496) --- app/package.json | 2 +- package.json | 8 +- script/dist-info.ts | 2 +- script/electron-builder-linux.yml | 40 ++ script/package.ts | 95 +++++ yarn.lock | 665 ++++++++++++++++++++++++++++-- 6 files changed, 782 insertions(+), 30 deletions(-) create mode 100644 script/electron-builder-linux.yml diff --git a/app/package.json b/app/package.json index 4bbe615f602..c7aba52d449 100644 --- a/app/package.json +++ b/app/package.json @@ -1,5 +1,5 @@ { - "name": "desktop", + "name": "github-desktop", "productName": "GitHub Desktop", "bundleID": "com.github.GitHubClient", "companyName": "GitHub, Inc.", diff --git a/package.json b/package.json index ab8bd621697..768283306b1 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,10 @@ "webpack-bundle-analyzer": "^4.5.0", "webpack-dev-middleware": "^5.3.4", "webpack-hot-middleware": "^2.25.1", - "webpack-merge": "^6.0.1" + "webpack-merge": "^6.0.1", + "xml2js": "^0.5.0", + "xvfb-maybe": "^0.2.1", + "yaml": "^2.5.0" }, "devDependencies": { "@github/markdownlint-github": "^0.1.0", @@ -151,7 +154,10 @@ "@types/webpack": "^5.28.5", "@types/webpack-bundle-analyzer": "^4.7.0", "@types/webpack-hot-middleware": "^2.25.9", + "@types/webpack-merge": "^5.0.0", + "@types/xml2js": "^0.4.11", "electron": "32.1.2", + "electron-builder": "^24.13.3", "electron-packager": "^17.1.1", "electron-winstaller": "^5.0.0", "eslint-plugin-github": "^4.10.1", diff --git a/script/dist-info.ts b/script/dist-info.ts index e2ae688d55d..88a0bcbd4b4 100644 --- a/script/dist-info.ts +++ b/script/dist-info.ts @@ -25,7 +25,7 @@ export function getExecutableName() { if (process.platform === 'win32') { return `${getWindowsIdentifierName()}${suffix}` } else if (process.platform === 'linux') { - return 'desktop' + return `github-desktop${suffix}` } else { return productName } diff --git a/script/electron-builder-linux.yml b/script/electron-builder-linux.yml new file mode 100644 index 00000000000..01133639a58 --- /dev/null +++ b/script/electron-builder-linux.yml @@ -0,0 +1,40 @@ +artifactName: 'GitHubDesktop-${os}-${version}.${ext}' +linux: + category: 'GNOME;GTK;Development' + packageCategory: 'GNOME;GTK;Development' + icon: 'app/static/logos' + mimeTypes: + - x-scheme-handler/x-github-client + - x-scheme-handler/x-github-desktop-auth + # workaround for handling OAuth flow until we figure out what we're doing + # With the development OAuth details + # see https://github.com/shiftkey/desktop/issues/72 for more details + - x-scheme-handler/x-github-desktop-dev-auth + target: + - deb + - rpm + - AppImage + maintainer: 'GitHub, Inc ' +deb: + afterInstall: './script/linux-after-install.sh' + afterRemove: './script/linux-after-remove.sh' + depends: + # default Electron dependencies + - gconf2 + - gconf-service + - libnotify4 + - libappindicator1 + - libxtst6 + - libnss3 + # dugite-native dependencies + - libcurl3 | libcurl4 + # keytar dependencies + - libsecret-1-0 + - gnome-keyring +rpm: + depends: + # dugite-native dependencies + - libcurl + # keytar dependencies + - libsecret + - gnome-keyring diff --git a/script/package.ts b/script/package.ts index 1b1df20ac63..79dab238781 100644 --- a/script/package.ts +++ b/script/package.ts @@ -1,8 +1,14 @@ /* eslint-disable no-sync */ import * as cp from 'child_process' +import { chmodSync, createReadStream } from 'fs' +import { writeFile } from 'fs/promises' import * as path from 'path' import * as electronInstaller from 'electron-winstaller' +import * as crypto from 'crypto' + +import glob = require('glob') + import { getProductName, getCompanyName } from '../app/package-info' import { getDistPath, @@ -24,6 +30,7 @@ import { getVersion } from '../app/package-info' import { rename } from 'fs/promises' import { join } from 'path' import { assertNonNullable } from '../app/src/lib/fatal-error' +import { pathExistsSync } from 'fs-extra' const distPath = getDistPath() const productName = getProductName() @@ -39,6 +46,8 @@ if (process.platform === 'darwin') { packageOSX() } else if (process.platform === 'win32') { packageWindows() +} else if (process.platform === 'linux') { + packageLinux() } else { console.error(`I don't know how to package for ${process.platform} :(`) process.exit(1) @@ -157,3 +166,89 @@ function packageWindows() { process.exit(1) }) } + +function getSha256Checksum(fullPath: string): Promise { + return new Promise((resolve, reject) => { + const algo = 'sha256' + const shasum = crypto.createHash(algo) + + const s = createReadStream(fullPath) + s.on('data', function (d) { + shasum.update(d) + }) + s.on('error', err => { + reject(err) + }) + s.on('end', function () { + const d = shasum.digest('hex') + resolve(d) + }) + }) +} + +function generateChecksums() { + const distRoot = getDistRoot() + + const installersPath = `${distRoot}/GitHubDesktop-linux-*` + + glob(installersPath, async (error, files) => { + if (error != null) { + throw error + } + + const checksums = new Map() + + for (const f of files) { + const checksum = await getSha256Checksum(f) + checksums.set(f, checksum) + } + + let checksumsText = `Checksums: \n` + + for (const [fullPath, checksum] of checksums) { + const fileName = path.basename(fullPath) + checksumsText += `${checksum} - ${fileName}\n` + } + + const checksumFile = path.join(distRoot, 'checksums.txt') + + await writeFile(checksumFile, checksumsText) + }) +} + +function packageLinux() { + const helperPath = path.join(getDistPath(), 'chrome-sandbox') + const exists = pathExistsSync(helperPath) + + if (exists) { + console.log('Updating file mode for chrome-sandbox…') + chmodSync(helperPath, 0o4755) + } + + const electronBuilder = path.resolve( + __dirname, + '..', + 'node_modules', + '.bin', + 'electron-builder' + ) + + const configPath = path.resolve(__dirname, 'electron-builder-linux.yml') + + const args = [ + 'build', + '--prepackaged', + distPath, + '--x64', + '--config', + configPath, + ] + + const { error } = cp.spawnSync(electronBuilder, args, { stdio: 'inherit' }) + + if (error != null) { + throw error + } + + generateChecksums() +} diff --git a/yarn.lock b/yarn.lock index 558651b69a0..76b76199f01 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"7zip-bin@~5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/7zip-bin/-/7zip-bin-5.2.0.tgz#7a03314684dd6572b7dfa89e68ce31d60286854d" + integrity sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A== + "@aashutoshrathi/word-wrap@^1.2.3": version "1.2.6" resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" @@ -542,6 +547,14 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@develar/schema-utils@~2.6.5": + version "2.6.5" + resolved "https://registry.yarnpkg.com/@develar/schema-utils/-/schema-utils-2.6.5.tgz#3ece22c5838402419a6e0425f85742b961d9b6c6" + integrity sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig== + dependencies: + ajv "^6.12.0" + ajv-keywords "^3.4.1" + "@discoveryjs/json-ext@0.5.7": version "0.5.7" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" @@ -572,6 +585,15 @@ optionalDependencies: global-agent "^3.0.0" +"@electron/notarize@2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@electron/notarize/-/notarize-2.2.1.tgz#d0aa6bc43cba830c41bfd840b85dbe0e273f59fe" + integrity sha512-aL+bFMIkpR0cmmj5Zgy0LMKEpgy43/hw5zadEArgmAMWWlKc5buwFvFT9G/o/YJkvXAJm5q3iuTuLaiaXW39sg== + dependencies: + debug "^4.1.1" + fs-extra "^9.0.1" + promise-retry "^2.0.1" + "@electron/notarize@^1.2.3": version "1.2.3" resolved "https://registry.yarnpkg.com/@electron/notarize/-/notarize-1.2.3.tgz#38056a629e5a0b5fd56c975c4828c0f74285b644" @@ -580,6 +602,18 @@ debug "^4.1.1" fs-extra "^9.0.1" +"@electron/osx-sign@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@electron/osx-sign/-/osx-sign-1.0.5.tgz#0af7149f2fce44d1a8215660fd25a9fb610454d8" + integrity sha512-k9ZzUQtamSoweGQDV2jILiRIHUu7lYlJ3c6IEmjv1hC17rclE+eb9U+f6UFlOOETo0JzY1HNlXy4YOlCvl+Lww== + dependencies: + compare-version "^0.1.2" + debug "^4.3.4" + fs-extra "^10.0.0" + isbinaryfile "^4.0.8" + minimist "^1.2.6" + plist "^3.0.5" + "@electron/osx-sign@^1.0.1": version "1.0.4" resolved "https://registry.yarnpkg.com/@electron/osx-sign/-/osx-sign-1.0.4.tgz#8e91442846471636ca0469426a82b253b9170151" @@ -592,6 +626,19 @@ minimist "^1.2.6" plist "^3.0.5" +"@electron/universal@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@electron/universal/-/universal-1.5.1.tgz#f338bc5bcefef88573cf0ab1d5920fac10d06ee5" + integrity sha512-kbgXxyEauPJiQQUNG2VgUeyfQNFk6hBF11ISN2PNI6agUgPl55pv4eQmaqHzTAzchBvqZ2tQuRVaPStGf0mxGw== + dependencies: + "@electron/asar" "^3.2.1" + "@malept/cross-spawn-promise" "^1.1.0" + debug "^4.3.1" + dir-compare "^3.0.0" + fs-extra "^9.0.1" + minimatch "^3.0.4" + plist "^3.0.4" + "@electron/universal@^1.3.2": version "1.3.4" resolved "https://registry.yarnpkg.com/@electron/universal/-/universal-1.3.4.tgz#bccd94b635d7c85eeed5eabba457eb4ed2be2777" @@ -957,6 +1004,16 @@ dependencies: cross-spawn "^7.0.1" +"@malept/flatpak-bundler@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz#e8a32c30a95d20c2b1bb635cc580981a06389858" + integrity sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q== + dependencies: + debug "^4.1.1" + fs-extra "^9.0.0" + lodash "^4.17.15" + tmp-promise "^3.0.2" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1125,6 +1182,13 @@ dependencies: "@types/node" "*" +"@types/debug@^4.1.6": + version "4.1.8" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.8.tgz#cef723a5d0a90990313faec2d1e22aee5eecb317" + integrity sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ== + dependencies: + "@types/ms" "*" + "@types/deep-equal@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/deep-equal/-/deep-equal-1.0.1.tgz#71cfabb247c22bcc16d536111f50c0ed12476b03" @@ -1195,6 +1259,13 @@ dependencies: "@types/node" "*" +"@types/fs-extra@9.0.13", "@types/fs-extra@^9.0.11": + version "9.0.13" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.13.tgz#7594fbae04fe7f1918ce8b3d213f74ff44ac1f45" + integrity sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA== + dependencies: + "@types/node" "*" + "@types/fs-extra@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-7.0.0.tgz#9c4ad9e1339e7448a76698829def1f159c1b636c" @@ -1343,6 +1414,11 @@ resolved "https://registry.yarnpkg.com/@types/mri/-/mri-1.1.0.tgz#66555e4d797713789ea0fefdae0898d8170bf5af" integrity sha512-fMl88ZoZXOB7VKazJ6wUMpZc9QIn+jcigSFRf2K/rrw4DcXn+/uGxlWX8DDlcE7JkwgIZ7BDH+JgxZPlc/Ap3g== +"@types/ms@*": + version "0.7.31" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" + integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== + "@types/node@*": version "22.5.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.1.tgz#de01dce265f6b99ed32b295962045d10b5b99560" @@ -1369,7 +1445,7 @@ resolved "https://registry.yarnpkg.com/@types/parse-dds/-/parse-dds-1.0.3.tgz#a1bb00421906094510d88c64af978564d3c35c9b" integrity sha512-LD9BruIpfP6Z9aAJ488h+PwtSwLzM0NO+Rs1l/zjcPLBTqR31OnIGmAvJYhGiHhbOn7R0YXw1gL5bImNiK6HNw== -"@types/plist@^3.0.2": +"@types/plist@^3.0.1", "@types/plist@^3.0.2": version "3.0.2" resolved "https://registry.yarnpkg.com/@types/plist/-/plist-3.0.2.tgz#61b3727bba0f5c462fe333542534a0c3e19ccb01" integrity sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw== @@ -1572,6 +1648,11 @@ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-3.4.9.tgz#fcf01997bbc9f7c09ae5f91383af076d466594e1" integrity sha512-XDwyIlt/47l2kWLTzw/mtrpLdB+GPSskR2n/PIcPn+VYhVO77rGhRncIR5GPU0KRzXuqkDO+J5qqrG0Y8P6jzQ== +"@types/verror@^1.10.3": + version "1.10.6" + resolved "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.6.tgz#3e600c62d210c5826460858f84bcbb65805460bb" + integrity sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ== + "@types/webgl2@^0.0.11": version "0.0.11" resolved "https://registry.yarnpkg.com/@types/webgl2/-/webgl2-0.0.11.tgz#a54d56775816c86725cc9fefdc3c90619eabce5a" @@ -1595,6 +1676,13 @@ tapable "^2.2.0" webpack "^5" +"@types/webpack-merge@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@types/webpack-merge/-/webpack-merge-5.0.0.tgz#818a13948c1642bde7e2f4f079335a5f85365699" + integrity sha512-CFedsXD/7vmJ66PaC3eavdqqNZujWlvdkGFcizi0QPtDswK75DV7a5GTKzL9Ev6d0okLurq+ebQjwIEFmP9aZw== + dependencies: + webpack-merge "*" + "@types/webpack@^5.28.5": version "5.28.5" resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-5.28.5.tgz#0e9d9a15efa09bbda2cef41356ca4ac2031ea9a2" @@ -1604,6 +1692,13 @@ tapable "^2.2.0" webpack "^5" +"@types/xml2js@^0.4.11": + version "0.4.14" + resolved "https://registry.yarnpkg.com/@types/xml2js/-/xml2js-0.4.14.tgz#5d462a2a7330345e2309c6b549a183a376de8f9a" + integrity sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ== + dependencies: + "@types/node" "*" + "@types/yargs-parser@*": version "15.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" @@ -2088,7 +2183,7 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" -ajv-keywords@^3.5.2: +ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== @@ -2108,7 +2203,7 @@ ajv@^4.9.2: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^6.12.4, ajv@^6.12.5: +ajv@^6.10.0, ajv@^6.12.0, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -2200,6 +2295,44 @@ anymatch@^3.0.3, anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" +app-builder-bin@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-4.0.0.tgz#1df8e654bd1395e4a319d82545c98667d7eed2f0" + integrity sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA== + +app-builder-lib@24.13.3: + version "24.13.3" + resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-24.13.3.tgz#36e47b65fecb8780bb73bff0fee4e0480c28274b" + integrity sha512-FAzX6IBit2POXYGnTCT8YHFO/lr5AapAII6zzhQO3Rw4cEDOgK+t1xhLc5tNcKlicTHlo9zxIwnYCX9X2DLkig== + dependencies: + "@develar/schema-utils" "~2.6.5" + "@electron/notarize" "2.2.1" + "@electron/osx-sign" "1.0.5" + "@electron/universal" "1.5.1" + "@malept/flatpak-bundler" "^0.4.0" + "@types/fs-extra" "9.0.13" + async-exit-hook "^2.0.1" + bluebird-lst "^1.0.9" + builder-util "24.13.1" + builder-util-runtime "9.2.4" + chromium-pickle-js "^0.2.0" + debug "^4.3.4" + ejs "^3.1.8" + electron-publish "24.13.1" + form-data "^4.0.0" + fs-extra "^10.1.0" + hosted-git-info "^4.1.0" + is-ci "^3.0.0" + isbinaryfile "^5.0.0" + js-yaml "^4.1.0" + lazy-val "^1.0.5" + minimatch "^5.1.1" + read-config-file "6.3.2" + sanitize-filename "^1.6.3" + semver "^7.3.8" + tar "^6.1.12" + temp-file "^3.4.0" + are-docs-informative@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/are-docs-informative/-/are-docs-informative-0.0.2.tgz#387f0e93f5d45280373d387a59d34c96db321963" @@ -2373,11 +2506,31 @@ asar@^2.0.1: mkdirp "^0.5.1" tmp-promise "^1.0.5" +assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + ast-types-flow@^0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +async-exit-hook@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/async-exit-hook/-/async-exit-hook-2.0.1.tgz#8bd8b024b0ec9b1c01cccb9af9db29bd717dfaf3" + integrity sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw== + +async@^3.2.3: + version "3.2.4" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + asynciterator.prototype@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz#8c5df0514936cdd133604dfcc9d3fb93f09b2b62" @@ -2489,7 +2642,7 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-js@^1.5.1: +base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -2509,11 +2662,23 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== +bluebird-lst@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/bluebird-lst/-/bluebird-lst-1.0.9.tgz#a64a0e4365658b9ab5fe875eb9dfb694189bb41c" + integrity sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw== + dependencies: + bluebird "^3.5.5" + bluebird@^3.0.6, bluebird@^3.1.1, bluebird@^3.5.0: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" integrity sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA== +bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + boolbase@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" @@ -2607,6 +2772,44 @@ buffer-from@^1.1.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== +buffer@^5.1.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +builder-util-runtime@9.2.4: + version "9.2.4" + resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz#13cd1763da621e53458739a1e63f7fcba673c42a" + integrity sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA== + dependencies: + debug "^4.3.4" + sax "^1.2.4" + +builder-util@24.13.1: + version "24.13.1" + resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-24.13.1.tgz#4a4c4f9466b016b85c6990a0ea15aa14edec6816" + integrity sha512-NhbCSIntruNDTOVI9fdXz0dihaqX2YuE1D6zZMrwiErzH4ELZHE6mdiB40wEgZNprDia+FghRFgKoAqMZRRjSA== + dependencies: + "7zip-bin" "~5.2.0" + "@types/debug" "^4.1.6" + app-builder-bin "4.0.0" + bluebird-lst "^1.0.9" + builder-util-runtime "9.2.4" + chalk "^4.1.2" + cross-spawn "^7.0.3" + debug "^4.3.4" + fs-extra "^10.1.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.1" + is-ci "^3.0.0" + js-yaml "^4.1.0" + source-map-support "^0.5.19" + stat-mode "^1.0.0" + temp-file "^3.4.0" + builtin-modules@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -2702,15 +2905,7 @@ chalk@^2.0.0, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^4.1.0: +chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -2743,6 +2938,11 @@ char-regex@^1.0.2: optionalDependencies: fsevents "~2.1.2" +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + chrome-trace-event@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" @@ -2754,9 +2954,9 @@ chromium-pickle-js@^0.2.0: integrity sha1-BKEGZywYsIWrd02YPfo+oTjyIgU= ci-info@^3.2.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" - integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== + version "3.8.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== cjs-module-lexer@^1.0.0: version "1.2.3" @@ -2775,6 +2975,14 @@ clean-css@^5.2.2: dependencies: source-map "~0.6.0" +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + cliui@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" @@ -2886,6 +3094,14 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +config-file-ts@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/config-file-ts/-/config-file-ts-0.2.4.tgz#6c0741fbe118a7cf786c65f139030f0448a2cc99" + integrity sha512-cKSW0BfrSaAUnxpgvpXPLaaW/umg4bqg4k3GO1JqlRfpx+d5W0GDXznCMkWotJQek5Mmz1MJVChQnz3IVaeMZQ== + dependencies: + glob "^7.1.6" + typescript "^4.0.2" + console-polyfill@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/console-polyfill/-/console-polyfill-0.3.0.tgz#84900902a18c47a5eba932be75fa44d23e8af861" @@ -2896,6 +3112,18 @@ convert-source-map@^2.0.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +crc@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/crc/-/crc-3.8.0.tgz#ad60269c2c856f8c299e2c4cc0de4556914056c6" + integrity sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ== + dependencies: + buffer "^5.1.0" + create-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" @@ -2925,7 +3153,7 @@ cross-spawn-windows-exe@^1.1.0, cross-spawn-windows-exe@^1.2.0: is-wsl "^2.2.0" which "^2.0.2" -cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -2934,6 +3162,15 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +cross-spawn@^7.0.1: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.2.tgz#d0d7dcfa74e89115c7619f4f721a94e1fdb716d6" + integrity sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + css-loader@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-7.1.2.tgz#64671541c6efe06b0e22e750503106bdd86880f8" @@ -3196,6 +3433,34 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" +dmg-builder@24.13.3: + version "24.13.3" + resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-24.13.3.tgz#95d5b99c587c592f90d168a616d7ec55907c7e55" + integrity sha512-rcJUkMfnJpfCboZoOOPf4L29TRtEieHNOeAbYPWPxlaBw/Z1RKrRA86dOI9rwaI4tQSc/RD82zTNHprfUHXsoQ== + dependencies: + app-builder-lib "24.13.3" + builder-util "24.13.1" + builder-util-runtime "9.2.4" + fs-extra "^10.1.0" + iconv-lite "^0.6.2" + js-yaml "^4.1.0" + optionalDependencies: + dmg-license "^1.0.11" + +dmg-license@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/dmg-license/-/dmg-license-1.0.11.tgz#7b3bc3745d1b52be7506b4ee80cb61df6e4cd79a" + integrity sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q== + dependencies: + "@types/plist" "^3.0.1" + "@types/verror" "^1.10.3" + ajv "^6.10.0" + crc "^3.8.0" + iconv-corefoundation "^1.1.7" + plist "^3.0.4" + smart-buffer "^4.0.2" + verror "^1.10.0" + doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -3262,6 +3527,16 @@ dot-case@^3.0.4: no-case "^3.0.4" tslib "^2.0.3" +dotenv-expand@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" + integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== + +dotenv@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-9.0.2.tgz#dacc20160935a37dea6364aa1bef819fb9b6ab05" + integrity sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg== + duplexer@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" @@ -3277,6 +3552,30 @@ easy-stack@^1.0.0: resolved "https://registry.yarnpkg.com/easy-stack/-/easy-stack-1.0.0.tgz#12c91b3085a37f0baa336e9486eac4bf94e3e788" integrity sha1-EskbMIWjfwuqM26UhurEv5Tj54g= +ejs@^3.1.8: + version "3.1.9" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" + integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== + dependencies: + jake "^10.8.5" + +electron-builder@^24.13.3: + version "24.13.3" + resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-24.13.3.tgz#c506dfebd36d9a50a83ee8aa32d803d83dbe4616" + integrity sha512-yZSgVHft5dNVlo31qmJAe4BVKQfFdwpRw7sFp1iQglDRCDD6r22zfRJuZlhtB5gp9FHUxCMEoWGq10SkCnMAIg== + dependencies: + app-builder-lib "24.13.3" + builder-util "24.13.1" + builder-util-runtime "9.2.4" + chalk "^4.1.2" + dmg-builder "24.13.3" + fs-extra "^10.1.0" + is-ci "^3.0.0" + lazy-val "^1.0.5" + read-config-file "6.3.2" + simple-update-notifier "2.0.0" + yargs "^17.6.2" + electron-packager@^17.1.1: version "17.1.1" resolved "https://registry.yarnpkg.com/electron-packager/-/electron-packager-17.1.1.tgz#f156fc63d3a66f4e902e4b42992550a172982d59" @@ -3302,7 +3601,25 @@ electron-packager@^17.1.1: semver "^7.1.3" yargs-parser "^21.1.1" -electron-to-chromium@^1.4.202, electron-to-chromium@^1.5.4: +electron-publish@24.13.1: + version "24.13.1" + resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-24.13.1.tgz#57289b2f7af18737dc2ad134668cdd4a1b574a0c" + integrity sha512-2ZgdEqJ8e9D17Hwp5LEq5mLQPjqU3lv/IALvgp+4W8VeNhryfGhYEQC/PgDPMrnWUp+l60Ou5SJLsu+k4mhQ8A== + dependencies: + "@types/fs-extra" "^9.0.11" + builder-util "24.13.1" + builder-util-runtime "9.2.4" + chalk "^4.1.2" + fs-extra "^10.1.0" + lazy-val "^1.0.5" + mime "^2.5.2" + +electron-to-chromium@^1.4.202: + version "1.4.233" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.233.tgz#aa142e45468bda111b88abc9cc59d573b75d6a60" + integrity sha512-ejwIKXTg1wqbmkcRJh9Ur3hFGHFDZDw1POzdsVrB2WZjgRuRMHIQQKNpe64N/qh3ZtH2otEoRoS+s6arAAuAAw== + +electron-to-chromium@^1.5.4: version "1.5.13" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz#1abf0410c5344b2b829b7247e031f02810d442e6" integrity sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q== @@ -3395,6 +3712,11 @@ env-paths@^2.2.0: resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + errno@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" @@ -4018,6 +4340,11 @@ extract-zip@^2.0.0, extract-zip@^2.0.1: optionalDependencies: "@types/yauzl" "^2.9.1" +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + fake-indexeddb@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/fake-indexeddb/-/fake-indexeddb-5.0.1.tgz#1111a2b6981eaaad03027d816a8536a940d36cee" @@ -4100,6 +4427,13 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" +filelist@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== + dependencies: + minimatch "^5.0.1" + filename-reserved-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" @@ -4238,6 +4572,16 @@ fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^9.0.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-extra@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" @@ -4248,6 +4592,13 @@ fs-extra@^9.0.1: jsonfile "^6.0.1" universalify "^1.0.0" +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + fs-monkey@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.5.tgz#fe450175f0db0d7ea758102e1d84096acb925788" @@ -4671,6 +5022,13 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== +hosted-git-info@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" + integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== + dependencies: + lru-cache "^6.0.0" + html-encoding-sniffer@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9" @@ -4778,7 +5136,15 @@ human-signals@^4.3.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== -iconv-lite@0.6.3: +iconv-corefoundation@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz#31065e6ab2c9272154c8b0821151e2c88f1b002a" + integrity sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ== + dependencies: + cli-truncate "^2.1.0" + node-addon-api "^1.6.3" + +iconv-lite@0.6.3, iconv-lite@^0.6.2: version "0.6.3" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== @@ -4790,6 +5156,11 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore@^5.0.5, ignore@^5.2.0, ignore@~5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" @@ -4937,6 +5308,13 @@ is-callable@^1.2.7: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== +is-ci@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" + integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== + dependencies: + ci-info "^3.2.0" + is-core-module@^2.13.0: version "2.13.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" @@ -5172,6 +5550,11 @@ isbinaryfile@^4.0.8: resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== +isbinaryfile@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-5.0.0.tgz#034b7e54989dab8986598cbcea41f66663c65234" + integrity sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -5260,6 +5643,16 @@ jackspeak@^4.0.1: optionalDependencies: "@pkgjs/parseargs" "^0.11.0" +jake@^10.8.5: + version "10.8.7" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" + integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== + dependencies: + async "^3.2.3" + chalk "^4.0.2" + filelist "^1.0.4" + minimatch "^3.1.2" + jest-changed-files@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" @@ -5666,7 +6059,15 @@ js-queue@2.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.10.0, js-yaml@^3.13.1: +js-yaml@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" + integrity sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@^3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== @@ -5772,7 +6173,7 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.2.3: +json5@^2.2.0, json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -5882,6 +6283,11 @@ language-tags@=1.0.5: dependencies: language-subtag-registry "~0.3.2" +lazy-val@^1.0.4, lazy-val@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.5.tgz#6cf3b9f5bc31cee7ee3e369c0832b7583dcd923d" + integrity sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q== + legal-eagle@0.16.0: version "0.16.0" resolved "https://registry.yarnpkg.com/legal-eagle/-/legal-eagle-0.16.0.tgz#bd3d136dd1b761a540bad898ace68f4009412575" @@ -6191,6 +6597,11 @@ mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31: dependencies: mime-db "1.52.0" +mime@^2.5.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -6240,6 +6651,13 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" +minimatch@^5.1.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + minimatch@~5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" @@ -6257,11 +6675,31 @@ minimist@^1.2.0, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== +minipass@^3.0.0: + version "3.3.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== + dependencies: + yallist "^4.0.0" + +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + minipass@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== +minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" @@ -6269,6 +6707,11 @@ mkdirp@^0.5.1: dependencies: minimist "0.0.8" +mkdirp@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + mrmime@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-2.0.0.tgz#151082a6e06e59a9a39b46b3e14d5cfe92b3abb4" @@ -6312,6 +6755,11 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" +node-addon-api@^1.6.3: + version "1.7.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.7.2.tgz#3df30b95720b53c24e59948b49532b662444f54d" + integrity sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -6888,6 +7336,14 @@ progress@^2.0.3: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + promise.prototype.finally@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.0.tgz#66f161b1643636e50e7cf201dc1b84a857f3864e" @@ -6993,6 +7449,18 @@ react-is@^18.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== +read-config-file@6.3.2: + version "6.3.2" + resolved "https://registry.yarnpkg.com/read-config-file/-/read-config-file-6.3.2.tgz#556891aa6ffabced916ed57457cb192e61880411" + integrity sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q== + dependencies: + config-file-ts "^0.2.4" + dotenv "^9.0.2" + dotenv-expand "^5.1.0" + js-yaml "^4.1.0" + json5 "^2.2.0" + lazy-val "^1.0.4" + read-installed@4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067" @@ -7190,6 +7658,11 @@ responselike@^2.0.0: dependencies: lowercase-keys "^2.0.0" +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -7200,7 +7673,7 @@ ric-shim@^1.0.0: resolved "https://registry.yarnpkg.com/ric-shim/-/ric-shim-1.0.0.tgz#a20a8edfcbd05f304b58a1b52a846d53baccacf4" integrity sha1-ogqO38vQXzBLWKG1KoRtU7rMrPQ= -rimraf@^3.0.2: +rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -7287,6 +7760,13 @@ safe-regex-test@^1.0.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sanitize-filename@^1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.3.tgz#755ebd752045931977e30b2025d340d7c9090378" + integrity sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg== + dependencies: + truncate-utf8-bytes "^1.0.0" + sass-loader@^16.0.0: version "16.0.0" resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-16.0.0.tgz#9b8d497e24bc176dc368df2b5b9e90b4ad24bf4e" @@ -7301,6 +7781,11 @@ sass@^1.27.0: dependencies: chokidar ">=2.0.0 <4.0.0" +sax@>=0.6.0, sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + saxes@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5" @@ -7347,14 +7832,21 @@ semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.1.3, semver@^7.3.2, semver@^7.3.4: +semver@^7.1.3, semver@^7.3.2: version "7.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.0.tgz#ed8c5dc8efb6c629c88b23d41dc9bf40c1d96cd0" integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== dependencies: lru-cache "^6.0.0" -semver@^7.3.7, semver@^7.5.3, semver@^7.5.4: +semver@^7.3.4: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -7437,6 +7929,13 @@ signal-exit@^4.0.1: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== +simple-update-notifier@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz#d70b92bdab7d6d90dfd73931195a30b6e3d7cebb" + integrity sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w== + dependencies: + semver "^7.5.3" + sirv@^2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/sirv/-/sirv-2.0.4.tgz#5dd9a725c578e34e449f332703eb2a74e46a29b0" @@ -7461,11 +7960,25 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + slide@~1.1.3: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= +smart-buffer@^4.0.2: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + smoothscroll-polyfill@^0.3.6: version "0.3.6" resolved "https://registry.yarnpkg.com/smoothscroll-polyfill/-/smoothscroll-polyfill-0.3.6.tgz#492be845195157cdc2fc529a95d89e7a71509172" @@ -7484,7 +7997,7 @@ source-map-support@0.5.13: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@^0.5.6, source-map-support@~0.5.20: +source-map-support@^0.5.19, source-map-support@^0.5.6, source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -7549,6 +8062,11 @@ stack-utils@^2.0.3: dependencies: escape-string-regexp "^2.0.0" +stat-mode@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-1.0.0.tgz#68b55cb61ea639ff57136f36b216a291800d1465" + integrity sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg== + string-length@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.1.tgz#4a973bf31ef77c4edbceadd6af2611996985f8a1" @@ -7827,6 +8345,26 @@ tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tar@^6.1.12: + version "6.1.15" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.15.tgz#c9738b0b98845a3b344d334b8fa3041aaba53a69" + integrity sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +temp-file@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/temp-file/-/temp-file-3.4.0.tgz#766ea28911c683996c248ef1a20eea04d51652c7" + integrity sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg== + dependencies: + async-exit-hook "^2.0.1" + fs-extra "^10.0.0" + temp@^0.9.0: version "0.9.1" resolved "https://registry.yarnpkg.com/temp/-/temp-0.9.1.tgz#2d666114fafa26966cd4065996d7ceedd4dd4697" @@ -7882,6 +8420,13 @@ tmp-promise@^1.0.5: bluebird "^3.5.0" tmp "0.0.33" +tmp-promise@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.3.tgz#60a1a1cc98c988674fcbfd23b6e3367bdeac4ce7" + integrity sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ== + dependencies: + tmp "^0.2.0" + tmp@0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -7889,6 +8434,13 @@ tmp@0.0.33: dependencies: os-tmpdir "~1.0.2" +tmp@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -7954,6 +8506,13 @@ trim-repeated@^1.0.0: dependencies: escape-string-regexp "^1.0.2" +truncate-utf8-bytes@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b" + integrity sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ== + dependencies: + utf8-byte-length "^1.0.1" + ts-api-utils@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" @@ -8110,6 +8669,11 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" +typescript@^4.0.2: + version "4.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== + typescript@^5.6.3: version "5.6.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b" @@ -8203,6 +8767,11 @@ url-parse@^1.5.3: querystringify "^2.1.1" requires-port "^1.0.0" +utf8-byte-length@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61" + integrity sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA== + util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -8235,6 +8804,15 @@ validate-npm-package-license@^3.0.1: spdx-correct "~1.0.0" spdx-expression-parse "~1.0.0" +verror@^1.10.0: + version "1.10.1" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.1.tgz#4bf09eeccf4563b109ed4b3d458380c972b0cdeb" + integrity sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + vscode-json-languageservice@^3.7.0: version "3.8.0" resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.8.0.tgz#c7e7283f993e3db39fa5501407b023ada6fd3ae3" @@ -8331,7 +8909,7 @@ webpack-hot-middleware@^2.25.1: html-entities "^2.1.0" strip-ansi "^6.0.0" -webpack-merge@^6.0.1: +webpack-merge@*, webpack-merge@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-6.0.1.tgz#50c776868e080574725abc5869bd6e4ef0a16c6a" integrity sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg== @@ -8460,6 +9038,13 @@ which-typed-array@^1.1.9: gopd "^1.0.1" has-tostringtag "^1.0.0" +which@^1.2.4: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -8531,11 +9116,24 @@ xml-name-validator@^4.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835" integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== +xml2js@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.5.0.tgz#d9440631fbb2ed800203fad106f2724f62c493b7" + integrity sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + xmlbuilder@>=11.0.1, xmlbuilder@^15.1.1: version "15.1.1" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz#9dcdce49eea66d8d10b42cae94a79c3c8d0c2ec5" integrity sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg== +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + xmlchars@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" @@ -8546,6 +9144,14 @@ xtend@^4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= +xvfb-maybe@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/xvfb-maybe/-/xvfb-maybe-0.2.1.tgz#ed8cb132957b7848b439984c66f010ea7f24361b" + integrity sha1-7YyxMpV7eEi0OZhMZvAQ6n8kNhs= + dependencies: + debug "^2.2.0" + which "^1.2.4" + y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" @@ -8561,12 +9167,17 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.0.tgz#c6165a721cf8000e91c36490a41d7be25176cf5d" + integrity sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw== + yargs-parser@^21.0.1, yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== -yargs@^17.3.1: +yargs@^17.3.1, yargs@^17.6.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== From 6965227fdab5443cf70329ba3e94aff7700d4a2e Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Fri, 19 Apr 2019 10:05:03 -0300 Subject: [PATCH 03/41] fix: redirect in-app menu for reporting an issue to the fork (#141) --- app/src/main-process/menu/build-default-menu.ts | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/app/src/main-process/menu/build-default-menu.ts b/app/src/main-process/menu/build-default-menu.ts index 05ac2581e25..1f57244ea5d 100644 --- a/app/src/main-process/menu/build-default-menu.ts +++ b/app/src/main-process/menu/build-default-menu.ts @@ -1,4 +1,4 @@ -import { Menu, shell, app, BrowserWindow } from 'electron' +import { Menu, shell, BrowserWindow } from 'electron' import { ensureItemIds } from './ensure-item-ids' import { MenuEvent } from './menu-event' import { truncateWithEllipsis } from '../../lib/truncate-with-ellipsis' @@ -486,22 +486,11 @@ export function buildDefaultMenu({ label: __DARWIN__ ? 'Report Issue…' : 'Report issue…', click() { shell - .openExternal('https://github.com/desktop/desktop/issues/new/choose') + .openExternal('https://github.com/shiftkey/desktop/issues/new/choose') .catch(err => log.error('Failed opening issue creation page', err)) }, } - const contactSupportItem: Electron.MenuItemConstructorOptions = { - label: __DARWIN__ ? 'Contact GitHub Support…' : '&Contact GitHub support…', - click() { - shell - .openExternal( - `https://github.com/contact?from_desktop_app=1&app_version=${app.getVersion()}` - ) - .catch(err => log.error('Failed opening contact support page', err)) - }, - } - const showUserGuides: Electron.MenuItemConstructorOptions = { label: 'Show User Guides', click() { @@ -540,7 +529,6 @@ export function buildDefaultMenu({ const helpItems = [ submitIssueItem, - contactSupportItem, showUserGuides, showKeyboardShortcuts, showLogsItem, From ae9d97fd7aed723c972379710cb1653fced6ad4f Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Thu, 30 May 2019 16:47:05 -0300 Subject: [PATCH 04/41] fix: allow users to view the app at very low resolution screens --- app/src/main-process/app-window.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main-process/app-window.ts b/app/src/main-process/app-window.ts index c5ee06f0560..fd9992b9656 100644 --- a/app/src/main-process/app-window.ts +++ b/app/src/main-process/app-window.ts @@ -78,6 +78,12 @@ export class AppWindow { windowOptions.frame = false } else if (__LINUX__) { windowOptions.icon = path.join(__dirname, 'static', 'icon-logo.png') + + // relax restriction here for users trying to run app at a small + // resolution and any other side-effects of dropping this restriction are + // currently unsupported + delete windowOptions.minHeight + delete windowOptions.minWidth } this.window = new BrowserWindow(windowOptions) From 2d72611260fd77ac3800ba54d343a9f4458d064c Mon Sep 17 00:00:00 2001 From: jfgordon2 <55799997+jfgordon2@users.noreply.github.com> Date: Sun, 29 Mar 2020 16:01:51 -0500 Subject: [PATCH 05/41] feat: add command line script to debian package (#231 #239) --- app/static/linux/github | 35 +++++++++++++++++++++++++++++++++++ script/linux-after-install.sh | 33 +++++++++++++++++++++++++++++++++ script/linux-after-remove.sh | 24 ++++++++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 app/static/linux/github create mode 100644 script/linux-after-install.sh create mode 100644 script/linux-after-remove.sh diff --git a/app/static/linux/github b/app/static/linux/github new file mode 100644 index 00000000000..0f7513eb244 --- /dev/null +++ b/app/static/linux/github @@ -0,0 +1,35 @@ +#!/bin/sh + +if [ ! -L "$0" ]; then + # if path is not a symlink, find relatively + GITHUB_PATH=$(dirname "$(dirname "$(dirname "$(dirname "$0")")")") +else + if command -v readlink >/dev/null; then + # if readlink exists, follow the symlink and then find relatively + SYMLINK=$(readlink -f "$0") + GITHUB_PATH=$(dirname "$(dirname "$(dirname "$(dirname "$SYMLINK")")")") + else + # else use the standard install location + GITHUB_PATH="/opt/GitHub Desktop" + fi +fi +# check if this is a dev install or standard +if [ -f "$GITHUB_PATH/github-desktop-dev" ]; then + BINARY_NAME="github-desktop-dev" +else + BINARY_NAME="github-desktop" +fi + +ELECTRON="$GITHUB_PATH/$BINARY_NAME" +CLI="$GITHUB_PATH/resources/app/cli.js" + +case $1 in + # if help in the first variable, return contents to shell + *help*|*--help*) + ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@";; + # any other, redirect to /dev/null to detach from controlling terminal + *) + ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@" < /dev/null > /dev/null &;; +esac + +exit $? diff --git a/script/linux-after-install.sh b/script/linux-after-install.sh new file mode 100644 index 00000000000..204b930b83d --- /dev/null +++ b/script/linux-after-install.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +set -e + +PROFILE_D_FILE="/etc/profile.d/github-desktop.sh" +INSTALL_DIR="/opt/${productFilename}" +CLI_DIR="$INSTALL_DIR/resources/app/static" + +case "$1" in + configure) + # add executable permissions for CLI interface + chmod +x "$CLI_DIR"/github || : + # check if this is a dev install or standard + if [ -f "$INSTALL_DIR/github-desktop-dev" ]; then + BINARY_NAME="github-desktop-dev" + else + BINARY_NAME="github-desktop" + fi + # create symbolic links to /usr/bin directory + ln -f -s "$INSTALL_DIR"/$BINARY_NAME /usr/bin || : + ln -f -s "$CLI_DIR"/github /usr/bin || : + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +exit 0 \ No newline at end of file diff --git a/script/linux-after-remove.sh b/script/linux-after-remove.sh new file mode 100644 index 00000000000..d85b3eb28e8 --- /dev/null +++ b/script/linux-after-remove.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -e + +PROFILE_D_FILE="/etc/profile.d/github-desktop.sh" +BASE_FILE="/usr/bin/github" + +case "$1" in + purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) + echo "#!/bin/sh" > "${PROFILE_D_FILE}"; + . "${PROFILE_D_FILE}"; + rm "${PROFILE_D_FILE}"; + # remove symbolic links in /usr/bin directory + test -f ${BASE_FILE} && unlink ${BASE_FILE} + test -f ${BASE_FILE}-desktop && unlink ${BASE_FILE}-desktop + test -f ${BASE_FILE}-desktop-dev && unlink ${BASE_FILE}-desktop-dev + ;; + + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +exit 0 From d98d24f470e5775e7a76ee360db3b165f421d841 Mon Sep 17 00:00:00 2001 From: jfgordon2 <55799997+jfgordon2@users.noreply.github.com> Date: Mon, 30 Mar 2020 12:06:52 -0500 Subject: [PATCH 06/41] fix: update About modal by hiding unsupported features on Linux (#241) Updated the "About GitHub Desktop" model to remove the button to check for updates (since it didn't do anything on Linux) and replace with a link to the linux releases page --- app/src/ui/about/about.tsx | 24 ++++++++++++++++++++++-- app/src/ui/lib/releases.ts | 2 ++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/app/src/ui/about/about.tsx b/app/src/ui/about/about.tsx index f4e458ec366..c33c20b4cba 100644 --- a/app/src/ui/about/about.tsx +++ b/app/src/ui/about/about.tsx @@ -14,7 +14,7 @@ import { Disposable } from 'event-kit' import { Loading } from '../lib/loading' import { RelativeTime } from '../relative-time' import { assertNever } from '../../lib/fatal-error' -import { ReleaseNotesUri } from '../lib/releases' +import { ReleaseNotesUri, LinuxReleasesUri } from '../lib/releases' import { encodePathAsUrl } from '../../lib/path' import { isOSNoLongerSupportedByElectron } from '../../lib/get-os' @@ -100,6 +100,17 @@ export class About extends React.Component { return null } + if (__LINUX__) { + const linuxReleaseLink = ( + View Releases + ) + return ( + +

{linuxReleaseLink}

+
+ ) + } + const updateStatus = this.state.updateState.status switch (updateStatus) { @@ -185,7 +196,12 @@ export class About extends React.Component { private renderUpdateDetails() { if (__LINUX__) { - return null + return ( +

+ Please visit the GitHub Desktop for Linux release page for + Linux-specific release notes and to download the latest version. +

+ ) } if (__RELEASE_CHANNEL__ === 'development') { @@ -257,6 +273,10 @@ export class About extends React.Component { return } + if (__LINUX__) { + return + } + return (

Looking for the latest features?

diff --git a/app/src/ui/lib/releases.ts b/app/src/ui/lib/releases.ts index 958ccad3722..ba088f73374 100644 --- a/app/src/ui/lib/releases.ts +++ b/app/src/ui/lib/releases.ts @@ -2,3 +2,5 @@ export const ReleaseNotesUri = __RELEASE_CHANNEL__ === 'beta' ? 'https://desktop.github.com/release-notes/?env=beta' : 'https://desktop.github.com/release-notes/' + +export const LinuxReleasesUri = 'https://github.com/shiftkey/desktop/releases/' From 0ed88fbab85a65da11fdf695d6b8d47003d7c9db Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Thu, 22 Jul 2021 12:21:27 -0300 Subject: [PATCH 07/41] feat(tooling): detect and support running post-install script with offline yarn (#567 #587) --- script/post-install.ts | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/script/post-install.ts b/script/post-install.ts index 4d35d219a80..0665cc3bac8 100644 --- a/script/post-install.ts +++ b/script/post-install.ts @@ -13,6 +13,22 @@ const options: SpawnSyncOptions = { stdio: 'inherit', } +/** Check if the caller has set the OFFLINe environment variable */ +function isOffline() { + return process.env.OFFLINE === '1' +} + +/** Format the arguments to ensure these work offline */ +function getYarnArgs(baseArgs: Array): Array { + const args = baseArgs + + if (isOffline()) { + args.splice(1, 0, '--offline') + } + + return args +} + function findYarnVersion(callback: (path: string) => void) { glob('vendor/yarn-*.js', (error, files) => { if (error != null) { @@ -28,27 +44,27 @@ function findYarnVersion(callback: (path: string) => void) { } findYarnVersion(path => { - let result = spawnSync( - 'node', - [path, '--cwd', 'app', 'install', '--force'], - options - ) + const installArgs = getYarnArgs([path, '--cwd', 'app', 'install', '--force']) + + let result = spawnSync('node', installArgs, options) if (result.status !== 0) { process.exit(result.status || 1) } - result = spawnSync( - 'git', - ['submodule', 'update', '--recursive', '--init'], - options - ) + if (!isOffline()) { + result = spawnSync( + 'git', + ['submodule', 'update', '--recursive', '--init'], + options + ) - if (result.status !== 0) { - process.exit(result.status || 1) + if (result.status !== 0) { + process.exit(result.status || 1) + } } - result = spawnSync('node', [path, 'compile:script'], options) + result = spawnSync('node', getYarnArgs([path, 'compile:script']), options) if (result.status !== 0) { process.exit(result.status || 1) From 490e6cd9800285e7b5772d04bb406934dbb45322 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Thu, 23 Apr 2020 14:05:20 -0300 Subject: [PATCH 08/41] feat(tooling): move debian packaging out to dedicated step (#263) --- package.json | 3 + script/electron-builder-linux.yml | 17 -- script/package-debian.ts | 101 ++++++++++ script/package-electron-builder.ts | 68 +++++++ script/package.ts | 78 +++----- .../deb/postinst.sh} | 4 +- .../deb/postrm.sh} | 0 yarn.lock | 173 ++++++++++++++++-- 8 files changed, 358 insertions(+), 86 deletions(-) create mode 100644 script/package-debian.ts create mode 100644 script/package-electron-builder.ts rename script/{linux-after-install.sh => resources/deb/postinst.sh} (94%) mode change 100644 => 100755 rename script/{linux-after-remove.sh => resources/deb/postrm.sh} (100%) mode change 100644 => 100755 diff --git a/package.json b/package.json index 768283306b1..16a2bd06d94 100644 --- a/package.json +++ b/package.json @@ -164,5 +164,8 @@ "markdownlint-cli": "^0.32.2", "reserved-words": "^0.1.2", "tsconfig-paths": "^3.9.0" + }, + "optionalDependencies": { + "electron-installer-debian": "3.2.0" } } diff --git a/script/electron-builder-linux.yml b/script/electron-builder-linux.yml index 01133639a58..81d33876e81 100644 --- a/script/electron-builder-linux.yml +++ b/script/electron-builder-linux.yml @@ -11,26 +11,9 @@ linux: # see https://github.com/shiftkey/desktop/issues/72 for more details - x-scheme-handler/x-github-desktop-dev-auth target: - - deb - rpm - AppImage maintainer: 'GitHub, Inc ' -deb: - afterInstall: './script/linux-after-install.sh' - afterRemove: './script/linux-after-remove.sh' - depends: - # default Electron dependencies - - gconf2 - - gconf-service - - libnotify4 - - libappindicator1 - - libxtst6 - - libnss3 - # dugite-native dependencies - - libcurl3 | libcurl4 - # keytar dependencies - - libsecret-1-0 - - gnome-keyring rpm: depends: # dugite-native dependencies diff --git a/script/package-debian.ts b/script/package-debian.ts new file mode 100644 index 00000000000..60df69915ff --- /dev/null +++ b/script/package-debian.ts @@ -0,0 +1,101 @@ +import { promisify } from 'util' +import { join } from 'path' + +import glob = require('glob') +const globPromise = promisify(glob) + +import { rename } from 'fs-extra' + +import { getVersion } from '../app/package-info' +import { getDistPath, getDistRoot } from './dist-info' + +const distRoot = getDistRoot() + +// best guess based on documentation +type DebianOptions = { + // required + src: string + dest: string + arch: 'amd64' | 'i386' | 'arm64' + // optional + description?: string + productDescription?: string + categories?: Array + section?: string + priority?: 'required' | 'important' | 'standard' | 'optional' | 'extra' + homepage?: string + icon?: any + scripts?: { + preinst?: string + postinst?: string + prerm?: string + postrm?: string + } + mimeType?: Array + maintainer?: string + depends?: Array +} + +const options: DebianOptions = { + src: getDistPath(), + dest: distRoot, + arch: 'amd64', + description: 'Simple collaboration from your desktop', + productDescription: + 'This is the unofficial port of GitHub Desktop for Linux distributions', + section: 'GNOME;GTK;Development', + priority: 'extra', + homepage: 'https://github.com/shiftkey/desktop', + depends: [ + // Desktop-specific dependencies + 'libcurl3 | libcurl4', + 'libsecret-1-0', + 'gnome-keyring', + ], + icon: { + '256x256': 'app/static/logos/256x256.png', + '512x512': 'app/static/logos/512x512.png', + '1024x1024': 'app/static/logos/1024x1024.png', + }, + scripts: { + postinst: 'script/resources/deb/postinst.sh', + postrm: 'script/resources/deb/postrm.sh', + }, + mimeType: [ + 'x-scheme-handler/x-github-client', + 'x-scheme-handler/x-github-desktop-auth', + // workaround for handling OAuth flow until we figure out what we're doing + // with the development OAuth details + // + // see https://github.com/shiftkey/desktop/issues/72 for more details + 'x-scheme-handler/x-github-desktop-dev-auth', + ], + maintainer: 'Brendan Forster ', +} + +export async function packageDebian(): Promise { + if (process.platform === 'win32') { + return Promise.reject('Windows is not supported') + } + + const installer = require('electron-installer-debian') + + await installer(options) + const installersPath = `${distRoot}/github-desktop*.deb` + + const files = await globPromise(installersPath) + + if (files.length !== 1) { + return Promise.reject( + `Expected one file but instead found '${files.join(', ')}' - exiting...` + ) + } + + const oldPath = files[0] + + const newFileName = `GitHubDesktop-linux-${getVersion()}.deb` + const newPath = join(distRoot, newFileName) + await rename(oldPath, newPath) + + return Promise.resolve(newPath) +} diff --git a/script/package-electron-builder.ts b/script/package-electron-builder.ts new file mode 100644 index 00000000000..daba1973377 --- /dev/null +++ b/script/package-electron-builder.ts @@ -0,0 +1,68 @@ +/* eslint-disable no-sync */ + +import * as path from 'path' +import * as cp from 'child_process' +import { promisify } from 'util' + +import glob = require('glob') +const globPromise = promisify(glob) + +import { getDistPath, getDistRoot } from './dist-info' + +export async function packageElectronBuilder(): Promise> { + const distPath = getDistPath() + const distRoot = getDistRoot() + + const electronBuilder = path.resolve( + __dirname, + '..', + 'node_modules', + '.bin', + 'electron-builder' + ) + + const configPath = path.resolve(__dirname, 'electron-builder-linux.yml') + + const args = [ + 'build', + '--prepackaged', + distPath, + '--x64', + '--config', + configPath, + ] + + const { error } = cp.spawnSync(electronBuilder, args, { stdio: 'inherit' }) + + if (error != null) { + return Promise.reject(error) + } + + const appImageInstaller = `${distRoot}/GitHubDesktop-linux-*.AppImage` + + let files = await globPromise(appImageInstaller) + if (files.length !== 1) { + return Promise.reject( + `Expected one AppImage installer but instead found '${files.join( + ', ' + )}' - exiting...` + ) + } + + const appImageInstallerPath = files[0] + + const rpmInstaller = `${distRoot}/GitHubDesktop-linux-*.rpm` + + files = await globPromise(rpmInstaller) + if (files.length !== 1) { + return Promise.reject( + `Expected one RPM installer but instead found '${files.join( + ', ' + )}' - exiting...` + ) + } + + const rpmInstallerPath = files[0] + + return Promise.resolve([appImageInstallerPath, rpmInstallerPath]) +} diff --git a/script/package.ts b/script/package.ts index 79dab238781..536fced84de 100644 --- a/script/package.ts +++ b/script/package.ts @@ -1,14 +1,13 @@ /* eslint-disable no-sync */ import * as cp from 'child_process' -import { chmodSync, createReadStream } from 'fs' +import { createReadStream } from 'fs' import { writeFile } from 'fs/promises' +import { pathExists, chmod } from 'fs-extra' import * as path from 'path' import * as electronInstaller from 'electron-winstaller' import * as crypto from 'crypto' -import glob = require('glob') - import { getProductName, getCompanyName } from '../app/package-info' import { getDistPath, @@ -30,7 +29,9 @@ import { getVersion } from '../app/package-info' import { rename } from 'fs/promises' import { join } from 'path' import { assertNonNullable } from '../app/src/lib/fatal-error' -import { pathExistsSync } from 'fs-extra' + +import { packageElectronBuilder } from './package-electron-builder' +import { packageDebian } from './package-debian' const distPath = getDistPath() const productName = getProductName() @@ -186,69 +187,46 @@ function getSha256Checksum(fullPath: string): Promise { }) } -function generateChecksums() { +async function generateChecksums(files: Array) { const distRoot = getDistRoot() - const installersPath = `${distRoot}/GitHubDesktop-linux-*` - - glob(installersPath, async (error, files) => { - if (error != null) { - throw error - } - - const checksums = new Map() + const checksums = new Map() - for (const f of files) { - const checksum = await getSha256Checksum(f) - checksums.set(f, checksum) - } + for (const f of files) { + const checksum = await getSha256Checksum(f) + checksums.set(f, checksum) + } - let checksumsText = `Checksums: \n` + let checksumsText = `Checksums: \n` - for (const [fullPath, checksum] of checksums) { - const fileName = path.basename(fullPath) - checksumsText += `${checksum} - ${fileName}\n` - } + for (const [fullPath, checksum] of checksums) { + const fileName = path.basename(fullPath) + checksumsText += `${checksum} - ${fileName}\n` + } - const checksumFile = path.join(distRoot, 'checksums.txt') + const checksumFile = path.join(distRoot, 'checksums.txt') - await writeFile(checksumFile, checksumsText) - }) + await writeFile(checksumFile, checksumsText) } -function packageLinux() { +async function packageLinux() { const helperPath = path.join(getDistPath(), 'chrome-sandbox') - const exists = pathExistsSync(helperPath) + const exists = await pathExists(helperPath) if (exists) { console.log('Updating file mode for chrome-sandbox…') - chmodSync(helperPath, 0o4755) + await chmod(helperPath, 0o4755) } - const electronBuilder = path.resolve( - __dirname, - '..', - 'node_modules', - '.bin', - 'electron-builder' - ) - - const configPath = path.resolve(__dirname, 'electron-builder-linux.yml') - - const args = [ - 'build', - '--prepackaged', - distPath, - '--x64', - '--config', - configPath, - ] + const files = await packageElectronBuilder() + const debianPackage = await packageDebian() - const { error } = cp.spawnSync(electronBuilder, args, { stdio: 'inherit' }) + const installers = [...files, debianPackage] - if (error != null) { - throw error + console.log(`Installers created:`) + for (const installer of installers) { + console.log(` - ${installer}`) } - generateChecksums() + generateChecksums(installers) } diff --git a/script/linux-after-install.sh b/script/resources/deb/postinst.sh old mode 100644 new mode 100755 similarity index 94% rename from script/linux-after-install.sh rename to script/resources/deb/postinst.sh index 204b930b83d..79081967042 --- a/script/linux-after-install.sh +++ b/script/resources/deb/postinst.sh @@ -3,7 +3,7 @@ set -e PROFILE_D_FILE="/etc/profile.d/github-desktop.sh" -INSTALL_DIR="/opt/${productFilename}" +INSTALL_DIR="/usr/lib/github-desktop" CLI_DIR="$INSTALL_DIR/resources/app/static" case "$1" in @@ -30,4 +30,4 @@ case "$1" in ;; esac -exit 0 \ No newline at end of file +exit 0 diff --git a/script/linux-after-remove.sh b/script/resources/deb/postrm.sh old mode 100644 new mode 100755 similarity index 100% rename from script/linux-after-remove.sh rename to script/resources/deb/postrm.sh diff --git a/yarn.lock b/yarn.lock index 76b76199f01..51d595b9441 100644 --- a/yarn.lock +++ b/yarn.lock @@ -997,6 +997,13 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@malept/cross-spawn-promise@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.0.tgz#258fde4098f5004a56db67c35f33033af64810f6" + integrity sha512-GeIK5rfU1Yd7BZJQPTGZMMmcZy5nhRToPXZcjaDwQDRSewdhp648GT2E4dh+L7+Io7AOW6WQ+GR44QSzja4qxg== + dependencies: + cross-spawn "^7.0.1" + "@malept/cross-spawn-promise@^1.1.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz#504af200af6b98e198bce768bc1730c6936ae01d" @@ -1259,7 +1266,7 @@ dependencies: "@types/node" "*" -"@types/fs-extra@9.0.13", "@types/fs-extra@^9.0.11": +"@types/fs-extra@9.0.13", "@types/fs-extra@^9.0.1", "@types/fs-extra@^9.0.11": version "9.0.13" resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.13.tgz#7594fbae04fe7f1918ce8b3d213f74ff44ac1f45" integrity sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA== @@ -1287,6 +1294,14 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/glob@^7.1.1": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + "@types/graceful-fs@^4.1.3": version "4.1.9" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" @@ -2506,6 +2521,18 @@ asar@^2.0.1: mkdirp "^0.5.1" tmp-promise "^1.0.5" +asar@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/asar/-/asar-3.2.0.tgz#e6edb5edd6f627ebef04db62f771c61bea9c1221" + integrity sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg== + dependencies: + chromium-pickle-js "^0.2.0" + commander "^5.0.0" + glob "^7.1.6" + minimatch "^3.0.4" + optionalDependencies: + "@types/glob" "^7.1.1" + assert-plus@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" @@ -2983,6 +3010,15 @@ cli-truncate@^2.1.0: slice-ansi "^3.0.0" string-width "^4.2.0" +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + cliui@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" @@ -3252,10 +3288,10 @@ debounce@^1.2.1: resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== -debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" - integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== +debug@4, debug@^4.3.1, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" @@ -3273,6 +3309,27 @@ debug@^3.1.0, debug@^3.2.7: dependencies: ms "^2.1.1" +debug@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" + integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== + dependencies: + ms "^2.1.1" + +debug@^4.1.0, debug@^4.1.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + +debug@^4.3.2: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -3576,6 +3633,37 @@ electron-builder@^24.13.3: simple-update-notifier "2.0.0" yargs "^17.6.2" +electron-installer-common@^0.10.2: + version "0.10.3" + resolved "https://registry.yarnpkg.com/electron-installer-common/-/electron-installer-common-0.10.3.tgz#40f9db644ca60eb28673d545b67ee0113aef4444" + integrity sha512-mYbP+6i+nHMIm0WZHXgGdmmXMe+KXncl6jZYQNcCF9C1WsNA9C5SZ2VP4TLQMSIoFO+X4ugkMEA5uld1bmyEvA== + dependencies: + "@malept/cross-spawn-promise" "^1.0.0" + asar "^3.0.0" + debug "^4.1.1" + fs-extra "^9.0.0" + glob "^7.1.4" + lodash "^4.17.15" + parse-author "^2.0.0" + semver "^7.1.1" + tmp-promise "^3.0.2" + optionalDependencies: + "@types/fs-extra" "^9.0.1" + +electron-installer-debian@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/electron-installer-debian/-/electron-installer-debian-3.2.0.tgz#2a9c8220f50a57807de8f93619a0d61ec41271e0" + integrity sha512-58ZrlJ1HQY80VucsEIG9tQ//HrTlG6sfofA3nRGr6TmkX661uJyu4cMPPh6kXW+aHdq/7+q25KyQhDrXvRL7jw== + dependencies: + "@malept/cross-spawn-promise" "^1.0.0" + debug "^4.1.1" + electron-installer-common "^0.10.2" + fs-extra "^9.0.0" + get-folder-size "^2.0.1" + lodash "^4.17.4" + word-wrap "^1.2.3" + yargs "^16.0.2" + electron-packager@^17.1.1: version "17.1.1" resolved "https://registry.yarnpkg.com/electron-packager/-/electron-packager-17.1.1.tgz#f156fc63d3a66f4e902e4b42992550a172982d59" @@ -4573,24 +4661,24 @@ fs-extra@^8.1.0: universalify "^0.1.0" fs-extra@^9.0.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + version "9.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" + integrity sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ== dependencies: at-least-node "^1.0.0" graceful-fs "^4.2.0" jsonfile "^6.0.1" - universalify "^2.0.0" + universalify "^1.0.0" fs-extra@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" - integrity sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ== + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== dependencies: at-least-node "^1.0.0" graceful-fs "^4.2.0" jsonfile "^6.0.1" - universalify "^1.0.0" + universalify "^2.0.0" fs-minipass@^2.0.0: version "2.1.0" @@ -4672,6 +4760,11 @@ galactus@^0.2.1: flora-colossus "^1.0.0" fs-extra "^4.0.0" +gar@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/gar/-/gar-1.0.4.tgz#f777bc7db425c0572fdeb52676172ca1ae9888b8" + integrity sha512-w4n9cPWyP7aHxKxYHFQMegj7WIAsL/YX/C4Bs5Rr8s1H9M1rNtRWRsw+ovYMkXDQ5S4ZbYHsHAPmevPjPgw44w== + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -4682,6 +4775,14 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-folder-size@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/get-folder-size/-/get-folder-size-2.0.1.tgz#3fe0524dd3bad05257ef1311331417bcd020a497" + integrity sha512-+CEb+GDCM7tkOS2wdMKTn9vU7DgnKUTuDlehkNJKNSovdCOVxs14OfKCk4cvSaR3za4gj+OBdl9opPN9xrJ0zA== + dependencies: + gar "^1.0.4" + tiny-each-async "2.0.3" + get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" @@ -6437,11 +6538,16 @@ lodash.upperfirst@4.3.1: resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" integrity sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg== -lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21: +lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +lodash@^4.17.19: + version "4.17.19" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" + integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== + loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -7818,9 +7924,9 @@ semver-compare@^1.0.0: integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= "semver@2 || 3 || 4 || 5": - version "5.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + version "5.4.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: version "6.3.0" @@ -7832,6 +7938,11 @@ semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== +semver@^7.1.1: + version "7.1.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.1.3.tgz#e4345ce73071c53f336445cfc19efb1c311df2a6" + integrity sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA== + semver@^7.1.3, semver@^7.3.2: version "7.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.0.tgz#ed8c5dc8efb6c629c88b23d41dc9bf40c1d96cd0" @@ -8407,6 +8518,11 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= +tiny-each-async@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/tiny-each-async/-/tiny-each-async-2.0.3.tgz#8ebbbfd6d6295f1370003fbb37162afe5a0a51d1" + integrity sha1-jru/1tYpXxNwAD+7NxYq/loKUdE= + titleize@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" @@ -9062,6 +9178,11 @@ window-location-origin@^0.1.0: resolved "https://registry.yarnpkg.com/window-location-origin/-/window-location-origin-0.1.0.tgz#e0a0b3cbe8802c4966b358f859315355d3a15e04" integrity sha1-4KCzy+iALElms1j4WTFTVdOhXgQ= +word-wrap@^1.2.3: + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + worker-farm@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.5.1.tgz#8e9f4a7da4f3c595aa600903051b969390423fa1" @@ -9172,11 +9293,29 @@ yaml@^2.5.0: resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.0.tgz#c6165a721cf8000e91c36490a41d7be25176cf5d" integrity sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw== +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + yargs-parser@^21.0.1, yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== +yargs@^16.0.2: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + 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@^17.3.1, yargs@^17.6.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" From 14c1c21d7c26b3f9628a3741e8c70447f169ce01 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 17 May 2020 14:42:40 -0300 Subject: [PATCH 09/41] feat(tooling): move redhat packaging out to own step (#273 #837 #1038) * add patch-package so we can patch a node_modules package * generate patch to disable build-id contents for RPM package * move patch-package command to post-install script * regenerate patch file --- package.json | 5 +- patches/electron-installer-redhat+3.4.0.patch | 10 + script/electron-builder-linux.yml | 10 +- script/package-electron-builder.ts | 17 +- script/package-redhat.ts | 97 +++++++ script/package.ts | 22 +- script/post-install.ts | 8 + script/resources/rpm/post.sh | 12 + script/resources/rpm/preun.sh | 8 + yarn.lock | 249 +++++++++++++----- 10 files changed, 344 insertions(+), 94 deletions(-) create mode 100644 patches/electron-installer-redhat+3.4.0.patch create mode 100644 script/package-redhat.ts create mode 100755 script/resources/rpm/post.sh create mode 100755 script/resources/rpm/preun.sh diff --git a/package.json b/package.json index 16a2bd06d94..1b4818bd0b2 100644 --- a/package.json +++ b/package.json @@ -162,10 +162,13 @@ "electron-winstaller": "^5.0.0", "eslint-plugin-github": "^4.10.1", "markdownlint-cli": "^0.32.2", + "patch-package": "^8.0.0", + "postinstall-postinstall": "^2.1.0", "reserved-words": "^0.1.2", "tsconfig-paths": "^3.9.0" }, "optionalDependencies": { - "electron-installer-debian": "3.2.0" + "electron-installer-debian": "3.2.0", + "electron-installer-redhat": "3.4.0" } } diff --git a/patches/electron-installer-redhat+3.4.0.patch b/patches/electron-installer-redhat+3.4.0.patch new file mode 100644 index 00000000000..9f8d649ba51 --- /dev/null +++ b/patches/electron-installer-redhat+3.4.0.patch @@ -0,0 +1,10 @@ +diff --git a/node_modules/electron-installer-redhat/resources/spec.ejs b/node_modules/electron-installer-redhat/resources/spec.ejs +index e07a8a3..486f59e 100644 +--- a/node_modules/electron-installer-redhat/resources/spec.ejs ++++ b/node_modules/electron-installer-redhat/resources/spec.ejs +@@ -1,4 +1,5 @@ + %define _binary_payload w<%= compressionLevel %>.xzdio ++%define _build_id_links none + + %if "%{_host_cpu}" != "%{_target_cpu}" + %global __strip /bin/true diff --git a/script/electron-builder-linux.yml b/script/electron-builder-linux.yml index 81d33876e81..5f93ce91121 100644 --- a/script/electron-builder-linux.yml +++ b/script/electron-builder-linux.yml @@ -11,13 +11,5 @@ linux: # see https://github.com/shiftkey/desktop/issues/72 for more details - x-scheme-handler/x-github-desktop-dev-auth target: - - rpm - AppImage - maintainer: 'GitHub, Inc ' -rpm: - depends: - # dugite-native dependencies - - libcurl - # keytar dependencies - - libsecret - - gnome-keyring + maintainer: 'Brendan Forster' diff --git a/script/package-electron-builder.ts b/script/package-electron-builder.ts index daba1973377..7b26f48b2b5 100644 --- a/script/package-electron-builder.ts +++ b/script/package-electron-builder.ts @@ -40,7 +40,7 @@ export async function packageElectronBuilder(): Promise> { const appImageInstaller = `${distRoot}/GitHubDesktop-linux-*.AppImage` - let files = await globPromise(appImageInstaller) + const files = await globPromise(appImageInstaller) if (files.length !== 1) { return Promise.reject( `Expected one AppImage installer but instead found '${files.join( @@ -51,18 +51,5 @@ export async function packageElectronBuilder(): Promise> { const appImageInstallerPath = files[0] - const rpmInstaller = `${distRoot}/GitHubDesktop-linux-*.rpm` - - files = await globPromise(rpmInstaller) - if (files.length !== 1) { - return Promise.reject( - `Expected one RPM installer but instead found '${files.join( - ', ' - )}' - exiting...` - ) - } - - const rpmInstallerPath = files[0] - - return Promise.resolve([appImageInstallerPath, rpmInstallerPath]) + return Promise.resolve([appImageInstallerPath]) } diff --git a/script/package-redhat.ts b/script/package-redhat.ts new file mode 100644 index 00000000000..bba953b2345 --- /dev/null +++ b/script/package-redhat.ts @@ -0,0 +1,97 @@ +import { promisify } from 'util' +import { join } from 'path' + +import glob = require('glob') +const globPromise = promisify(glob) + +import { rename } from 'fs-extra' + +import { getVersion } from '../app/package-info' +import { getDistPath, getDistRoot } from './dist-info' + +const distRoot = getDistRoot() + +// best guess based on documentation +type RedhatOptions = { + // required + src: string + dest: string + arch: 'x86_64' + // optional + description?: string + productDescription?: string + categories?: Array + icon?: any + scripts?: { + pre?: string + post?: string + preun?: string + postun?: string + } + homepage?: string + mimeType?: Array + requires?: Array +} + +const options: RedhatOptions = { + src: getDistPath(), + dest: distRoot, + arch: 'x86_64', + description: 'Simple collaboration from your desktop', + productDescription: + 'This is the unofficial port of GitHub Desktop for Linux distributions', + categories: ['GNOME', 'GTK', 'Development'], + requires: [ + // dugite-native dependencies + '(libcurl or libcurl4)', + // keytar dependencies + 'libsecret', + 'gnome-keyring', + ], + icon: { + '256x256': 'app/static/logos/256x256.png', + '512x512': 'app/static/logos/512x512.png', + '1024x1024': 'app/static/logos/1024x1024.png', + }, + scripts: { + post: 'script/resources/rpm/post.sh', + preun: 'script/resources/rpm/preun.sh', + }, + homepage: 'https://github.com/shiftkey/desktop', + mimeType: [ + 'x-scheme-handler/x-github-client', + 'x-scheme-handler/x-github-desktop-auth', + // workaround for handling OAuth flow until we figure out what we're doing + // with the development OAuth details + // + // see https://github.com/shiftkey/desktop/issues/72 for more details + 'x-scheme-handler/x-github-desktop-dev-auth', + ], +} + +export async function packageRedhat(): Promise { + if (process.platform === 'win32') { + return Promise.reject('Windows is not supported') + } + + const installer = require('electron-installer-redhat') + + await installer(options) + const installersPath = `${distRoot}/github-desktop*.rpm` + + const files = await globPromise(installersPath) + + if (files.length !== 1) { + return Promise.reject( + `Expected one file but instead found '${files.join(', ')}' - exiting...` + ) + } + + const oldPath = files[0] + + const newFileName = `GitHubDesktop-linux-${getVersion()}.rpm` + const newPath = join(distRoot, newFileName) + await rename(oldPath, newPath) + + return Promise.resolve(newPath) +} diff --git a/script/package.ts b/script/package.ts index 536fced84de..b32499d40de 100644 --- a/script/package.ts +++ b/script/package.ts @@ -32,6 +32,7 @@ import { assertNonNullable } from '../app/src/lib/fatal-error' import { packageElectronBuilder } from './package-electron-builder' import { packageDebian } from './package-debian' +import { packageRedhat } from './package-redhat' const distPath = getDistPath() const productName = getProductName() @@ -217,16 +218,21 @@ async function packageLinux() { console.log('Updating file mode for chrome-sandbox…') await chmod(helperPath, 0o4755) } + try { + const files = await packageElectronBuilder() + const debianPackage = await packageDebian() + const redhatPackage = await packageRedhat() - const files = await packageElectronBuilder() - const debianPackage = await packageDebian() + const installers = [...files, debianPackage, redhatPackage] - const installers = [...files, debianPackage] + console.log(`Installers created:`) + for (const installer of installers) { + console.log(` - ${installer}`) + } - console.log(`Installers created:`) - for (const installer of installers) { - console.log(` - ${installer}`) + generateChecksums(installers) + } catch (err) { + console.error('A problem occurred with the packaging step', err) + process.exit(1) } - - generateChecksums(installers) } diff --git a/script/post-install.ts b/script/post-install.ts index 0665cc3bac8..3f79a3d1f2d 100644 --- a/script/post-install.ts +++ b/script/post-install.ts @@ -69,4 +69,12 @@ findYarnVersion(path => { if (result.status !== 0) { process.exit(result.status || 1) } + + if (process.platform === 'linux') { + result = spawnSync('node', getYarnArgs([path, 'patch-package']), options) + + if (result.status !== 0) { + process.exit(result.status || 1) + } + } }) diff --git a/script/resources/rpm/post.sh b/script/resources/rpm/post.sh new file mode 100755 index 00000000000..092c75b9d26 --- /dev/null +++ b/script/resources/rpm/post.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +INSTALL_DIR="/usr/lib/github-desktop" +CLI_DIR="$INSTALL_DIR/resources/app/static" + +# add executable permissions for CLI interface +chmod +x "$CLI_DIR"/github || : + +# create symbolic links to /usr/bin directory +ln -f -s "$CLI_DIR"/github /usr/bin || : + +exit 0 diff --git a/script/resources/rpm/preun.sh b/script/resources/rpm/preun.sh new file mode 100755 index 00000000000..fdb0a748a34 --- /dev/null +++ b/script/resources/rpm/preun.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +BASE_FILE="/usr/bin/github" + +# remove symbolic links in /usr/bin directory +test -f ${BASE_FILE} && unlink ${BASE_FILE} + +exit 0 diff --git a/yarn.lock b/yarn.lock index 51d595b9441..1a51a298d55 100644 --- a/yarn.lock +++ b/yarn.lock @@ -997,14 +997,7 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@malept/cross-spawn-promise@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.0.tgz#258fde4098f5004a56db67c35f33033af64810f6" - integrity sha512-GeIK5rfU1Yd7BZJQPTGZMMmcZy5nhRToPXZcjaDwQDRSewdhp648GT2E4dh+L7+Io7AOW6WQ+GR44QSzja4qxg== - dependencies: - cross-spawn "^7.0.1" - -"@malept/cross-spawn-promise@^1.1.0": +"@malept/cross-spawn-promise@^1.0.0", "@malept/cross-spawn-promise@^1.1.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz#504af200af6b98e198bce768bc1730c6936ae01d" integrity sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ== @@ -2094,6 +2087,11 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== +"@yarnpkg/lockfile@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + abab@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" @@ -2738,7 +2736,14 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^3.0.3, braces@~3.0.2: +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +braces@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== @@ -2884,6 +2889,17 @@ call-bind@^1.0.4: get-intrinsic "^1.2.1" set-function-length "^1.1.1" +call-bind@^1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -2980,10 +2996,10 @@ chromium-pickle-js@^0.2.0: resolved "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz#04a106672c18b085ab774d983dfa3ea138f22205" integrity sha1-BKEGZywYsIWrd02YPfo+oTjyIgU= -ci-info@^3.2.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" - integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== +ci-info@^3.2.0, ci-info@^3.7.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== cjs-module-lexer@^1.0.0: version "1.2.3" @@ -3189,7 +3205,7 @@ cross-spawn-windows-exe@^1.1.0, cross-spawn-windows-exe@^1.2.0: is-wsl "^2.2.0" which "^2.0.2" -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -3198,15 +3214,6 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -cross-spawn@^7.0.1: - version "7.0.2" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.2.tgz#d0d7dcfa74e89115c7619f4f721a94e1fdb716d6" - integrity sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - css-loader@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-7.1.2.tgz#64671541c6efe06b0e22e750503106bdd86880f8" @@ -3408,6 +3415,15 @@ define-data-property@^1.1.1: gopd "^1.0.1" has-property-descriptors "^1.0.0" +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + define-lazy-prop@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" @@ -3664,6 +3680,19 @@ electron-installer-debian@3.2.0: word-wrap "^1.2.3" yargs "^16.0.2" +electron-installer-redhat@3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/electron-installer-redhat/-/electron-installer-redhat-3.4.0.tgz#4a7f8d67b48b7d5b23bd1eb074f4b684ae43b192" + integrity sha512-gEISr3U32Sgtj+fjxUAlSDo3wyGGq6OBx7rF5UdpIgbnpUvMN4W5uYb0ThpnAZ42VEJh/3aODQXHbFS4f5J3Iw== + dependencies: + "@malept/cross-spawn-promise" "^1.0.0" + debug "^4.1.1" + electron-installer-common "^0.10.2" + fs-extra "^9.0.0" + lodash "^4.17.15" + word-wrap "^1.2.3" + yargs "^16.0.2" + electron-packager@^17.1.1: version "17.1.1" resolved "https://registry.yarnpkg.com/electron-packager/-/electron-packager-17.1.1.tgz#f156fc63d3a66f4e902e4b42992550a172982d59" @@ -3948,6 +3977,18 @@ es-abstract@^1.5.1, es-abstract@^1.7.0: is-callable "^1.1.3" is-regex "^1.0.4" +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + es-iterator-helpers@^1.0.12: version "1.0.15" resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz#bd81d275ac766431d19305923707c3efd9f1ae40" @@ -4536,7 +4577,7 @@ filenamify@^4.1.0: strip-outer "^1.0.1" trim-repeated "^1.0.0" -fill-range@^7.1.1: +fill-range@^7.0.1: version "7.1.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== @@ -4566,6 +4607,13 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" +find-yarn-workspace-root@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd" + integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ== + dependencies: + micromatch "^4.0.2" + flat-cache@^3.0.4: version "3.2.0" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" @@ -4660,17 +4708,7 @@ fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" - integrity sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^1.0.0" - -fs-extra@^9.0.1: +fs-extra@^9.0.0, fs-extra@^9.0.1: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== @@ -4802,6 +4840,17 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: has-proto "^1.0.1" has-symbols "^1.0.3" +get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + get-package-info@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/get-package-info/-/get-package-info-1.0.0.tgz#6432796563e28113cd9474dbbd00052985a4999c" @@ -5060,6 +5109,13 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.1.1" +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + has-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" @@ -5634,7 +5690,7 @@ is-weakset@^2.0.1: call-bind "^1.0.2" get-intrinsic "^1.1.1" -is-wsl@^2.2.0: +is-wsl@^2.1.1, is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== @@ -6255,12 +6311,15 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= +json-stable-stringify@^1.0.1, json-stable-stringify@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz#52d4361b47d49168bcc4e564189a42e5a7439454" + integrity sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg== dependencies: - jsonify "~0.0.0" + call-bind "^1.0.5" + isarray "^2.0.5" + jsonify "^0.0.1" + object-keys "^1.1.1" json-stringify-safe@^5.0.1: version "5.0.1" @@ -6305,10 +6364,10 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= +jsonify@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.1.tgz#2aa3111dae3d34a0f151c63f3a45d995d9420978" + integrity sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg== "jsx-ast-utils@^2.4.1 || ^3.0.0": version "3.2.1" @@ -6367,6 +6426,13 @@ klaw-sync@^3.0.0: dependencies: graceful-fs "^4.1.11" +klaw-sync@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c" + integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ== + dependencies: + graceful-fs "^4.1.11" + kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" @@ -6538,16 +6604,11 @@ lodash.upperfirst@4.3.1: resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" integrity sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg== -lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4: +lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -lodash@^4.17.19: - version "4.17.19" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" - integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== - loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -6691,6 +6752,14 @@ micromatch@^4.0.0, micromatch@^4.0.4: braces "^3.0.3" picomatch "^2.3.1" +micromatch@^4.0.2: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -7079,6 +7148,14 @@ onetime@^6.0.0: dependencies: mimic-fn "^4.0.0" +open@^7.4.2: + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + open@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" @@ -7243,6 +7320,27 @@ pascal-case@^3.1.2: no-case "^3.0.4" tslib "^2.0.3" +patch-package@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-8.0.0.tgz#d191e2f1b6e06a4624a0116bcb88edd6714ede61" + integrity sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA== + dependencies: + "@yarnpkg/lockfile" "^1.1.0" + chalk "^4.1.2" + ci-info "^3.7.0" + cross-spawn "^7.0.3" + find-yarn-workspace-root "^2.0.0" + fs-extra "^9.0.0" + json-stable-stringify "^1.0.2" + klaw-sync "^6.0.0" + minimist "^1.2.6" + open "^7.4.2" + rimraf "^2.6.3" + semver "^7.5.3" + slash "^2.0.0" + tmp "^0.0.33" + yaml "^2.2.2" + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -7398,6 +7496,11 @@ postcss@^8.4.33: picocolors "^1.0.1" source-map-js "^1.2.0" +postinstall-postinstall@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz#4f7f77441ef539d1512c40bd04c71b06a4704ca3" + integrity sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ== + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -7779,6 +7882,13 @@ ric-shim@^1.0.0: resolved "https://registry.yarnpkg.com/ric-shim/-/ric-shim-1.0.0.tgz#a20a8edfcbd05f304b58a1b52a846d53baccacf4" integrity sha1-ogqO38vQXzBLWKG1KoRtU7rMrPQ= +rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -7924,16 +8034,11 @@ semver-compare@^1.0.0: integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= "semver@2 || 3 || 4 || 5": - version "5.4.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" - integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== - -semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.3.1: +semver@^6.0.0, semver@^6.2.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== @@ -7993,6 +8098,18 @@ set-function-length@^1.1.1: gopd "^1.0.1" has-property-descriptors "^1.0.0" +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + set-function-name@^2.0.0, set-function-name@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" @@ -8066,6 +8183,11 @@ slash@^1.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -8543,7 +8665,7 @@ tmp-promise@^3.0.2: dependencies: tmp "^0.2.0" -tmp@0.0.33: +tmp@0.0.33, tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== @@ -9288,6 +9410,11 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml@^2.2.2: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.4.1.tgz#2e57e0b5e995292c25c75d2658f0664765210eed" + integrity sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg== + yaml@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.0.tgz#c6165a721cf8000e91c36490a41d7be25176cf5d" From 27abc0c549015ce88547745c54a120b21dc4819d Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Wed, 24 Jun 2020 13:51:38 -0300 Subject: [PATCH 10/41] feat(tooling): run codeql on linux branch (#302) --- .github/workflows/codeql.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 6b78b39f3f4..7305888af47 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -2,7 +2,7 @@ name: 'Code scanning - action' on: push: - branches: ['development'] + branches: ['development', 'linux'] pull_request: branches: ['development'] schedule: From deed4443edaeb4fe47bca355ba8318d51ee58327 Mon Sep 17 00:00:00 2001 From: Dan McCarthy Date: Tue, 4 Aug 2020 07:00:32 -0500 Subject: [PATCH 11/41] fix: allow tilde character when specifying a local repository (#317) There already exists a function that will convert a tilde path to an absolute path. It was originally used for this purpose, but the functionality was removed during a commit that changed which function was used to validate git repositories. This reinstates that functionality and allows us to type a ~/ tilde path to get our home directories when typing in a path. --- .../add-repository/add-existing-repository.tsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/app/src/ui/add-repository/add-existing-repository.tsx b/app/src/ui/add-repository/add-existing-repository.tsx index 6eeed3ee481..6bfdb9887ce 100644 --- a/app/src/ui/add-repository/add-existing-repository.tsx +++ b/app/src/ui/add-repository/add-existing-repository.tsx @@ -253,9 +253,21 @@ export class AddExistingRepository extends React.Component< } private onPathChanged = async (path: string) => { - if (this.state.path !== path) { - this.updatePath(path) - } + const type = await getRepositoryType(this.resolvedPath(path)) + + const isRepository = type.kind !== 'missing' && type.kind !== 'unsafe' + const isRepositoryUnsafe = type.kind === 'unsafe' + const isRepositoryBare = type.kind === 'bare' + const showNonGitRepositoryWarning = !isRepository || isRepositoryBare + const repositoryUnsafePath = type.kind === 'unsafe' ? type.path : undefined + + this.setState({ + path, + isRepositoryUnsafe, + isRepositoryBare, + showNonGitRepositoryWarning, + repositoryUnsafePath, + }) } private showFilePicker = async () => { From 725e65a5be9a501b98abef94229e444073b6bbb0 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Mon, 15 Feb 2021 15:11:16 -0400 Subject: [PATCH 12/41] feat(tooling): enable dependabot monitoring for specific dependencies in project (#440 #1036) --- .github/dependabot.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e22a9bd70ab..6437a93715c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,5 +4,16 @@ updates: directory: / schedule: interval: weekly - # Disable version updates and keep only security updates - open-pull-requests-limit: 0 + - package-ecosystem: 'npm' + directory: '/' + open-pull-requests-limit: 5 + schedule: + interval: 'weekly' + allow: + - dependency-name: 'electron-builder' + - dependency-name: 'electron-packager' + - dependency-name: 'electron-installer-*' + - dependency-name: 'xvfb-maybe' + - dependency-name: 'yaml' + - dependency-name: 'patch-package' + - dependency-name: 'postinstall-postinstall' From f74008c6a63469b614c578c2fc35170bb1f33efb Mon Sep 17 00:00:00 2001 From: Kevin Evans Date: Sun, 27 Dec 2020 07:23:30 -0800 Subject: [PATCH 13/41] fix: add smaller icons and align with new theme (#395 #530 #561) * drop old icon used in app window * regenerate smaller icons from new 256px source --- app/src/main-process/app-window.ts | 4 ++-- app/static/linux/icon-logo.png | Bin 118370 -> 0 bytes app/static/logos/128x128.png | Bin 0 -> 12473 bytes app/static/logos/32x32.png | Bin 0 -> 1851 bytes app/static/logos/64x64.png | Bin 0 -> 4779 bytes script/package-debian.ts | 3 +++ script/package-redhat.ts | 3 +++ 7 files changed, 8 insertions(+), 2 deletions(-) delete mode 100644 app/static/linux/icon-logo.png create mode 100644 app/static/logos/128x128.png create mode 100644 app/static/logos/32x32.png create mode 100644 app/static/logos/64x64.png diff --git a/app/src/main-process/app-window.ts b/app/src/main-process/app-window.ts index fd9992b9656..fc682434125 100644 --- a/app/src/main-process/app-window.ts +++ b/app/src/main-process/app-window.ts @@ -8,6 +8,7 @@ import { } from 'electron' import { shell } from '../lib/app-shell' import { Emitter, Disposable } from 'event-kit' +import { join } from 'path' import { encodePathAsUrl } from '../lib/path' import { getWindowState, @@ -18,7 +19,6 @@ import { URLActionType } from '../lib/parse-app-url' import { ILaunchStats } from '../lib/stats' import { menuFromElectronMenu } from '../models/app-menu' import { now } from './now' -import * as path from 'path' import windowStateKeeper from 'electron-window-state' import * as ipcMain from './ipc-main' import * as ipcWebContents from './ipc-webcontents' @@ -77,7 +77,7 @@ export class AppWindow { } else if (__WIN32__) { windowOptions.frame = false } else if (__LINUX__) { - windowOptions.icon = path.join(__dirname, 'static', 'icon-logo.png') + windowOptions.icon = join(__dirname, 'static', 'logos', '512x512.png') // relax restriction here for users trying to run app at a small // resolution and any other side-effects of dropping this restriction are diff --git a/app/static/linux/icon-logo.png b/app/static/linux/icon-logo.png deleted file mode 100644 index 7e598fe01189e9dc3d1c34bee0d850c54eb71c1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 118370 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

dd`1+QBLhMR9?LkaCHw)NK&N^%gW$tI% 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 literal 0 HcmV?d00001 diff --git a/app/static/logos/32x32.png b/app/static/logos/32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..f1b5f9719eaf7f103ca6ebab3ca22fe6426e05fb GIT binary patch literal 1851 zcmV-B2gLY^P)ew@}nX$pe1`YSk!JTT-Oyb`afT4riU%SD_cLA>DZyFbbS4DZ$3Fb)#TheH#c0^ zTf7~tyWd&{L*v@n%*{N6vchL#;M(b7ZhSC?!m5l)goz<l{gG>Q7T)h2dU-OZ8^6m^FY!4P&WhRzq-Si5y4ZYlvP%!Wv~phP_!M+2pBQwi2?T}kKm zHnbSZYl;wfy8Yn6gH$-s-QA5})RrM^8binP&8*tk2@3MJ3*<%$czK_o7~mHJ0x#@- zF(4>vya}J&$RzpUNl>tAV<#P3o6(qZ^L?$hZQE8!!oI#fo|-3!3iDsHG)C9v43?wt zJaC9vPdW%-0>jNC6V&7z$i8xh1O8EL z%fV4G0JH=I#-}LDgk36cJStOlQM6D7VCE{54yKzMwCNPK*u%NYLE{O#;g^LCwhU3SN zS8~9%?T~mF=65$@$3v6WhN~B^bLH?*8Am}dP$sL1TqxOZoE)Y9^FeeFTAaAeBi(5< z2F-MFv+jzO3MYuBVSX(rFk;ZY=48)V;&u`(GNqe{;ik;=k}YPtoH%%fz}J{43yt&Z z(4sL2t*xz<5DX3uV&({7NL0m$;U0 zXlZFFL*OP8p#u`_3QI+)e$W;|gCYt%O`Phvz`&=&+&D3Ofsx9il{O3}DgwRzDX%>nD~-@XWK{V#mwx zaOB-ydJlif`+q-%z!YM_z@=+prHrbjHU_^CaN+b7df&PNSYd!l)RHAj$`072K{lIZ zW%JWN6GM{#w&if@*cldNnt6CZGpV%8`){1)v-iHhAGJYSNLhrTu_MKTN9SSL3Nb?9 zX$H?-~6d-%~yPm_6~gU7$q z2}U@)?-V_+p94|lLyHr4Fj@$ThQJHxKYNuOzuk|MpM^v(4>c;dw0rmNnYUq4CiWVM z#6&_Uobg%w;l+Ktw>!)5)lnw%MS>s*(;v;#Q7*i^&+ymhUojF^@MILNwK092ag} z$YTf9*jB8}k5Vg|$&*(n&Ti_zeR||eKTKTLt$wm~`%e;9^+roMtx=s9rX4S*-KQT8 z!m$zrBf)@Y@^2p+diBqDMsxWG`Z6kAO-)Vq*w|RY^E|sW*O+i0JC0K>Sku6oVz+HO pNT<`@p+krC!i5XJ`VO7(`Y+_dE3(9qAuRv^002ovPDHLkV1kf7c?tjk literal 0 HcmV?d00001 diff --git a/app/static/logos/64x64.png b/app/static/logos/64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..77fe2a72c18be8ac2d1de0140ae665f1e82346dc GIT binary patch literal 4779 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 FV1jxK_(=c& literal 0 HcmV?d00001 diff --git a/script/package-debian.ts b/script/package-debian.ts index 60df69915ff..35402cafaf2 100644 --- a/script/package-debian.ts +++ b/script/package-debian.ts @@ -53,6 +53,9 @@ const options: DebianOptions = { 'gnome-keyring', ], icon: { + '32x32': 'app/static/logos/32x32.png', + '64x64': 'app/static/logos/64x64.png', + '128x128': 'app/static/logos/128x128.png', '256x256': 'app/static/logos/256x256.png', '512x512': 'app/static/logos/512x512.png', '1024x1024': 'app/static/logos/1024x1024.png', diff --git a/script/package-redhat.ts b/script/package-redhat.ts index bba953b2345..3b5a55b8a25 100644 --- a/script/package-redhat.ts +++ b/script/package-redhat.ts @@ -49,6 +49,9 @@ const options: RedhatOptions = { 'gnome-keyring', ], icon: { + '32x32': 'app/static/logos/32x32.png', + '64x64': 'app/static/logos/64x64.png', + '128x128': 'app/static/logos/128x128.png', '256x256': 'app/static/logos/256x256.png', '512x512': 'app/static/logos/512x512.png', '1024x1024': 'app/static/logos/1024x1024.png', From 7552cc52090572f770699fc645ef89f495f00812 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 3 Oct 2021 18:49:32 -0300 Subject: [PATCH 14/41] fix: move icons to correct location, update usages in tooling (#606) --- app/static/{ => linux}/logos/1024x1024.png | Bin app/static/{ => linux}/logos/128x128.png | Bin app/static/{ => linux}/logos/256x256.png | Bin app/static/{ => linux}/logos/32x32.png | Bin app/static/{ => linux}/logos/512x512.png | Bin app/static/{ => linux}/logos/64x64.png | Bin script/build.ts | 9 ++++++++- script/electron-builder-linux.yml | 2 +- script/package-debian.ts | 12 ++++++------ script/package-redhat.ts | 12 ++++++------ 10 files changed, 21 insertions(+), 14 deletions(-) rename app/static/{ => linux}/logos/1024x1024.png (100%) rename app/static/{ => linux}/logos/128x128.png (100%) rename app/static/{ => linux}/logos/256x256.png (100%) rename app/static/{ => linux}/logos/32x32.png (100%) rename app/static/{ => linux}/logos/512x512.png (100%) rename app/static/{ => linux}/logos/64x64.png (100%) diff --git a/app/static/logos/1024x1024.png b/app/static/linux/logos/1024x1024.png similarity index 100% rename from app/static/logos/1024x1024.png rename to app/static/linux/logos/1024x1024.png diff --git a/app/static/logos/128x128.png b/app/static/linux/logos/128x128.png similarity index 100% rename from app/static/logos/128x128.png rename to app/static/linux/logos/128x128.png diff --git a/app/static/logos/256x256.png b/app/static/linux/logos/256x256.png similarity index 100% rename from app/static/logos/256x256.png rename to app/static/linux/logos/256x256.png diff --git a/app/static/logos/32x32.png b/app/static/linux/logos/32x32.png similarity index 100% rename from app/static/logos/32x32.png rename to app/static/linux/logos/32x32.png diff --git a/app/static/logos/512x512.png b/app/static/linux/logos/512x512.png similarity index 100% rename from app/static/logos/512x512.png rename to app/static/linux/logos/512x512.png diff --git a/app/static/logos/64x64.png b/app/static/linux/logos/64x64.png similarity index 100% rename from app/static/logos/64x64.png rename to app/static/linux/logos/64x64.png diff --git a/script/build.ts b/script/build.ts index 07a769c63ad..d09df96e7ac 100755 --- a/script/build.ts +++ b/script/build.ts @@ -160,13 +160,20 @@ function packageApp() { ) } + // this setting only works for macOS and Windows, so let's clear it now to ensure + // the app is working as expected + const icon = + process.platform === 'linux' + ? undefined + : path.join(projectRoot, 'app', 'static', 'logos', getIconFileName()) + return packager({ name: getExecutableName(), platform: toPackagePlatform(process.platform), arch: toPackageArch(process.env.TARGET_ARCH), asar: false, // TODO: Probably wanna enable this down the road. out: getDistRoot(), - icon: path.join(projectRoot, 'app', 'static', 'logos', getIconFileName()), + icon, dir: outRoot, overwrite: true, tmpdir: false, diff --git a/script/electron-builder-linux.yml b/script/electron-builder-linux.yml index 5f93ce91121..f73156cbadb 100644 --- a/script/electron-builder-linux.yml +++ b/script/electron-builder-linux.yml @@ -2,7 +2,7 @@ artifactName: 'GitHubDesktop-${os}-${version}.${ext}' linux: category: 'GNOME;GTK;Development' packageCategory: 'GNOME;GTK;Development' - icon: 'app/static/logos' + icon: 'app/static/linux/logos' mimeTypes: - x-scheme-handler/x-github-client - x-scheme-handler/x-github-desktop-auth diff --git a/script/package-debian.ts b/script/package-debian.ts index 35402cafaf2..15314d519dd 100644 --- a/script/package-debian.ts +++ b/script/package-debian.ts @@ -53,12 +53,12 @@ const options: DebianOptions = { 'gnome-keyring', ], icon: { - '32x32': 'app/static/logos/32x32.png', - '64x64': 'app/static/logos/64x64.png', - '128x128': 'app/static/logos/128x128.png', - '256x256': 'app/static/logos/256x256.png', - '512x512': 'app/static/logos/512x512.png', - '1024x1024': 'app/static/logos/1024x1024.png', + '32x32': 'app/static/linux/logos/32x32.png', + '64x64': 'app/static/linux/logos/64x64.png', + '128x128': 'app/static/linux/logos/128x128.png', + '256x256': 'app/static/linux/logos/256x256.png', + '512x512': 'app/static/linux/logos/512x512.png', + '1024x1024': 'app/static/linux/logos/1024x1024.png', }, scripts: { postinst: 'script/resources/deb/postinst.sh', diff --git a/script/package-redhat.ts b/script/package-redhat.ts index 3b5a55b8a25..66ef2f39f37 100644 --- a/script/package-redhat.ts +++ b/script/package-redhat.ts @@ -49,12 +49,12 @@ const options: RedhatOptions = { 'gnome-keyring', ], icon: { - '32x32': 'app/static/logos/32x32.png', - '64x64': 'app/static/logos/64x64.png', - '128x128': 'app/static/logos/128x128.png', - '256x256': 'app/static/logos/256x256.png', - '512x512': 'app/static/logos/512x512.png', - '1024x1024': 'app/static/logos/1024x1024.png', + '32x32': 'app/static/linux/logos/32x32.png', + '64x64': 'app/static/linux/logos/64x64.png', + '128x128': 'app/static/linux/logos/128x128.png', + '256x256': 'app/static/linux/logos/256x256.png', + '512x512': 'app/static/linux/logos/512x512.png', + '1024x1024': 'app/static/linux/logos/1024x1024.png', }, scripts: { post: 'script/resources/rpm/post.sh', From 3cd62b4c1cf084c3063f11a73f47d7f07679f734 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Wed, 14 Jul 2021 11:53:03 -0300 Subject: [PATCH 15/41] feat(tooling): flatpak - introduce abstractions to make Flatpak integration easier (#555 #558) Co-Authored-By: nullrequest <30698906+advaithm@users.noreply.github.com> --- app/src/lib/editors/launch.ts | 4 +- app/src/lib/editors/linux.ts | 3 +- app/src/lib/helpers/linux.ts | 98 +++++++++++++++++++++++++++++ app/src/lib/shells/linux.ts | 4 +- app/src/lib/shells/shared.ts | 2 +- app/test/unit/helpers/linux-test.ts | 47 ++++++++++++++ 6 files changed, 153 insertions(+), 5 deletions(-) create mode 100644 app/src/lib/helpers/linux.ts create mode 100644 app/test/unit/helpers/linux-test.ts diff --git a/app/src/lib/editors/launch.ts b/app/src/lib/editors/launch.ts index ed00ff396ff..8e83b9f8c3d 100644 --- a/app/src/lib/editors/launch.ts +++ b/app/src/lib/editors/launch.ts @@ -1,5 +1,5 @@ import { spawn, SpawnOptions } from 'child_process' -import { pathExists } from '../../ui/lib/path-exists' +import { pathExists, spawnEditor } from '../helpers/linux' import { ExternalEditorError, FoundEditor } from './shared' import { expandTargetPathArgument, @@ -42,6 +42,8 @@ export async function launchExternalEditor( // In macOS we can use `open`, which will open the right executable file // for us, we only need the path to the editor .app folder. spawn('open', ['-a', editorPath, fullPath], opts) + } else if (__LINUX__) { + spawnEditor(editorPath, fullPath, opts) } else { spawn(editorPath, [fullPath], opts) } diff --git a/app/src/lib/editors/linux.ts b/app/src/lib/editors/linux.ts index 5d9c527622d..83e41dc3b8f 100644 --- a/app/src/lib/editors/linux.ts +++ b/app/src/lib/editors/linux.ts @@ -1,4 +1,5 @@ -import { pathExists } from '../../ui/lib/path-exists' +import { pathExists } from '../helpers/linux' + import { IFoundEditor } from './found-editor' /** Represents an external editor on Linux */ diff --git a/app/src/lib/helpers/linux.ts b/app/src/lib/helpers/linux.ts new file mode 100644 index 00000000000..aac3701dd95 --- /dev/null +++ b/app/src/lib/helpers/linux.ts @@ -0,0 +1,98 @@ +import { join } from 'path' +import { pathExists as pathExistsInternal } from 'fs-extra' +import { + ChildProcess, + spawn as nodeSpawn, + SpawnOptionsWithoutStdio, + SpawnOptions, +} from 'child_process' + +export function isFlatpakBuild() { + return __LINUX__ && process.env.FLATPAK_HOST === '1' +} + +/** + * Convert an executable path to be relative to the flatpak host + * + * @param path a path to an executable relative to the root of the filesystem + */ +export function convertToFlatpakPath(path: string) { + if (!__LINUX__) { + return path + } + + if (path.startsWith('/opt/')) { + return path + } + + return join('/var/run/host', path) +} + +export function formatWorkingDirectoryForFlatpak(path: string): string { + return path.replace(/(\s)/, ' ') +} + +/** + * Checks the file path on disk exists before attempting to launch a specific shell + * + * @param path + * + * @returns `true` if the path can be resolved, or `false` otherwise + */ +export async function pathExists(path: string): Promise { + if (isFlatpakBuild()) { + path = convertToFlatpakPath(path) + } + + try { + return await pathExistsInternal(path) + } catch { + return false + } +} + +/** + * Spawn a particular shell in a way that works for Flatpak-based usage + * + * @param path path to shell, relative to the root of the filesystem + * @param args arguments to provide to the shell + * @param options additional options to provide to spawn function + * + * @returns a child process to observe and monitor + */ +export function spawn( + path: string, + args: ReadonlyArray, + options?: SpawnOptionsWithoutStdio +): ChildProcess { + if (isFlatpakBuild()) { + return nodeSpawn('flatpak-spawn', ['--host', path, ...args], options) + } + + return nodeSpawn(path, args, options) +} + +/** + * Spawn a given editor in a way that works for Flatpak-based usage + * + * @param path path to editor, relative to the root of the filesystem + * @param workingDirectory working directory to open initially in editor + * @param options additional options to provide to spawn function + */ +export function spawnEditor( + path: string, + workingDirectory: string, + options: SpawnOptions +): ChildProcess { + if (isFlatpakBuild()) { + const EscapedworkingDirectory = + formatWorkingDirectoryForFlatpak(workingDirectory) + return nodeSpawn( + 'flatpak-spawn', + ['--host', path, EscapedworkingDirectory], + options + ) + } else { + return nodeSpawn(path, [workingDirectory], options) + } +} diff --git a/app/src/lib/shells/linux.ts b/app/src/lib/shells/linux.ts index afb8087cc31..5800dd1f2f5 100644 --- a/app/src/lib/shells/linux.ts +++ b/app/src/lib/shells/linux.ts @@ -1,7 +1,6 @@ -import { spawn, ChildProcess } from 'child_process' +import { ChildProcess } from 'child_process' import { assertNever } from '../fatal-error' import { parseEnumValue } from '../enum' -import { pathExists } from '../../ui/lib/path-exists' import { FoundShell } from './shared' import { expandTargetPathArgument, @@ -9,6 +8,7 @@ import { parseCustomIntegrationArguments, spawnCustomIntegration, } from '../custom-integration' +import { pathExists, spawn } from '../helpers/linux' export enum Shell { Gnome = 'GNOME Terminal', diff --git a/app/src/lib/shells/shared.ts b/app/src/lib/shells/shared.ts index 25e52bfd3ea..211a8265793 100644 --- a/app/src/lib/shells/shared.ts +++ b/app/src/lib/shells/shared.ts @@ -3,8 +3,8 @@ import { ChildProcess } from 'child_process' import * as Darwin from './darwin' import * as Win32 from './win32' import * as Linux from './linux' +import { pathExists } from '../helpers/linux' import { ShellError } from './error' -import { pathExists } from '../../ui/lib/path-exists' import { ICustomIntegration } from '../custom-integration' export type Shell = Darwin.Shell | Win32.Shell | Linux.Shell diff --git a/app/test/unit/helpers/linux-test.ts b/app/test/unit/helpers/linux-test.ts new file mode 100644 index 00000000000..52873f4e9d0 --- /dev/null +++ b/app/test/unit/helpers/linux-test.ts @@ -0,0 +1,47 @@ +import { + convertToFlatpakPath, + formatWorkingDirectoryForFlatpak, +} from '../../../src/lib/helpers/linux' + +describe('convertToFlatpakPath()', () => { + if (__LINUX__) { + it('converts /usr paths', () => { + const path = '/usr/bin/subl' + const expectedPath = '/var/run/host/usr/bin/subl' + expect(convertToFlatpakPath(path)).toEqual(expectedPath) + }) + + it('preserves /opt paths', () => { + const path = '/opt/slickedit-pro2018/bin/vs' + expect(convertToFlatpakPath(path)).toEqual(path) + }) + } + + if (__WIN32__) { + it('returns same path', () => { + const path = 'C:\\Windows\\System32\\Notepad.exe' + expect(convertToFlatpakPath(path)).toEqual(path) + }) + } + + if (__DARWIN__) { + it('returns same path', () => { + const path = '/usr/local/bin/code' + expect(convertToFlatpakPath(path)).toEqual(path) + }) + } +}) + +describe('formatWorkingDirectoryForFlatpak()', () => { + if (__LINUX__) { + it('escapes string', () => { + const path = '/home/test/path with space' + const expectedPath = '/home/test/path with space' + expect(formatWorkingDirectoryForFlatpak(path)).toEqual(expectedPath) + }) + it('returns same path', () => { + const path = '/home/test/path_wthout_spaces' + expect(formatWorkingDirectoryForFlatpak(path)).toEqual(path) + }) + } +}) From ba7107e377bcedf3143bb1ee02be3c7151d2ca86 Mon Sep 17 00:00:00 2001 From: Luna <30698906+Lunarequest@users.noreply.github.com> Date: Thu, 30 Sep 2021 21:27:13 +0530 Subject: [PATCH 16/41] feat(tooling): flatpak - locate and launch flatpaked code editors (#602) --- app/src/lib/helpers/linux.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/src/lib/helpers/linux.ts b/app/src/lib/helpers/linux.ts index aac3701dd95..2355ddf82da 100644 --- a/app/src/lib/helpers/linux.ts +++ b/app/src/lib/helpers/linux.ts @@ -21,7 +21,7 @@ export function convertToFlatpakPath(path: string) { return path } - if (path.startsWith('/opt/')) { + if (path.startsWith('/opt/') || path.startsWith('/var/lib/flatpak')) { return path } @@ -32,6 +32,12 @@ export function formatWorkingDirectoryForFlatpak(path: string): string { return path.replace(/(\s)/, ' ') } +export function formatPathForFlatpak(path: string): string { + if (path.startsWith('/var/lib/flatpak/app')) { + return path.replace('/var/lib/flatpak/app/', '') + } + return path +} /** * Checks the file path on disk exists before attempting to launch a specific shell * @@ -85,11 +91,12 @@ export function spawnEditor( options: SpawnOptions ): ChildProcess { if (isFlatpakBuild()) { + const actualPath = formatPathForFlatpak(path) const EscapedworkingDirectory = formatWorkingDirectoryForFlatpak(workingDirectory) return nodeSpawn( 'flatpak-spawn', - ['--host', path, EscapedworkingDirectory], + ['--host', actualPath, EscapedworkingDirectory], options ) } else { From 9c28d41ee458aebe9fce8ee4938c895acd93ad82 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 3 Apr 2022 13:52:37 -0300 Subject: [PATCH 17/41] fix: Add additional validation to find the app-specific argument we require (#687 #689) --- app/src/main-process/main.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/src/main-process/main.ts b/app/src/main-process/main.ts index 070663f9961..6ee34e18592 100644 --- a/app/src/main-process/main.ts +++ b/app/src/main-process/main.ts @@ -273,6 +273,16 @@ function handlePossibleProtocolLauncherArgs(args: ReadonlyArray) { } else { log.error(`Malformed launch arguments received: ${args}`) } + } else if (__LINUX__) { + // we expect this call to have several parameters before the URL we want, + // so we should filter out the program name as well as any parameters that + // look like arguments to Electron + const argsWithoutParameters = args.filter( + a => !a.endsWith('github-desktop') && !a.startsWith('--') + ) + if (argsWithoutParameters.length > 0) { + handleAppURL(argsWithoutParameters[0]) + } } else if (args.length > 1) { handleAppURL(args[1]) } From 0d9f1f5da280222658db8d968fe6afbae6395d06 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Fri, 15 Apr 2022 13:22:29 -0300 Subject: [PATCH 18/41] fix(tooling): move electron-winstaller to optional dependency to not block arm32 usage --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1b4818bd0b2..d517077e133 100644 --- a/package.json +++ b/package.json @@ -159,7 +159,6 @@ "electron": "32.1.2", "electron-builder": "^24.13.3", "electron-packager": "^17.1.1", - "electron-winstaller": "^5.0.0", "eslint-plugin-github": "^4.10.1", "markdownlint-cli": "^0.32.2", "patch-package": "^8.0.0", @@ -169,6 +168,7 @@ }, "optionalDependencies": { "electron-installer-debian": "3.2.0", - "electron-installer-redhat": "3.4.0" + "electron-installer-redhat": "3.4.0", + "electron-winstaller": "^5.0.0" } } From 653555e887bff71874130ad3a6027eb2bfcdc3c3 Mon Sep 17 00:00:00 2001 From: theofficialgman <28281419+theofficialgman@users.noreply.github.com> Date: Sat, 7 May 2022 14:04:01 -0400 Subject: [PATCH 19/41] feat(tooling) add armv7l support to scripts (#712) Co-authored-by: Brendan Forster --- script/build.ts | 6 +++++- script/dist-info.ts | 8 ++++++-- script/package-debian.ts | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/script/build.ts b/script/build.ts index d09df96e7ac..cf18eb15be6 100755 --- a/script/build.ts +++ b/script/build.ts @@ -136,7 +136,11 @@ function packageApp() { targetArch = os.arch() } - if (targetArch === 'arm64' || targetArch === 'x64') { + if ( + targetArch === 'arm64' || + targetArch === 'x64' || + targetArch === 'armv7l' + ) { return targetArch } diff --git a/script/dist-info.ts b/script/dist-info.ts index 88a0bcbd4b4..420444f7448 100644 --- a/script/dist-info.ts +++ b/script/dist-info.ts @@ -112,11 +112,12 @@ export const isPublishable = () => export const getChannel = () => process.env.RELEASE_CHANNEL ?? process.env.NODE_ENV ?? 'development' -export function getDistArchitecture(): 'arm64' | 'x64' { +export function getDistArchitecture(): 'arm64' | 'x64' | 'armv7l' { // If a specific npm_config_arch is set, we use that one instead of the OS arch (to support cross compilation) if ( process.env.npm_config_arch === 'arm64' || - process.env.npm_config_arch === 'x64' + process.env.npm_config_arch === 'x64' || + process.env.npm_config_arch === 'armv7l' ) { return process.env.npm_config_arch } @@ -124,6 +125,9 @@ export function getDistArchitecture(): 'arm64' | 'x64' { if (process.arch === 'arm64') { return 'arm64' } + if (process.arch === 'arm') { + return 'armv7l' + } // TODO: Check if it's x64 running on an arm64 Windows with IsWow64Process2 // More info: https://www.rudyhuyn.com/blog/2017/12/13/how-to-detect-that-your-x86-application-runs-on-windows-on-arm/ diff --git a/script/package-debian.ts b/script/package-debian.ts index 15314d519dd..fc6ae2cf57c 100644 --- a/script/package-debian.ts +++ b/script/package-debian.ts @@ -16,7 +16,7 @@ type DebianOptions = { // required src: string dest: string - arch: 'amd64' | 'i386' | 'arm64' + arch: 'amd64' | 'i386' | 'arm64' | 'armhf' // optional description?: string productDescription?: string From cd6580489f643d5085fa184f636f6507375f1c08 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 11 Aug 2024 21:29:45 -0300 Subject: [PATCH 20/41] fix: update electron-builder config to support different architectures (#774) --- script/package-electron-builder.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/script/package-electron-builder.ts b/script/package-electron-builder.ts index 7b26f48b2b5..6292c28b9f4 100644 --- a/script/package-electron-builder.ts +++ b/script/package-electron-builder.ts @@ -9,6 +9,17 @@ const globPromise = promisify(glob) import { getDistPath, getDistRoot } from './dist-info' +function getArchitecture() { + switch (process.arch) { + case 'arm64': + return '--arm64' + case 'arm': + return '--armv7l' + default: + return '--x64' + } +} + export async function packageElectronBuilder(): Promise> { const distPath = getDistPath() const distRoot = getDistRoot() @@ -27,7 +38,7 @@ export async function packageElectronBuilder(): Promise> { 'build', '--prepackaged', distPath, - '--x64', + getArchitecture(), '--config', configPath, ] From 23c6fee0feeddd6434fd86ac38dd3896ab0baf5b Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 11 Aug 2024 21:29:58 -0300 Subject: [PATCH 21/41] fix: update debian config to support different architectures (#774) --- script/package-debian.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/script/package-debian.ts b/script/package-debian.ts index fc6ae2cf57c..9a918473070 100644 --- a/script/package-debian.ts +++ b/script/package-debian.ts @@ -9,6 +9,17 @@ import { rename } from 'fs-extra' import { getVersion } from '../app/package-info' import { getDistPath, getDistRoot } from './dist-info' +function getArchitecture() { + switch (process.arch) { + case 'arm64': + return 'arm64' + case 'arm': + return 'armhf' + default: + return 'amd64' + } +} + const distRoot = getDistRoot() // best guess based on documentation @@ -39,7 +50,7 @@ type DebianOptions = { const options: DebianOptions = { src: getDistPath(), dest: distRoot, - arch: 'amd64', + arch: getArchitecture(), description: 'Simple collaboration from your desktop', productDescription: 'This is the unofficial port of GitHub Desktop for Linux distributions', From f68405cb7c1b6c2b5dc89dc4f219c89fe53657d9 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 11 Aug 2024 21:30:16 -0300 Subject: [PATCH 22/41] fix: update redhat config to support different architectures (#774) --- script/package-redhat.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/script/package-redhat.ts b/script/package-redhat.ts index 66ef2f39f37..37bd3819293 100644 --- a/script/package-redhat.ts +++ b/script/package-redhat.ts @@ -9,6 +9,17 @@ import { rename } from 'fs-extra' import { getVersion } from '../app/package-info' import { getDistPath, getDistRoot } from './dist-info' +function getArchitecture() { + switch (process.arch) { + case 'arm64': + return 'aarch64' + case 'arm': + return 'armv7l' + default: + return 'x86_64' + } +} + const distRoot = getDistRoot() // best guess based on documentation @@ -16,7 +27,7 @@ type RedhatOptions = { // required src: string dest: string - arch: 'x86_64' + arch: string // optional description?: string productDescription?: string @@ -36,7 +47,7 @@ type RedhatOptions = { const options: RedhatOptions = { src: getDistPath(), dest: distRoot, - arch: 'x86_64', + arch: getArchitecture(), description: 'Simple collaboration from your desktop', productDescription: 'This is the unofficial port of GitHub Desktop for Linux distributions', From e72301b8ac9a97535c512896a54ef792f1a7ead4 Mon Sep 17 00:00:00 2001 From: Sarim Khan Date: Fri, 17 Feb 2023 19:43:51 +0600 Subject: [PATCH 23/41] fix: args processing on first launch on linux (#793) --- app/src/main-process/main.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main-process/main.ts b/app/src/main-process/main.ts index 6ee34e18592..4897a2e4484 100644 --- a/app/src/main-process/main.ts +++ b/app/src/main-process/main.ts @@ -155,6 +155,10 @@ if (__WIN32__ && process.argv.length > 1) { } } +if (__LINUX__ && process.argv.length > 1) { + handlePossibleProtocolLauncherArgs(process.argv) +} + initializeDesktopNotifications() function handleAppURL(url: string) { From ebf8bcf3702ab71c43c147bff9f2377f506d4bc0 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Thu, 17 Dec 2020 15:03:36 -0400 Subject: [PATCH 24/41] feat(tooling): update upstream CI settings to work with fork (#393 #495 #551 #863) --- .github/workflows/ci.yml | 100 ++++++++++++--------------------------- 1 file changed, 31 insertions(+), 69 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 55addcedfd4..bae186c1535 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,38 +4,14 @@ on: push: branches: - development + - linux + - 'linux-release-*' + tags: + - 'release-*.*.*-linux*' pull_request: - workflow_call: - inputs: - repository: - default: desktop/desktop - required: false - type: string - ref: - required: true - type: string - upload-artifacts: - default: false - required: false - type: boolean - environment: - type: string - required: true - sign: - type: boolean - default: true - required: false - secrets: - AZURE_CODE_SIGNING_TENANT_ID: - AZURE_CODE_SIGNING_CLIENT_ID: - AZURE_CODE_SIGNING_CLIENT_SECRET: - DESKTOP_OAUTH_CLIENT_ID: - DESKTOP_OAUTH_CLIENT_SECRET: - APPLE_ID: - APPLE_ID_PASSWORD: - APPLE_TEAM_ID: - APPLE_APPLICATION_CERT: - APPLE_APPLICATION_CERT_PASSWORD: + branches: + - linux + - 'linux-release-*' env: NODE_VERSION: 20.17.0 @@ -66,17 +42,22 @@ jobs: name: ${{ matrix.friendlyName }} ${{ matrix.arch }} runs-on: ${{ matrix.os }} permissions: - contents: read + contents: write strategy: fail-fast: false matrix: - os: [macos-13-xl-arm64, windows-2019] + os: [macos-13, windows-2019, ubuntu-20.04] arch: [x64, arm64] include: - - os: macos-13-xl-arm64 + - os: macos-13 friendlyName: macOS - os: windows-2019 friendlyName: Windows + - os: ubuntu-20.04 + friendlyName: Ubuntu + exclude: + - os: ubuntu-20.04 + arch: arm64 timeout-minutes: 60 environment: ${{ inputs.environment }} env: @@ -103,14 +84,6 @@ jobs: - name: Build production app run: yarn build:prod env: - DESKTOP_OAUTH_CLIENT_ID: ${{ secrets.DESKTOP_OAUTH_CLIENT_ID }} - DESKTOP_OAUTH_CLIENT_SECRET: - ${{ secrets.DESKTOP_OAUTH_CLIENT_SECRET }} - APPLE_ID: ${{ secrets.APPLE_ID }} - APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} - APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} - APPLE_APPLICATION_CERT: ${{ secrets.APPLE_APPLICATION_CERT }} - KEY_PASSWORD: ${{ secrets.APPLE_APPLICATION_CERT_PASSWORD }} npm_config_arch: ${{ matrix.arch }} TARGET_ARCH: ${{ matrix.arch }} - name: Prepare testing environment @@ -124,31 +97,20 @@ jobs: - name: Run script tests if: matrix.arch == 'x64' run: yarn test:script - - name: Install Azure Code Signing Client - if: ${{ runner.os == 'Windows' && inputs.sign }} - run: | - $acsZip = Join-Path $env:RUNNER_TEMP "acs.zip" - $acsDir = Join-Path $env:RUNNER_TEMP "acs" - Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Microsoft.Trusted.Signing.Client/1.0.52 -OutFile $acsZip -Verbose - Expand-Archive $acsZip -Destination $acsDir -Force -Verbose - # Replace ancient signtool in electron-winstall with one that supports ACS - Copy-Item -Path "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\*" -Include signtool.exe,signtool.exe.manifest,Microsoft.Windows.Build.Signing.mssign32.dll.manifest,mssign32.dll,Microsoft.Windows.Build.Signing.wintrust.dll.manifest,wintrust.dll,Microsoft.Windows.Build.Appx.AppxSip.dll.manifest,AppxSip.dll,Microsoft.Windows.Build.Appx.AppxPackaging.dll.manifest,AppxPackaging.dll,Microsoft.Windows.Build.Appx.OpcServices.dll.manifest,OpcServices.dll -Destination "node_modules\electron-winstaller\vendor" -Verbose - - name: Package production app - run: yarn package - env: - npm_config_arch: ${{ matrix.arch }} - AZURE_TENANT_ID: ${{ secrets.AZURE_CODE_SIGNING_TENANT_ID }} - AZURE_CLIENT_ID: ${{ secrets.AZURE_CODE_SIGNING_CLIENT_ID }} - AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CODE_SIGNING_CLIENT_SECRET }} - - name: Upload artifacts - uses: actions/upload-artifact@v4 - if: ${{ inputs.upload-artifacts }} + - name: Package application + run: yarn run package + if: ${{ matrix.os == 'ubuntu-20.04' && matrix.arch == 'x64' }} + - name: Create Release + uses: softprops/action-gh-release@v1 + if: + ${{ matrix.os == 'ubuntu-20.04' && startsWith(github.ref, + 'refs/tags/') }} with: - name: ${{matrix.friendlyName}}-${{matrix.arch}} - path: | - dist/GitHub Desktop-${{matrix.arch}}.zip - dist/GitHubDesktop-*.nupkg - dist/GitHubDesktopSetup-${{matrix.arch}}.exe - dist/GitHubDesktopSetup-${{matrix.arch}}.msi - dist/bundle-size.json - if-no-files-found: error + files: | + dist/*.AppImage + dist/*.deb + dist/*.rpm + dist/*.txt + draft: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 48c116e2b0a19713da5ea20e6538183572bbfd0b Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 11 Aug 2024 21:21:35 -0300 Subject: [PATCH 25/41] feat(tooling): update base CI to use configured docker image (#898) Co-authored-by: theofficialgman <28281419+theofficialgman@users.noreply.github.com> --- .github/workflows/ci.yml | 82 +++++++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bae186c1535..702097a2dba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,6 +41,7 @@ jobs: build: name: ${{ matrix.friendlyName }} ${{ matrix.arch }} runs-on: ${{ matrix.os }} + container: ${{ matrix.image }} permissions: contents: write strategy: @@ -55,6 +56,18 @@ jobs: friendlyName: Windows - os: ubuntu-20.04 friendlyName: Ubuntu + image: ubuntu:18.04 + arch: x64 + environment: + AS: as + STRIP: strip + AR: ar + CC: gcc + CPP: cpp + CXX: g++ + LD: ld + FC: gfortran + PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig exclude: - os: ubuntu-20.04 arch: arm64 @@ -62,8 +75,43 @@ jobs: environment: ${{ inputs.environment }} env: RELEASE_CHANNEL: ${{ inputs.environment }} + AS: ${{ matrix.environment.AS }} + STRIP: ${{ matrix.environment.STRIP }} + AR: ${{ matrix.environment.AR }} + CC: ${{ matrix.environment.CC }} + CPP: ${{ matrix.environment.CPP }} + CXX: ${{ matrix.environment.CXX }} + LD: ${{ matrix.environment.LD }} + FC: ${{ matrix.environment.FC }} + PKG_CONFIG_PATH: ${{ matrix.environment.PKG_CONFIG_PATH }} + npm_config_arch: ${{ matrix.arch }} steps: - - uses: actions/checkout@v4 + - name: Install dependencies into dockerfile on Ubuntu + if: matrix.friendlyName == 'Ubuntu' + run: | + # ubuntu dockerfile is very minimal (only 122 packages are installed) + # add dependencies expected by scripts + apt update + apt install -y software-properties-common lsb-release \ + sudo wget curl build-essential jq autoconf automake \ + pkg-config ca-certificates rpm + # install new enough git to run actions/checkout + sudo add-apt-repository ppa:git-core/ppa -y + sudo apt update + sudo apt install -y git + # avoid "fatal: detected dubious ownership in repository at '/__w/shiftkey/desktop'" error + git config --global --add safe.directory '*' + - name: Add additional dependencies for Ubuntu x64 + if: ${{ matrix.friendlyName == 'Ubuntu' && matrix.arch == 'x64' }} + run: | + # add electron unit test dependencies + sudo apt install -y libasound2 libatk-bridge2.0-0 libatk1.0-0 \ + libatspi2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libdrm2 \ + libexpat1 libgbm1 libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 \ + libnss3 libpango-1.0-0 libx11-6 libxcb1 libxcomposite1 \ + libxdamage1 libxext6 libxfixes3 libxkbcommon0 libxrandr2 \ + libsecret-1-0 + - uses: actions/checkout@v3 with: repository: ${{ inputs.repository || github.repository }} ref: ${{ inputs.ref }} @@ -72,20 +120,26 @@ jobs: with: python-version: '3.11' - name: Use Node.js ${{ env.NODE_VERSION }} + if: matrix.friendlyName != 'Ubuntu' uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: yarn + - name: Install unofficial-builds Node.js ${{ matrix.node }} on Ubuntu + if: matrix.friendlyName == 'Ubuntu' + run: | + # This version supports older GLIBC (official builds required a minimum of GLIBC 2.28) + # this might break if you bump the `matrix.node` version - ensure you are on the latest version + # of which ever major/minor release which should have this variant available + # + # See https://github.com/nodejs/unofficial-builds/ for more information on these versions. + # + curl -sL 'https://unofficial-builds.nodejs.org/download/release/v${{ matrix.node }}/node-v${{ matrix.node }}-linux-x64-glibc-217.tar.xz' | xzcat | sudo tar -vx --strip-components=1 -C /usr/local/ + sudo npm install --global yarn - name: Install and build dependencies run: yarn - env: - npm_config_arch: ${{ matrix.arch }} - TARGET_ARCH: ${{ matrix.arch }} - name: Build production app run: yarn build:prod - env: - npm_config_arch: ${{ matrix.arch }} - TARGET_ARCH: ${{ matrix.arch }} - name: Prepare testing environment if: matrix.arch == 'x64' run: yarn test:setup @@ -99,11 +153,11 @@ jobs: run: yarn test:script - name: Package application run: yarn run package - if: ${{ matrix.os == 'ubuntu-20.04' && matrix.arch == 'x64' }} + if: ${{ matrix.friendlyName == 'Ubuntu' }} - name: Create Release uses: softprops/action-gh-release@v1 if: - ${{ matrix.os == 'ubuntu-20.04' && startsWith(github.ref, + ${{ matrix.friendlyName == 'Ubuntu' && startsWith(github.ref, 'refs/tags/') }} with: files: | @@ -114,3 +168,13 @@ jobs: draft: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Upload output artifacts + uses: actions/upload-artifact@v3 + if: matrix.friendlyName == 'Ubuntu' + with: + name: ${{ matrix.friendlyName }}-${{ matrix.arch }}-artifacts + path: | + dist/*.AppImage + dist/*.deb + dist/*.rpm + retention-days: 5 From fc5330eb90b30482ef5d3bbca81939e655962fd5 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 11 Aug 2024 21:23:08 -0300 Subject: [PATCH 26/41] feat(tooling): update build scripts to support ARM architectures (#898) Co-authored-by: theofficialgman <28281419+theofficialgman@users.noreply.github.com> --- script/build.ts | 23 ++++++++++------------- script/dist-info.ts | 15 +++++---------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/script/build.ts b/script/build.ts index cf18eb15be6..152de3bf01b 100755 --- a/script/build.ts +++ b/script/build.ts @@ -3,8 +3,7 @@ import * as path from 'path' import * as cp from 'child_process' -import * as os from 'os' -import packager, { OfficialArch, OsxNotarizeOptions } from 'electron-packager' +import packager, { OsxNotarizeOptions } from 'electron-packager' import frontMatter from 'front-matter' import { externals } from '../app/webpack.common' @@ -131,21 +130,19 @@ function packageApp() { ) } - const toPackageArch = (targetArch: string | undefined): OfficialArch => { - if (targetArch === undefined) { - targetArch = os.arch() + const getPackageArch = (): 'arm64' | 'x64' | 'armv7l' => { + const arch = process.env.npm_config_arch || process.arch + + if (arch === 'arm64' || arch === 'x64') { + return arch } - if ( - targetArch === 'arm64' || - targetArch === 'x64' || - targetArch === 'armv7l' - ) { - return targetArch + if (arch === 'arm') { + return 'armv7l' } throw new Error( - `Building Desktop for architecture '${targetArch}' is not supported` + `Building Desktop for architecture '${arch}' is not supported. Currently these architectures are supported: arm, arm64, x64` ) } @@ -174,7 +171,7 @@ function packageApp() { return packager({ name: getExecutableName(), platform: toPackagePlatform(process.platform), - arch: toPackageArch(process.env.TARGET_ARCH), + arch: getPackageArch(), asar: false, // TODO: Probably wanna enable this down the road. out: getDistRoot(), icon, diff --git a/script/dist-info.ts b/script/dist-info.ts index 420444f7448..459f01db905 100644 --- a/script/dist-info.ts +++ b/script/dist-info.ts @@ -114,18 +114,13 @@ export const getChannel = () => export function getDistArchitecture(): 'arm64' | 'x64' | 'armv7l' { // If a specific npm_config_arch is set, we use that one instead of the OS arch (to support cross compilation) - if ( - process.env.npm_config_arch === 'arm64' || - process.env.npm_config_arch === 'x64' || - process.env.npm_config_arch === 'armv7l' - ) { - return process.env.npm_config_arch - } + const arch = process.env.npm_config_arch || process.arch - if (process.arch === 'arm64') { - return 'arm64' + if (arch === 'arm64' || arch === 'x64' || arch === 'armv7l') { + return arch } - if (process.arch === 'arm') { + + if (arch === 'arm') { return 'armv7l' } From 29a853a7a26877fc59aea30ad372e387206eb593 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 11 Aug 2024 21:23:32 -0300 Subject: [PATCH 27/41] feat(tooling): update electron-builder package tooling to support ARM architectures (#898) Co-authored-by: theofficialgman <28281419+theofficialgman@users.noreply.github.com> --- script/electron-builder-linux.yml | 2 +- script/package-electron-builder.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/script/electron-builder-linux.yml b/script/electron-builder-linux.yml index f73156cbadb..77203eb0b46 100644 --- a/script/electron-builder-linux.yml +++ b/script/electron-builder-linux.yml @@ -1,4 +1,4 @@ -artifactName: 'GitHubDesktop-${os}-${version}.${ext}' +artifactName: 'GitHubDesktop-${os}-${arch}-${version}.${ext}' linux: category: 'GNOME;GTK;Development' packageCategory: 'GNOME;GTK;Development' diff --git a/script/package-electron-builder.ts b/script/package-electron-builder.ts index 6292c28b9f4..2f56e73fba5 100644 --- a/script/package-electron-builder.ts +++ b/script/package-electron-builder.ts @@ -10,7 +10,8 @@ const globPromise = promisify(glob) import { getDistPath, getDistRoot } from './dist-info' function getArchitecture() { - switch (process.arch) { + const arch = process.env.npm_config_arch || process.arch + switch (arch) { case 'arm64': return '--arm64' case 'arm': From 027e778d723ff9b736ee3f1375e2bd61dabcf044 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 11 Aug 2024 21:23:57 -0300 Subject: [PATCH 28/41] feat(tooling): update debian package script to support ARM architectures (#898) Co-authored-by: theofficialgman <28281419+theofficialgman@users.noreply.github.com> --- script/package-debian.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/script/package-debian.ts b/script/package-debian.ts index 9a918473070..b184481843d 100644 --- a/script/package-debian.ts +++ b/script/package-debian.ts @@ -10,7 +10,8 @@ import { getVersion } from '../app/package-info' import { getDistPath, getDistRoot } from './dist-info' function getArchitecture() { - switch (process.arch) { + const arch = process.env.npm_config_arch || process.arch + switch (arch) { case 'arm64': return 'arm64' case 'arm': @@ -107,7 +108,7 @@ export async function packageDebian(): Promise { const oldPath = files[0] - const newFileName = `GitHubDesktop-linux-${getVersion()}.deb` + const newFileName = `GitHubDesktop-linux-${getArchitecture()}-${getVersion()}.deb` const newPath = join(distRoot, newFileName) await rename(oldPath, newPath) From a78f424b22712fd3906842c8f6967de31a7a472b Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 11 Aug 2024 21:24:23 -0300 Subject: [PATCH 29/41] feat(tooling): update redhat package script to support ARM architectures (#898) Co-authored-by: theofficialgman <28281419+theofficialgman@users.noreply.github.com> --- script/package-redhat.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/script/package-redhat.ts b/script/package-redhat.ts index 37bd3819293..61fe4a1162e 100644 --- a/script/package-redhat.ts +++ b/script/package-redhat.ts @@ -10,7 +10,8 @@ import { getVersion } from '../app/package-info' import { getDistPath, getDistRoot } from './dist-info' function getArchitecture() { - switch (process.arch) { + const arch = process.env.npm_config_arch || process.arch + switch (arch) { case 'arm64': return 'aarch64' case 'arm': @@ -103,7 +104,7 @@ export async function packageRedhat(): Promise { const oldPath = files[0] - const newFileName = `GitHubDesktop-linux-${getVersion()}.rpm` + const newFileName = `GitHubDesktop-linux-${getArchitecture()}-${getVersion()}.rpm` const newPath = join(distRoot, newFileName) await rename(oldPath, newPath) From 66838b62e1e4fa46e9690fa0fdee51ec2c3ae6dd Mon Sep 17 00:00:00 2001 From: theofficialgman <28281419+theofficialgman@users.noreply.github.com> Date: Sun, 9 Jul 2023 19:09:35 -0400 Subject: [PATCH 30/41] feat(tooling): enable workflow for ARM32/ARM64 on Ubuntu (#897) --- .github/workflows/ci.yml | 43 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 702097a2dba..25c41d47fc4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,9 +68,36 @@ jobs: LD: ld FC: gfortran PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig - exclude: - os: ubuntu-20.04 + friendlyName: Ubuntu + image: ubuntu:18.04 arch: arm64 + environment: + AS: aarch64-linux-gnu-as + STRIP: aarch64-linux-gnu-strip + AR: aarch64-linux-gnu-ar + CC: aarch64-linux-gnu-gcc + CPP: aarch64-linux-gnu-cpp + CXX: aarch64-linux-gnu-g++ + LD: aarch64-linux-gnu-ld + FC: aarch64-linux-gnu-gfortran + PKG_CONFIG_PATH: /usr/lib/aarch64-linux-gnu/pkgconfig + - os: ubuntu-20.04 + friendlyName: Ubuntu + image: ubuntu:18.04 + arch: arm + node: 18.16.1 + environment: + AS: arm-linux-gnueabihf-as + STRIP: arm-linux-gnueabihf-strip + AR: arm-linux-gnueabihf-ar + CC: arm-linux-gnueabihf-gcc + CPP: arm-linux-gnueabihf-cpp + CXX: arm-linux-gnueabihf-g++ + LD: arm-linux-gnueabihf-ld + FC: arm-linux-gnueabihf-gfortran + PKG_CONFIG_PATH: /usr/lib/arm-linux-gnueabihf/pkgconfig + timeout-minutes: 60 environment: ${{ inputs.environment }} env: @@ -111,6 +138,20 @@ jobs: libnss3 libpango-1.0-0 libx11-6 libxcb1 libxcomposite1 \ libxdamage1 libxext6 libxfixes3 libxkbcommon0 libxrandr2 \ libsecret-1-0 + - name: Add additional dependencies for Ubuntu arm64 + if: ${{ matrix.friendlyName == 'Ubuntu' && matrix.arch == 'arm64' }} + run: | + sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu binutils-aarch64-linux-gnu + - name: Add additional dependencies for Ubuntu arm + if: ${{ matrix.friendlyName == 'Ubuntu' && matrix.arch == 'arm' }} + run: | + sudo apt-get install -y gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf binutils-arm-linux-gnueabihf pkg-config-arm-linux-gnueabihf + sudo sed -i "s/^deb/deb [arch=amd64,i386]/g" /etc/apt/sources.list + echo "deb [arch=arm64,armhf] http://ports.ubuntu.com/ $(lsb_release -s -c) main universe multiverse restricted" | sudo tee -a /etc/apt/sources.list + echo "deb [arch=arm64,armhf] http://ports.ubuntu.com/ $(lsb_release -s -c)-updates main universe multiverse restricted" | sudo tee -a /etc/apt/sources.list + sudo dpkg --add-architecture armhf + sudo apt-get update + sudo apt-get install -y libx11-dev:armhf libx11-xcb-dev:armhf libxkbfile-dev:armhf libsecret-1-dev:armhf - uses: actions/checkout@v3 with: repository: ${{ inputs.repository || github.repository }} From 2aff5cf7ac2826d8e29b50cc4b7a8ae9f4d1d2c6 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Mon, 10 Jul 2023 08:50:35 -0300 Subject: [PATCH 31/41] feat(tooling): introduce separate publish step which runs after build (#899 #900) --- .github/workflows/ci.yml | 80 +++++++++-- .github/workflows/release-pr.yml | 2 +- .gitignore | 1 + script/generate-release-notes.ts | 230 +++++++++++++++++++++++++++++++ script/package.ts | 3 + 5 files changed, 301 insertions(+), 15 deletions(-) create mode 100644 script/generate-release-notes.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 25c41d47fc4..f1a4dfe454b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,6 +8,7 @@ on: - 'linux-release-*' tags: - 'release-*.*.*-linux*' + - 'release-*.*.*-test*' pull_request: branches: - linux @@ -195,20 +196,6 @@ jobs: - name: Package application run: yarn run package if: ${{ matrix.friendlyName == 'Ubuntu' }} - - name: Create Release - uses: softprops/action-gh-release@v1 - if: - ${{ matrix.friendlyName == 'Ubuntu' && startsWith(github.ref, - 'refs/tags/') }} - with: - files: | - dist/*.AppImage - dist/*.deb - dist/*.rpm - dist/*.txt - draft: true - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload output artifacts uses: actions/upload-artifact@v3 if: matrix.friendlyName == 'Ubuntu' @@ -218,4 +205,69 @@ jobs: dist/*.AppImage dist/*.deb dist/*.rpm + dist/*.sha256 retention-days: 5 + + publish: + name: Create GitHub release + needs: [build, lint] + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') + permissions: + contents: write + steps: + - uses: actions/checkout@v3 + + - name: Use Node.js 18.14.0 + uses: actions/setup-node@v3 + with: + node-version: 18.14.0 + cache: yarn + + - name: Download all artifacts + uses: actions/download-artifact@v2 + with: + path: './artifacts' + + - name: Display structure of downloaded files + run: ls -R + working-directory: './artifacts' + + - name: Get tag name without prefix + run: | + RELEASE_TAG=${GITHUB_REF/refs\/tags\//} + echo "RELEASE_TAG=${RELEASE_TAG}" >> $GITHUB_ENV + tagNameWithoutPrefix="${RELEASE_TAG:1}" + echo "RELEASE_TAG_WITHOUT_PREFIX=${tagNameWithoutPrefix}" >> $GITHUB_ENV + + # TODO: generate release notes + # - pull in default if version matches X.Y.Z-linux1 + # - otherwise stub template + + - name: Generate release notes + run: | + node -v + yarn + node -r ts-node/register script/generate-release-notes.ts "${{ github.workspace }}/artifacts" "${{ env.RELEASE_TAG_WITHOUT_PREFIX }}" + RELEASE_NOTES_FILE=script/release_notes.txt + if [[ ! -f "$RELEASE_NOTES_FILE" ]]; then + echo "$RELEASE_NOTES_FILE does not exist. Something might have gone wrong while generating the release notes." + exit 1 + fi + echo "Release notes:" + echo "---" + cat ${RELEASE_NOTES_FILE} + echo "---" + + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + name: GitHub Desktop for Linux ${{ env.RELEASE_TAG_WITHOUT_PREFIX }} + body_path: script/release_notes.txt + files: | + artifacts/*.AppImage + artifacts/*.deb + artifacts/*.rpm + draft: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index f03f1f074f3..72f2ea0cad9 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -37,7 +37,7 @@ jobs: private_key: ${{ secrets.DESKTOP_RELEASES_APP_PRIVATE_KEY }} - name: Create Release Pull Request - uses: peter-evans/create-pull-request@v6.0.5 + uses: peter-evans/create-pull-request@v6.1.0 if: | startsWith(github.ref, 'refs/heads/releases/') && !contains(github.ref, 'test') with: diff --git a/.gitignore b/.gitignore index 91bdd56682f..5b9cda8e24e 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ vendor/windows-argv-parser/build/ junit*.xml *.swp tslint-rules/ +script/release_notes.txt diff --git a/script/generate-release-notes.ts b/script/generate-release-notes.ts new file mode 100644 index 00000000000..31183e51bd1 --- /dev/null +++ b/script/generate-release-notes.ts @@ -0,0 +1,230 @@ +/* eslint-disable no-sync */ + +const glob = require('glob') +const { dirname, join } = require('path') +const fs = require('fs') + +type ReleaseNotesGroupType = 'new' | 'added' | 'fixed' | 'improved' | 'removed' + +type ReleaseNotesGroups = Record> + +type ReleaseNoteEntry = { + text: string + ids: Array + contributor?: string +} + +// 3 architectures * 3 package formats * 2 files (package + checksum file) +const SUCCESSFUL_RELEASE_FILE_COUNT = 3 * 3 * 2 + +const Glob = glob.GlobSync + +const args = process.argv.slice(2) +const artifactsDir = args[0] + +if (!artifactsDir) { + console.error( + `🔴 First parameter with artifacts directory not found. Aborting...` + ) + process.exit(1) +} + +const releaseTagWithoutPrefix = args[1] +if (!releaseTagWithoutPrefix) { + console.error(`🔴 Second parameter with release tag not found. Aborting...`) + process.exit(1) +} + +console.log( + `Preparing release notes for release tag ${releaseTagWithoutPrefix}` +) + +const files = new Glob(artifactsDir + '/**/*', { nodir: true }) + +const matches = files.found as Array + +const fileCount = matches.length + +if (SUCCESSFUL_RELEASE_FILE_COUNT !== fileCount) { + console.error( + `🔴 Artifacts folder has ${fileCount} assets, expecting ${SUCCESSFUL_RELEASE_FILE_COUNT}. Please check the GH Actions artifacts to see which are missing.` + ) + process.exit(1) +} + +console.log(`Found ${fileCount} files in artifacts directory`) + +const releaseNotesByGroup = getReleaseGroups(releaseTagWithoutPrefix) + +const draftReleaseNotes = generateDraftReleaseNotes(releaseNotesByGroup) +const releaseNotesPath = join(__dirname, 'release_notes.txt') + +fs.writeFileSync(releaseNotesPath, draftReleaseNotes, { encoding: 'utf8' }) + +console.log( + `✅ All done! The release notes have been written to ${releaseNotesPath}` +) + +function extractIds(str: string): Array { + const idRegex = /#(\d+)/g + + const idArray = new Array() + let match + + while ((match = idRegex.exec(str))) { + const textValue = match[1].trim() + const numValue = parseInt(textValue, 10) + if (!isNaN(numValue)) { + idArray.push(numValue) + } + } + + return idArray +} + +function parseCategory(str: string): ReleaseNotesGroupType | null { + const input = str.toLocaleLowerCase() + switch (input) { + case 'added': + case 'fixed': + case 'improved': + case 'new': + case 'removed': + return input + default: + return null + } +} + +function isInitialTag(tag: string): boolean { + return tag.endsWith('-linux1') || tag.endsWith('-test1') +} + +function getVersionWithoutSuffix(tag: string): string { + return tag.replace('-linux1', '').replace('-test1', '') +} + +function getReleaseGroups(version: string): ReleaseNotesGroups { + if (!isInitialTag(version)) { + return { + new: [], + added: [], + fixed: [], + improved: [], + removed: [], + } + } + + const upstreamVersion = getVersionWithoutSuffix(version) + const rootDir = dirname(__dirname) + const changelogFile = fs.readFileSync(join(rootDir, 'changelog.json')) + const changelogJson = JSON.parse(changelogFile) + const releases = changelogJson['releases'] + const changelogForVersion: Array | undefined = + releases[upstreamVersion] + + if (!changelogForVersion) { + console.error( + `🔴 Changelog version ${upstreamVersion} not found in changelog.json, which is required for publishing a release based off an upstream releease. Aborting...` + ) + process.exit(1) + } + + console.log(`found release notes`, changelogForVersion) + + const releaseNotesByGroup: ReleaseNotesGroups = { + new: [], + added: [], + fixed: [], + improved: [], + removed: [], + } + + const releaseEntryExternalContributor = /\[(.*)\](.*)- (.*)\. Thanks (.*)!/ + const releaseEntryRegex = /\[(.*)\](.*)- (.*)/ + + for (const entry of changelogForVersion) { + const externalMatch = releaseEntryExternalContributor.exec(entry) + if (externalMatch) { + const category = parseCategory(externalMatch[1]) + const text = externalMatch[2].trim() + const ids = extractIds(externalMatch[3]) + const contributor = externalMatch[4] + + if (!category) { + console.warn(`unable to identify category for '${entry}'`) + } else { + releaseNotesByGroup[category].push({ + text, + ids, + contributor, + }) + } + } else { + const match = releaseEntryRegex.exec(entry) + if (match) { + const category = parseCategory(match[1]) + const text = match[2].trim() + const ids = extractIds(match[3]) + if (!category) { + console.warn(`unable to identify category for '${entry}'`) + } else { + releaseNotesByGroup[category].push({ + text, + ids, + }) + } + } else { + console.warn(`release entry does not match any format: '${entry}'`) + } + } + } + + return releaseNotesByGroup +} + +function formatReleaseNote(note: ReleaseNoteEntry): string { + const idsAsUrls = note.ids + .map(id => `https://github.com/desktop/desktop/issues/${id}`) + .join(' ') + const contributorNote = note.contributor + ? `. Thanks ${note.contributor}!` + : '' + + const template = ` - ${note.text} - ${idsAsUrls}${contributorNote}` + + return template.trim() +} + +function renderSection( + name: string, + items: Array, + omitIfEmpty: boolean = true +): string { + if (items.length === 0 && omitIfEmpty) { + return '' + } + + const itemsText = + items.length === 0 ? 'TODO' : items.map(formatReleaseNote).join('\n') + + return ` +## ${name} + +${itemsText} + ` +} + +/** + * Takes the release notes entries and the SHA entries, then merges them into the full draft release notes ✨ + */ +function generateDraftReleaseNotes( + releaseNotesGroups: ReleaseNotesGroups +): string { + return ` +${renderSection('New', releaseNotesGroups.new)} +${renderSection('Added', releaseNotesGroups.added)} +${renderSection('Fixed', releaseNotesGroups.fixed, false)} +${renderSection('Improved', releaseNotesGroups.improved, false)} +${renderSection('Removed', releaseNotesGroups.removed)}` +} diff --git a/script/package.ts b/script/package.ts index b32499d40de..5c6085d4c0e 100644 --- a/script/package.ts +++ b/script/package.ts @@ -203,6 +203,9 @@ async function generateChecksums(files: Array) { for (const [fullPath, checksum] of checksums) { const fileName = path.basename(fullPath) checksumsText += `${checksum} - ${fileName}\n` + + const checksumFilePath = `${fullPath}.sha256` + await writeFile(checksumFilePath, checksum) } const checksumFile = path.join(distRoot, 'checksums.txt') From 38c2964184602ade702cc4bb7c490fbd4ba79047 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Wed, 20 Dec 2023 10:36:39 -0400 Subject: [PATCH 32/41] fix(tooling): assorted changes to the upstream CI configuration --- .github/workflows/ci.yml | 260 +++++++++++---------------------------- 1 file changed, 74 insertions(+), 186 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f1a4dfe454b..e185647e9b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,11 +8,41 @@ on: - 'linux-release-*' tags: - 'release-*.*.*-linux*' - - 'release-*.*.*-test*' pull_request: branches: - linux - 'linux-release-*' + workflow_call: + inputs: + repository: + default: desktop/desktop + required: false + type: string + ref: + required: true + type: string + upload-artifacts: + default: false + required: false + type: boolean + environment: + type: string + required: true + sign: + type: boolean + default: true + required: false + secrets: + AZURE_CODE_SIGNING_TENANT_ID: + AZURE_CODE_SIGNING_CLIENT_ID: + AZURE_CODE_SIGNING_CLIENT_SECRET: + DESKTOP_OAUTH_CLIENT_ID: + DESKTOP_OAUTH_CLIENT_SECRET: + APPLE_ID: + APPLE_ID_PASSWORD: + APPLE_TEAM_ID: + APPLE_APPLICATION_CERT: + APPLE_APPLICATION_CERT_PASSWORD: env: NODE_VERSION: 20.17.0 @@ -42,118 +72,24 @@ jobs: build: name: ${{ matrix.friendlyName }} ${{ matrix.arch }} runs-on: ${{ matrix.os }} - container: ${{ matrix.image }} permissions: - contents: write + contents: read strategy: fail-fast: false matrix: - os: [macos-13, windows-2019, ubuntu-20.04] + os: [macos-13, windows-2019] arch: [x64, arm64] include: - os: macos-13 friendlyName: macOS - os: windows-2019 friendlyName: Windows - - os: ubuntu-20.04 - friendlyName: Ubuntu - image: ubuntu:18.04 - arch: x64 - environment: - AS: as - STRIP: strip - AR: ar - CC: gcc - CPP: cpp - CXX: g++ - LD: ld - FC: gfortran - PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig - - os: ubuntu-20.04 - friendlyName: Ubuntu - image: ubuntu:18.04 - arch: arm64 - environment: - AS: aarch64-linux-gnu-as - STRIP: aarch64-linux-gnu-strip - AR: aarch64-linux-gnu-ar - CC: aarch64-linux-gnu-gcc - CPP: aarch64-linux-gnu-cpp - CXX: aarch64-linux-gnu-g++ - LD: aarch64-linux-gnu-ld - FC: aarch64-linux-gnu-gfortran - PKG_CONFIG_PATH: /usr/lib/aarch64-linux-gnu/pkgconfig - - os: ubuntu-20.04 - friendlyName: Ubuntu - image: ubuntu:18.04 - arch: arm - node: 18.16.1 - environment: - AS: arm-linux-gnueabihf-as - STRIP: arm-linux-gnueabihf-strip - AR: arm-linux-gnueabihf-ar - CC: arm-linux-gnueabihf-gcc - CPP: arm-linux-gnueabihf-cpp - CXX: arm-linux-gnueabihf-g++ - LD: arm-linux-gnueabihf-ld - FC: arm-linux-gnueabihf-gfortran - PKG_CONFIG_PATH: /usr/lib/arm-linux-gnueabihf/pkgconfig - timeout-minutes: 60 environment: ${{ inputs.environment }} env: RELEASE_CHANNEL: ${{ inputs.environment }} - AS: ${{ matrix.environment.AS }} - STRIP: ${{ matrix.environment.STRIP }} - AR: ${{ matrix.environment.AR }} - CC: ${{ matrix.environment.CC }} - CPP: ${{ matrix.environment.CPP }} - CXX: ${{ matrix.environment.CXX }} - LD: ${{ matrix.environment.LD }} - FC: ${{ matrix.environment.FC }} - PKG_CONFIG_PATH: ${{ matrix.environment.PKG_CONFIG_PATH }} - npm_config_arch: ${{ matrix.arch }} steps: - - name: Install dependencies into dockerfile on Ubuntu - if: matrix.friendlyName == 'Ubuntu' - run: | - # ubuntu dockerfile is very minimal (only 122 packages are installed) - # add dependencies expected by scripts - apt update - apt install -y software-properties-common lsb-release \ - sudo wget curl build-essential jq autoconf automake \ - pkg-config ca-certificates rpm - # install new enough git to run actions/checkout - sudo add-apt-repository ppa:git-core/ppa -y - sudo apt update - sudo apt install -y git - # avoid "fatal: detected dubious ownership in repository at '/__w/shiftkey/desktop'" error - git config --global --add safe.directory '*' - - name: Add additional dependencies for Ubuntu x64 - if: ${{ matrix.friendlyName == 'Ubuntu' && matrix.arch == 'x64' }} - run: | - # add electron unit test dependencies - sudo apt install -y libasound2 libatk-bridge2.0-0 libatk1.0-0 \ - libatspi2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libdrm2 \ - libexpat1 libgbm1 libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 \ - libnss3 libpango-1.0-0 libx11-6 libxcb1 libxcomposite1 \ - libxdamage1 libxext6 libxfixes3 libxkbcommon0 libxrandr2 \ - libsecret-1-0 - - name: Add additional dependencies for Ubuntu arm64 - if: ${{ matrix.friendlyName == 'Ubuntu' && matrix.arch == 'arm64' }} - run: | - sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu binutils-aarch64-linux-gnu - - name: Add additional dependencies for Ubuntu arm - if: ${{ matrix.friendlyName == 'Ubuntu' && matrix.arch == 'arm' }} - run: | - sudo apt-get install -y gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf binutils-arm-linux-gnueabihf pkg-config-arm-linux-gnueabihf - sudo sed -i "s/^deb/deb [arch=amd64,i386]/g" /etc/apt/sources.list - echo "deb [arch=arm64,armhf] http://ports.ubuntu.com/ $(lsb_release -s -c) main universe multiverse restricted" | sudo tee -a /etc/apt/sources.list - echo "deb [arch=arm64,armhf] http://ports.ubuntu.com/ $(lsb_release -s -c)-updates main universe multiverse restricted" | sudo tee -a /etc/apt/sources.list - sudo dpkg --add-architecture armhf - sudo apt-get update - sudo apt-get install -y libx11-dev:armhf libx11-xcb-dev:armhf libxkbfile-dev:armhf libsecret-1-dev:armhf - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: ${{ inputs.repository || github.repository }} ref: ${{ inputs.ref }} @@ -162,26 +98,28 @@ jobs: with: python-version: '3.11' - name: Use Node.js ${{ env.NODE_VERSION }} - if: matrix.friendlyName != 'Ubuntu' uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: yarn - - name: Install unofficial-builds Node.js ${{ matrix.node }} on Ubuntu - if: matrix.friendlyName == 'Ubuntu' - run: | - # This version supports older GLIBC (official builds required a minimum of GLIBC 2.28) - # this might break if you bump the `matrix.node` version - ensure you are on the latest version - # of which ever major/minor release which should have this variant available - # - # See https://github.com/nodejs/unofficial-builds/ for more information on these versions. - # - curl -sL 'https://unofficial-builds.nodejs.org/download/release/v${{ matrix.node }}/node-v${{ matrix.node }}-linux-x64-glibc-217.tar.xz' | xzcat | sudo tar -vx --strip-components=1 -C /usr/local/ - sudo npm install --global yarn - name: Install and build dependencies run: yarn + env: + npm_config_arch: ${{ matrix.arch }} + TARGET_ARCH: ${{ matrix.arch }} - name: Build production app run: yarn build:prod + env: + DESKTOP_OAUTH_CLIENT_ID: ${{ secrets.DESKTOP_OAUTH_CLIENT_ID }} + DESKTOP_OAUTH_CLIENT_SECRET: + ${{ secrets.DESKTOP_OAUTH_CLIENT_SECRET }} + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + APPLE_APPLICATION_CERT: ${{ secrets.APPLE_APPLICATION_CERT }} + KEY_PASSWORD: ${{ secrets.APPLE_APPLICATION_CERT_PASSWORD }} + npm_config_arch: ${{ matrix.arch }} + TARGET_ARCH: ${{ matrix.arch }} - name: Prepare testing environment if: matrix.arch == 'x64' run: yarn test:setup @@ -193,81 +131,31 @@ jobs: - name: Run script tests if: matrix.arch == 'x64' run: yarn test:script - - name: Package application - run: yarn run package - if: ${{ matrix.friendlyName == 'Ubuntu' }} - - name: Upload output artifacts - uses: actions/upload-artifact@v3 - if: matrix.friendlyName == 'Ubuntu' - with: - name: ${{ matrix.friendlyName }}-${{ matrix.arch }}-artifacts - path: | - dist/*.AppImage - dist/*.deb - dist/*.rpm - dist/*.sha256 - retention-days: 5 - - publish: - name: Create GitHub release - needs: [build, lint] - runs-on: ubuntu-latest - if: startsWith(github.ref, 'refs/tags/') - permissions: - contents: write - steps: - - uses: actions/checkout@v3 - - - name: Use Node.js 18.14.0 - uses: actions/setup-node@v3 - with: - node-version: 18.14.0 - cache: yarn - - - name: Download all artifacts - uses: actions/download-artifact@v2 - with: - path: './artifacts' - - - name: Display structure of downloaded files - run: ls -R - working-directory: './artifacts' - - - name: Get tag name without prefix + - name: Install Azure Code Signing Client + if: ${{ runner.os == 'Windows' && inputs.sign }} run: | - RELEASE_TAG=${GITHUB_REF/refs\/tags\//} - echo "RELEASE_TAG=${RELEASE_TAG}" >> $GITHUB_ENV - tagNameWithoutPrefix="${RELEASE_TAG:1}" - echo "RELEASE_TAG_WITHOUT_PREFIX=${tagNameWithoutPrefix}" >> $GITHUB_ENV - - # TODO: generate release notes - # - pull in default if version matches X.Y.Z-linux1 - # - otherwise stub template - - - name: Generate release notes - run: | - node -v - yarn - node -r ts-node/register script/generate-release-notes.ts "${{ github.workspace }}/artifacts" "${{ env.RELEASE_TAG_WITHOUT_PREFIX }}" - RELEASE_NOTES_FILE=script/release_notes.txt - if [[ ! -f "$RELEASE_NOTES_FILE" ]]; then - echo "$RELEASE_NOTES_FILE does not exist. Something might have gone wrong while generating the release notes." - exit 1 - fi - echo "Release notes:" - echo "---" - cat ${RELEASE_NOTES_FILE} - echo "---" - - - name: Create Release - uses: softprops/action-gh-release@v2 - with: - name: GitHub Desktop for Linux ${{ env.RELEASE_TAG_WITHOUT_PREFIX }} - body_path: script/release_notes.txt - files: | - artifacts/*.AppImage - artifacts/*.deb - artifacts/*.rpm - draft: true + $acsZip = Join-Path $env:RUNNER_TEMP "acs.zip" + $acsDir = Join-Path $env:RUNNER_TEMP "acs" + Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Microsoft.Trusted.Signing.Client/1.0.52 -OutFile $acsZip -Verbose + Expand-Archive $acsZip -Destination $acsDir -Force -Verbose + # Replace ancient signtool in electron-winstall with one that supports ACS + Copy-Item -Path "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\*" -Include signtool.exe,signtool.exe.manifest,Microsoft.Windows.Build.Signing.mssign32.dll.manifest,mssign32.dll,Microsoft.Windows.Build.Signing.wintrust.dll.manifest,wintrust.dll,Microsoft.Windows.Build.Appx.AppxSip.dll.manifest,AppxSip.dll,Microsoft.Windows.Build.Appx.AppxPackaging.dll.manifest,AppxPackaging.dll,Microsoft.Windows.Build.Appx.OpcServices.dll.manifest,OpcServices.dll -Destination "node_modules\electron-winstaller\vendor" -Verbose + - name: Package production app + run: yarn package env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + npm_config_arch: ${{ matrix.arch }} + AZURE_TENANT_ID: ${{ secrets.AZURE_CODE_SIGNING_TENANT_ID }} + AZURE_CLIENT_ID: ${{ secrets.AZURE_CODE_SIGNING_CLIENT_ID }} + AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CODE_SIGNING_CLIENT_SECRET }} + - name: Upload artifacts + uses: actions/upload-artifact@v4 + if: ${{ inputs.upload-artifacts }} + with: + name: ${{matrix.friendlyName}}-${{matrix.arch}} + path: | + dist/GitHub Desktop-${{matrix.arch}}.zip + dist/GitHubDesktop-*.nupkg + dist/GitHubDesktopSetup-${{matrix.arch}}.exe + dist/GitHubDesktopSetup-${{matrix.arch}}.msi + dist/bundle-size.json + if-no-files-found: error From 3a031c167bc36fd20e5d8198e0951378988d6a58 Mon Sep 17 00:00:00 2001 From: mon-jai <91261297+mon-jai@users.noreply.github.com> Date: Sun, 8 Oct 2023 23:26:22 +0800 Subject: [PATCH 33/41] fix: add an option to use the Windows title bar (#912) Co-authored-by: Brendan Forster --- app/src/lib/app-state.ts | 4 ++ app/src/lib/get-title-bar-config.ts | 48 ++++++++++++++++ app/src/lib/ipc-shared.ts | 4 ++ app/src/lib/stores/app-store.ts | 15 +++++ app/src/main-process/app-window.ts | 4 ++ app/src/main-process/main.ts | 19 +++++++ app/src/models/popup.ts | 2 + app/src/ui/app.tsx | 19 ++++--- app/src/ui/dispatcher/dispatcher.ts | 14 +++++ app/src/ui/lib/title-bar-style.ts | 17 ++++++ app/src/ui/main-process-proxy.ts | 7 +++ app/src/ui/preferences/appearance.tsx | 65 ++++++++++++++++++---- app/src/ui/preferences/confirm-restart.tsx | 58 +++++++++++++++++++ app/src/ui/preferences/preferences.tsx | 13 ++++- app/src/ui/window/title-bar.tsx | 12 ++-- app/src/ui/window/window-controls.tsx | 5 -- app/styles/ui/window/_title-bar.scss | 10 +++- 17 files changed, 287 insertions(+), 29 deletions(-) create mode 100644 app/src/lib/get-title-bar-config.ts create mode 100644 app/src/ui/lib/title-bar-style.ts create mode 100644 app/src/ui/preferences/confirm-restart.tsx diff --git a/app/src/lib/app-state.ts b/app/src/lib/app-state.ts index 3ec85adc2f8..bdf06b6cdc7 100644 --- a/app/src/lib/app-state.ts +++ b/app/src/lib/app-state.ts @@ -32,6 +32,7 @@ import { WindowState } from './window-state' import { Shell } from './shells' import { ApplicableTheme, ApplicationTheme } from '../ui/lib/application-theme' +import { TitleBarStyle } from '../ui/lib/title-bar-style' import { IAccountRepositories } from './stores/api-repositories-store' import { ManualConflictResolution } from '../models/manual-conflict-resolution' import { Banner } from '../models/banner' @@ -292,6 +293,9 @@ export interface IAppState { /** The selected tab size preference */ readonly selectedTabSize: number + /** The selected title bar style for the application */ + readonly titleBarStyle: TitleBarStyle + /** * A map keyed on a user account (GitHub.com or GitHub Enterprise) * containing an object with repositories that the authenticated diff --git a/app/src/lib/get-title-bar-config.ts b/app/src/lib/get-title-bar-config.ts new file mode 100644 index 00000000000..ced0aeddb2f --- /dev/null +++ b/app/src/lib/get-title-bar-config.ts @@ -0,0 +1,48 @@ +import { writeFile } from 'fs/promises' +import { existsSync, readFileSync } from 'fs' +import { join } from 'path' +import { app } from 'electron' +import { TitleBarStyle } from '../ui/lib/title-bar-style' + +export type TitleBarConfig = { + titleBarStyle: TitleBarStyle +} + +let cachedTitleBarConfig: TitleBarConfig | null = null + +// The function has to be synchronous, +// since we need its return value to create electron BrowserWindow +export function readTitleBarConfigFileSync(): TitleBarConfig { + if (cachedTitleBarConfig) { + return cachedTitleBarConfig + } + + const titleBarConfigPath = getTitleBarConfigPath() + + if (existsSync(titleBarConfigPath)) { + const storedTitleBarConfig = JSON.parse( + readFileSync(titleBarConfigPath, 'utf8') + ) + + if ( + storedTitleBarConfig.titleBarStyle === 'native' || + storedTitleBarConfig.titleBarStyle === 'custom' + ) { + cachedTitleBarConfig = storedTitleBarConfig + } + } + + // Cache the default value if the config file is not found, or if it contains an invalid value. + if (cachedTitleBarConfig == null) { + cachedTitleBarConfig = { titleBarStyle: 'native' } + } + + return cachedTitleBarConfig +} + +export function saveTitleBarConfigFile(config: TitleBarConfig) { + return writeFile(getTitleBarConfigPath(), JSON.stringify(config), 'utf8') +} + +const getTitleBarConfigPath = () => + join(app.getPath('userData'), '.title-bar-config') diff --git a/app/src/lib/ipc-shared.ts b/app/src/lib/ipc-shared.ts index 8b6387b37e8..fc062dcbc72 100644 --- a/app/src/lib/ipc-shared.ts +++ b/app/src/lib/ipc-shared.ts @@ -13,6 +13,7 @@ import { Architecture } from './get-architecture' import { EndpointToken } from './endpoint-token' import { PathType } from '../ui/lib/app-proxy' import { ThemeSource } from '../ui/lib/theme-source' +import { TitleBarStyle } from '../ui/lib/title-bar-style' import { DesktopNotificationPermission } from 'desktop-notifications/dist/notification-permission' import { NotificationCallback } from 'desktop-notifications/dist/notification-callback' import { DesktopAliveEvent } from './stores/alive-store' @@ -66,6 +67,7 @@ export type RequestChannels = { blur: () => void 'update-accounts': (accounts: ReadonlyArray) => void 'quit-and-install-updates': () => void + 'restart-app': () => void 'quit-app': () => void 'minimize-window': () => void 'maximize-window': () => void @@ -124,6 +126,8 @@ export type RequestResponseChannels = { 'should-use-dark-colors': () => Promise 'save-guid': (guid: string) => Promise 'get-guid': () => Promise + 'save-title-bar-style': (titleBarStyle: TitleBarStyle) => Promise + 'get-title-bar-style': () => Promise 'show-notification': ( title: string, body: string, diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 3a27a1d75d4..81c8a39d357 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -80,6 +80,7 @@ import { getPersistedThemeName, setPersistedTheme, } from '../../ui/lib/application-theme' +import { TitleBarStyle } from '../../ui/lib/title-bar-style' import { getAppMenu, getCurrentWindowState, @@ -91,6 +92,8 @@ import { sendWillQuitEvenIfUpdatingSync, quitApp, sendCancelQuittingSync, + saveTitleBarStyle, + getTitleBarStyle, } from '../../ui/main-process-proxy' import { API, @@ -553,6 +556,7 @@ export class AppStore extends TypedBaseStore { private selectedTheme = ApplicationTheme.System private currentTheme: ApplicableTheme = ApplicationTheme.Light private selectedTabSize = tabSizeDefault + private titleBarStyle: TitleBarStyle = 'native' private useWindowsOpenSSH: boolean = false @@ -1055,6 +1059,7 @@ export class AppStore extends TypedBaseStore { selectedTheme: this.selectedTheme, currentTheme: this.currentTheme, selectedTabSize: this.selectedTabSize, + titleBarStyle: this.titleBarStyle, apiRepositories: this.apiRepositoriesStore.getState(), useWindowsOpenSSH: this.useWindowsOpenSSH, showCommitLengthWarning: this.showCommitLengthWarning, @@ -2260,6 +2265,8 @@ export class AppStore extends TypedBaseStore { this.emitUpdate() }) + this.titleBarStyle = await getTitleBarStyle() + this.lastThankYou = getObject(lastThankYouKey) this.useCustomEditor = @@ -6705,6 +6712,14 @@ export class AppStore extends TypedBaseStore { return Promise.resolve() } + /* + * Set the title bar style for the application + */ + public _setTitleBarStyle(titleBarStyle: TitleBarStyle) { + this.titleBarStyle = titleBarStyle + return saveTitleBarStyle(titleBarStyle) + } + public async _resolveCurrentEditor() { const match = await findEditorOrDefault(this.selectedExternalEditor) const resolvedExternalEditor = match != null ? match.editor : null diff --git a/app/src/main-process/app-window.ts b/app/src/main-process/app-window.ts index fc682434125..647bbce6786 100644 --- a/app/src/main-process/app-window.ts +++ b/app/src/main-process/app-window.ts @@ -14,6 +14,7 @@ import { getWindowState, registerWindowStateChangedEvents, } from '../lib/window-state' +import { readTitleBarConfigFileSync } from '../lib/get-title-bar-config' import { MenuEvent } from './menu' import { URLActionType } from '../lib/parse-app-url' import { ILaunchStats } from '../lib/stats' @@ -77,6 +78,9 @@ export class AppWindow { } else if (__WIN32__) { windowOptions.frame = false } else if (__LINUX__) { + if (readTitleBarConfigFileSync().titleBarStyle === 'custom') { + windowOptions.frame = false + } windowOptions.icon = join(__dirname, 'static', 'logos', '512x512.png') // relax restriction here for users trying to run app at a small diff --git a/app/src/main-process/main.ts b/app/src/main-process/main.ts index 4897a2e4484..42092cbf1bb 100644 --- a/app/src/main-process/main.ts +++ b/app/src/main-process/main.ts @@ -44,6 +44,10 @@ import { } from '../lib/get-architecture' import { buildSpellCheckMenu } from './menu/build-spell-check-menu' import { getMainGUID, saveGUIDFile } from '../lib/get-main-guid' +import { + readTitleBarConfigFileSync, + saveTitleBarConfigFile, +} from '../lib/get-title-bar-config' import { getNotificationsPermission, requestNotificationsPermission, @@ -509,6 +513,11 @@ app.on('ready', () => { mainWindow?.quitAndInstallUpdate() ) + ipcMain.on('restart-app', () => { + app.relaunch() + app.exit() + }) + ipcMain.on('quit-app', () => app.quit()) ipcMain.on('minimize-window', () => mainWindow?.minimizeWindow()) @@ -697,6 +706,16 @@ app.on('ready', () => { ipcMain.handle('save-guid', (_, guid) => saveGUIDFile(guid)) + ipcMain.handle( + 'get-title-bar-style', + async () => readTitleBarConfigFileSync().titleBarStyle + ) + + ipcMain.handle( + 'save-title-bar-style', + async (_, titleBarStyle) => await saveTitleBarConfigFile({ titleBarStyle }) + ) + ipcMain.handle('show-notification', async (_, title, body, userInfo) => showNotification(title, body, userInfo) ) diff --git a/app/src/models/popup.ts b/app/src/models/popup.ts index 9191b3a94e8..ebd7711aa2c 100644 --- a/app/src/models/popup.ts +++ b/app/src/models/popup.ts @@ -95,6 +95,7 @@ export enum PopupType { PullRequestComment = 'PullRequestComment', UnknownAuthors = 'UnknownAuthors', TestIcons = 'TestIcons', + ConfirmRestart = 'ConfirmRestart', } interface IBasePopup { @@ -423,5 +424,6 @@ export type PopupDetail = | { type: PopupType.TestIcons } + | { type: PopupType.ConfirmRestart } export type Popup = IBasePopup & PopupDetail diff --git a/app/src/ui/app.tsx b/app/src/ui/app.tsx index 36a4553ebb7..46e086b7f19 100644 --- a/app/src/ui/app.tsx +++ b/app/src/ui/app.tsx @@ -71,6 +71,7 @@ import { Welcome } from './welcome' import { AppMenuBar } from './app-menu' import { UpdateAvailable, renderBanner } from './banners' import { Preferences } from './preferences' +import { ConfirmRestart } from './preferences/confirm-restart' import { RepositorySettings } from './repository-settings' import { AppError } from './app-error' import { MissingRepository } from './missing-repository' @@ -1497,8 +1498,8 @@ export class App extends React.Component { * on Windows. */ private renderAppMenuBar() { - // We only render the app menu bar on Windows - if (!__WIN32__) { + // We do not render the app menu bar on macOS + if (__DARWIN__) { return null } @@ -1549,9 +1550,9 @@ export class App extends React.Component { this.state.currentFoldout && this.state.currentFoldout.type === FoldoutType.AppMenu - // As Linux still uses the classic Electron menu, we are opting out of the - // custom menu that is shown as part of the title bar below - if (__LINUX__) { + // We do not render the app menu bar on Linux when the user has selected + // the "native" menu option + if (__LINUX__ && this.state.titleBarStyle === 'native') { return null } @@ -1559,12 +1560,12 @@ export class App extends React.Component { // the title bar when the menu bar is active. On other platforms we // never render the title bar while in full-screen mode. if (inFullScreen) { - if (!__WIN32__ || !menuBarActive) { + if (__DARWIN__ || !menuBarActive) { return null } } - const showAppIcon = __WIN32__ && !this.state.showWelcomeFlow + const showAppIcon = !__DARWIN__ && !this.state.showWelcomeFlow const inWelcomeFlow = this.state.showWelcomeFlow const inNoRepositoriesView = this.inNoRepositoriesViewState() @@ -1757,6 +1758,7 @@ export class App extends React.Component { customEditor={this.state.customEditor} useCustomShell={this.state.useCustomShell} customShell={this.state.customShell} + titleBarStyle={this.state.titleBarStyle} repositoryIndicatorsEnabled={this.state.repositoryIndicatorsEnabled} onOpenFileInExternalEditor={this.openFileInExternalEditor} underlineLinks={this.state.underlineLinks} @@ -2664,6 +2666,9 @@ export class App extends React.Component { /> ) } + case PopupType.ConfirmRestart: { + return + } default: return assertNever(popup, `Unknown popup type: ${popup}`) } diff --git a/app/src/ui/dispatcher/dispatcher.ts b/app/src/ui/dispatcher/dispatcher.ts index 0db2666c36a..db05015a87c 100644 --- a/app/src/ui/dispatcher/dispatcher.ts +++ b/app/src/ui/dispatcher/dispatcher.ts @@ -87,6 +87,7 @@ import { TipState, IValidBranch } from '../../models/tip' import { Banner, BannerType } from '../../models/banner' import { ApplicationTheme } from '../lib/application-theme' +import { TitleBarStyle } from '../lib/title-bar-style' import { installCLI } from '../lib/install-cli' import { executeMenuItem, @@ -2452,6 +2453,19 @@ export class Dispatcher { public setSelectedTabSize(tabSize: number) { return this.appStore._setSelectedTabSize(tabSize) } + /* + * Set the title bar style for the application + */ + public async setTitleBarStyle(titleBarStyle: TitleBarStyle) { + const existingState = this.appStore.getState() + const { titleBarStyle: existingTitleBarStyle } = existingState + + await this.appStore._setTitleBarStyle(titleBarStyle) + + if (titleBarStyle !== existingTitleBarStyle) { + this.showPopup({ type: PopupType.ConfirmRestart }) + } + } /** * Increments either the `repoWithIndicatorClicked` or diff --git a/app/src/ui/lib/title-bar-style.ts b/app/src/ui/lib/title-bar-style.ts new file mode 100644 index 00000000000..452842d7794 --- /dev/null +++ b/app/src/ui/lib/title-bar-style.ts @@ -0,0 +1,17 @@ +/** + * This string enum represents the supported modes for rendering the title bar + * in the app. + * + * - 'native' - Use the default window style and chrome supported by the window + * manager + * + * - 'custom' - Hide the default window style and chrome and display the menu + * provided by GitHub Desktop + * + * This is only available on the Linux build. For other operating systems this + * is not configurable: + * + * - macOS uses the native title bar + * - Windows uses the custom title bar + */ +export type TitleBarStyle = 'native' | 'custom' diff --git a/app/src/ui/main-process-proxy.ts b/app/src/ui/main-process-proxy.ts index 8a6cfdf09a1..e9b19d21781 100644 --- a/app/src/ui/main-process-proxy.ts +++ b/app/src/ui/main-process-proxy.ts @@ -167,6 +167,9 @@ export const checkForUpdates = invokeProxy('check-for-updates', 1) /** Tell the main process to quit the app and install updates */ export const quitAndInstallUpdate = sendProxy('quit-and-install-updates', 0) +/** Tell the main process to restart the app */ +export const restartApp = sendProxy('restart-app', 0) + /** Tell the main process to quit the app */ export const quitApp = sendProxy('quit-app', 0) @@ -382,6 +385,10 @@ export const showOpenDialog = invokeProxy('show-open-dialog', 1) export const saveGUID = invokeProxy('save-guid', 1) export const getGUID = invokeProxy('get-guid', 0) +/** Tell the main process read/save the the title bar style */ +export const saveTitleBarStyle = invokeProxy('save-title-bar-style', 1) +export const getTitleBarStyle = invokeProxy('get-title-bar-style', 0) + /** Tell the main process to show a notification */ export const showNotification = invokeProxy('show-notification', 3) diff --git a/app/src/ui/preferences/appearance.tsx b/app/src/ui/preferences/appearance.tsx index 9bbab2de6b7..5d1eb64f313 100644 --- a/app/src/ui/preferences/appearance.tsx +++ b/app/src/ui/preferences/appearance.tsx @@ -4,6 +4,7 @@ import { supportsSystemThemeChanges, getCurrentlyAppliedTheme, } from '../lib/application-theme' +import { TitleBarStyle } from '../lib/title-bar-style' import { Row } from '../lib/row' import { DialogContent } from '../dialog' import { RadioGroup } from '../lib/radio-group' @@ -16,11 +17,23 @@ interface IAppearanceProps { readonly onSelectedThemeChanged: (theme: ApplicationTheme) => void readonly selectedTabSize: number readonly onSelectedTabSizeChanged: (tabSize: number) => void + readonly titleBarStyle: TitleBarStyle + readonly onTitleBarStyleChanged: (titleBarStyle: TitleBarStyle) => void } interface IAppearanceState { readonly selectedTheme: ApplicationTheme | null readonly selectedTabSize: number + readonly titleBarStyle: TitleBarStyle +} + +function getTitleBarStyleDescription(titleBarStyle: TitleBarStyle): string { + switch (titleBarStyle) { + case 'custom': + return 'Uses the menu system provided by GitHub Desktop, hiding the default chrome provided by your window manager.' + case 'native': + return 'Uses the menu system and chrome provided by your window manager.' + } } export class Appearance extends React.Component< @@ -37,6 +50,7 @@ export class Appearance extends React.Component< this.state = { selectedTheme: usePropTheme ? props.selectedTheme : null, selectedTabSize: props.selectedTabSize, + titleBarStyle: props.titleBarStyle, } if (!usePropTheme) { @@ -78,6 +92,12 @@ export class Appearance extends React.Component< this.props.onSelectedTabSizeChanged(parseInt(event.currentTarget.value)) } + private onSelectChanged = (event: React.FormEvent) => { + const titleBarStyle = event.currentTarget.value as TitleBarStyle + this.setState({ titleBarStyle }) + this.props.onTitleBarStyleChanged(titleBarStyle) + } + public renderThemeSwatch = (theme: ApplicationTheme) => { const darkThemeImage = encodePathAsUrl(__dirname, 'static/ghd_dark.svg') const lightThemeImage = encodePathAsUrl(__dirname, 'static/ghd_light.svg') @@ -115,8 +135,31 @@ export class Appearance extends React.Component< } } + private renderTitleBarStyleDropdown() { + const { titleBarStyle } = this.state + const titleBarStyleDescription = getTitleBarStyleDescription(titleBarStyle) + + return ( +

+ ) + } + private renderSelectedTheme() { - const selectedTheme = this.state.selectedTheme + const { selectedTheme } = this.state if (selectedTheme == null) { return Loading system theme @@ -131,15 +174,16 @@ export class Appearance extends React.Component< return (

Theme

- - - ariaLabelledBy="theme-heading" - className="theme-selector" - selectedKey={selectedTheme} - radioButtonKeys={themes} - onSelectionChanged={this.onSelectedThemeChanged} - renderRadioButtonLabelContents={this.renderThemeSwatch} - /> + + + ariaLabelledBy="theme-heading" + className="theme-selector" + selectedKey={selectedTheme} + radioButtonKeys={themes} + onSelectionChanged={this.onSelectedThemeChanged} + renderRadioButtonLabelContents={this.renderThemeSwatch} + /> +
) } @@ -171,6 +215,7 @@ export class Appearance extends React.Component< {this.renderSelectedTheme()} {this.renderSelectedTabSize()} + {this.renderTitleBarStyleDropdown()} ) } diff --git a/app/src/ui/preferences/confirm-restart.tsx b/app/src/ui/preferences/confirm-restart.tsx new file mode 100644 index 00000000000..537ee0a320b --- /dev/null +++ b/app/src/ui/preferences/confirm-restart.tsx @@ -0,0 +1,58 @@ +import * as React from 'react' +import { + Dialog, + DialogContent, + DialogFooter, + OkCancelButtonGroup, +} from '../dialog' +import { restartApp } from '../main-process-proxy' + +interface IConfirmRestartProps { + /** + * Callback to use when the dialog gets closed. + */ + readonly onDismissed: () => void +} + +export class ConfirmRestart extends React.Component { + public constructor(props: IConfirmRestartProps) { + super(props) + } + + public render() { + return ( + + +

Restart GitHub Desktop to apply the title bar settings change?

+
+ {this.renderFooter()} +
+ ) + } + + private renderFooter() { + return ( + + + + ) + } + + private onNotNow = () => { + this.props.onDismissed() + } + + private onSubmit = async () => { + this.props.onDismissed() + restartApp() + } +} diff --git a/app/src/ui/preferences/preferences.tsx b/app/src/ui/preferences/preferences.tsx index d449d7312f0..6cd572748b5 100644 --- a/app/src/ui/preferences/preferences.tsx +++ b/app/src/ui/preferences/preferences.tsx @@ -22,6 +22,7 @@ import { } from '../lib/identifier-rules' import { Appearance } from './appearance' import { ApplicationTheme } from '../lib/application-theme' +import { TitleBarStyle } from '../lib/title-bar-style' import { OkCancelButtonGroup } from '../dialog/ok-cancel-button-group' import { Integrations } from './integrations' import { @@ -77,6 +78,7 @@ interface IPreferencesProps { readonly customEditor: ICustomIntegration | null readonly useCustomShell: boolean readonly customShell: ICustomIntegration | null + readonly titleBarStyle: TitleBarStyle readonly repositoryIndicatorsEnabled: boolean readonly onOpenFileInExternalEditor: (path: string) => void readonly underlineLinks: boolean @@ -113,7 +115,7 @@ interface IPreferencesState { readonly selectedExternalEditor: string | null readonly availableShells: ReadonlyArray readonly selectedShell: Shell - + readonly titleBarStyle: TitleBarStyle /** * If unable to save Git configuration values (name, email) * due to an existing configuration lock file this property @@ -183,6 +185,7 @@ export class Preferences extends React.Component< selectedExternalEditor: this.props.selectedExternalEditor, availableShells: [], selectedShell: this.props.selectedShell, + titleBarStyle: this.props.titleBarStyle, repositoryIndicatorsEnabled: this.props.repositoryIndicatorsEnabled, initiallySelectedTheme: this.props.selectedTheme, initiallySelectedTabSize: this.props.selectedTabSize, @@ -461,6 +464,8 @@ export class Preferences extends React.Component< onSelectedThemeChanged={this.onSelectedThemeChanged} selectedTabSize={this.props.selectedTabSize} onSelectedTabSizeChanged={this.onSelectedTabSizeChanged} + titleBarStyle={this.props.titleBarStyle} + onTitleBarStyleChanged={this.onTitleBarStyleChanged} /> ) break @@ -678,6 +683,10 @@ export class Preferences extends React.Component< this.props.dispatcher.setSelectedTabSize(tabSize) } + private onTitleBarStyleChanged = (titleBarStyle: TitleBarStyle) => { + this.setState({ titleBarStyle }) + } + private renderFooter() { const hasDisabledError = this.state.disallowedCharactersMessage != null @@ -802,7 +811,9 @@ export class Preferences extends React.Component< if (this.state.selectedExternalEditor) { await dispatcher.setExternalEditor(this.state.selectedExternalEditor) } + await dispatcher.setShell(this.state.selectedShell) + await dispatcher.setTitleBarStyle(this.state.titleBarStyle) await dispatcher.setConfirmDiscardChangesSetting( this.state.confirmDiscardChanges ) diff --git a/app/src/ui/window/title-bar.tsx b/app/src/ui/window/title-bar.tsx index b6fe9b7c041..4de3108240f 100644 --- a/app/src/ui/window/title-bar.tsx +++ b/app/src/ui/window/title-bar.tsx @@ -84,7 +84,7 @@ export class TitleBar extends React.Component { const isMaximized = this.props.windowState === 'maximized' // No Windows controls when we're in full-screen mode. - const winControls = __WIN32__ && !inFullScreen ? : null + const winControls = !inFullScreen ? : null // On Windows it's not possible to resize a frameless window if the // element that sits flush along the window edge has -webkit-app-region: drag. @@ -92,12 +92,14 @@ export class TitleBar extends React.Component { // window controls need to disable dragging so we add a 3px tall element which // disables drag while still letting users drag the app by the titlebar below // those 3px. - const topResizeHandle = - __WIN32__ && !isMaximized ?
: null + const topResizeHandle = !isMaximized ? ( +
+ ) : null // And a 3px wide element on the left hand side. - const leftResizeHandle = - __WIN32__ && !isMaximized ?
: null + const leftResizeHandle = !isMaximized ? ( +
+ ) : null const titleBarClass = this.props.titleBarStyle === 'light' ? 'light-title-bar' : '' diff --git a/app/src/ui/window/window-controls.tsx b/app/src/ui/window/window-controls.tsx index a98aef33062..558d33f47dc 100644 --- a/app/src/ui/window/window-controls.tsx +++ b/app/src/ui/window/window-controls.tsx @@ -114,11 +114,6 @@ export class WindowControls extends React.Component<{}, IWindowControlState> { } public render() { - // We only know how to render fake Windows-y controls - if (!__WIN32__) { - return - } - const min = this.renderButton('minimize', this.onMinimize, minimizePath) const maximizeOrRestore = this.state.windowState === 'maximized' diff --git a/app/styles/ui/window/_title-bar.scss b/app/styles/ui/window/_title-bar.scss index 2662b3bb513..6dae12eab55 100644 --- a/app/styles/ui/window/_title-bar.scss +++ b/app/styles/ui/window/_title-bar.scss @@ -15,7 +15,7 @@ border-bottom: 1px solid #000; } - @include win32 { + @mixin custom-title-bar { height: var(--win32-title-bar-height); background: var(--win32-title-bar-background-color); border-bottom: 1px solid #000; @@ -27,6 +27,14 @@ } } + @include win32 { + @include custom-title-bar; + } + + @include linux { + @include custom-title-bar; + } + .resize-handle { position: absolute; top: 0px; From 7e7cf2286e5117e2d01a1f749c4fd44809d29924 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 2 Jun 2024 15:14:42 -0300 Subject: [PATCH 34/41] feat(tooling): scaffold workflows to handle automated rebasing of changes to make release automation boring (#1074 #1075) --- .github/workflows/create-draft-release.yml | 74 ++++++++++++++++++++++ .github/workflows/sync-with-upstream.yml | 43 +++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 .github/workflows/create-draft-release.yml create mode 100644 .github/workflows/sync-with-upstream.yml diff --git a/.github/workflows/create-draft-release.yml b/.github/workflows/create-draft-release.yml new file mode 100644 index 00000000000..b574ec45149 --- /dev/null +++ b/.github/workflows/create-draft-release.yml @@ -0,0 +1,74 @@ +name: 'Create draft release from upstream' + +on: + workflow_dispatch: + inputs: + release: + description: 'Upstream release' + required: true + type: string + publish: + description: 'Whether to publish the release to GitHub on success' + type: boolean + required: false + default: false + +jobs: + publish-draft-release: + runs-on: ubuntu-latest + name: Publish draft release + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + token: ${{ secrets.CREATE_RELEASE_AUTOMATION_TOKEN }} + - name: Configure git + run: | + git config --global user.name "shiftbot" + git config --global user.email "github@brendanforster.com" + git config --local core.autocrlf "input" + git remote add upstream https://github.com/desktop/desktop.git + shell: bash + - name: Create baseline branch on fork + id: create-baseline-branch + env: + RELEASE_TAG: ${{ inputs.release }} + BASE_BRANCH: 'linux-${{ inputs.release }}' + run: | + git fetch upstream 'refs/tags/*:refs/tags/*' + git fetch origin --unshallow + git checkout -b $BASE_BRANCH $RELEASE_TAG + git push origin $BASE_BRANCH + git config -l --show-origin + shell: bash + - name: Rebase Linux customizations on top of upstream release branch + id: rebase-linux-branch + env: + HEAD_BRANCH: 'apply-changes-${{ inputs.release }}' + BASE_BRANCH: 'linux-${{ inputs.release }}' + UPSTREAM_BRANCH: 'development' + run: | + + git fetch origin linux + git fetch origin $UPSTREAM_BRANCH + git checkout -b $HEAD_BRANCH linux + git push origin $HEAD_BRANCH + git submodule update + echo "One last git config output..." + git config -l --show-origin + echo "Commit identifiers before performing rebase..." + echo "BASE_BRANCH: $(git rev-parse $BASE_BRANCH)" + echo "development: $(git rev-parse origin/$UPSTREAM_BRANCH)" + echo "HEAD_BRANCH: $(git rev-parse $HEAD_BRANCH)" + echo "About to run 'git log --oneline --decorate=full --graph $HEAD_BRANCH...origin/$UPSTREAM_BRANCH'..." + git log --oneline --decorate=full --graph $HEAD_BRANCH...origin/$UPSTREAM_BRANCH + echo "About to run 'git rebase --verbose origin/$UPSTREAM_BRANCH $HEAD_BRANCH --onto $BASE_BRANCH'..." + git rebase --verbose origin/$UPSTREAM_BRANCH $HEAD_BRANCH --onto $BASE_BRANCH + git push origin $HEAD_BRANCH + shell: bash + continue-on-error: true + - name: Review current status + id: status + run: | + git status + shell: bash diff --git a/.github/workflows/sync-with-upstream.yml b/.github/workflows/sync-with-upstream.yml new file mode 100644 index 00000000000..7eb1ec30c7d --- /dev/null +++ b/.github/workflows/sync-with-upstream.yml @@ -0,0 +1,43 @@ +name: 'Sync main branch with upstream' + +on: workflow_dispatch + +jobs: + sync-with-upstream: + runs-on: ubuntu-latest + name: Sync main branch with upstream + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + token: ${{ secrets.CREATE_RELEASE_AUTOMATION_TOKEN }} + - name: Configure git + run: | + git config --global user.name "shiftbot" + git config --global user.email "github@brendanforster.com" + git remote add upstream https://github.com/desktop/desktop.git + shell: bash + - name: Push development changes from upstream to fork + id: sync-development-branch + run: | + git fetch upstream development + git fetch origin --unshallow + git fetch origin development + git checkout -b development upstream/development + git push origin development + shell: bash + - name: Rebase Linux customizations on top of development branch + id: rebase-linux-branch + run: | + git fetch origin linux + git checkout linux + git log linux...development --oneline + git rebase --verbose development linux + shell: bash + continue-on-error: true + - name: Review current status + id: status + run: | + git status + shell: bash + # TODO: force push this when we're confident that the rebase has succeeded? From 2ac499d3feff69ffd8696b73a423d1808d451a96 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 11 Aug 2024 20:59:33 -0300 Subject: [PATCH 35/41] feat(tooling): add support for building and packaging app on Linux --- .github/workflows/ci-linux.yml | 150 +++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 .github/workflows/ci-linux.yml diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml new file mode 100644 index 00000000000..424476e1b37 --- /dev/null +++ b/.github/workflows/ci-linux.yml @@ -0,0 +1,150 @@ +name: 'CI / Linux' + +on: + push: + branches: + - development + - linux + - 'linux-release-*' + tags: + - 'release-*.*.*-linux*' + - 'release-*.*.*-test*' + pull_request: + branches: + - linux + - linux-vnext + - 'linux-release-*' + +jobs: + arm64: + name: Ubuntu arm64 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + repository: ${{ inputs.repository || github.repository }} + ref: ${{ inputs.ref }} + submodules: recursive + - name: Package and test application in container + uses: shiftkey/desktop-ubuntu-arm64-packaging@d5a0346959c7d553eb8dbe2828e7fe2e10147160 + - name: Upload output artifacts + uses: actions/upload-artifact@v4 + with: + name: ubuntu-arm64-artifacts + path: | + dist/*.AppImage + dist/*.deb + dist/*.rpm + dist/*.sha256 + retention-days: 5 + if-no-files-found: error + arm: + name: Ubuntu arm + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + repository: ${{ inputs.repository || github.repository }} + ref: ${{ inputs.ref }} + submodules: recursive + - name: Package and test application in container + uses: shiftkey/desktop-ubuntu-arm-packaging@48215eee48762e1c919309b2915b8ceb478e5642 + - name: Upload output artifacts + uses: actions/upload-artifact@v4 + with: + name: ubuntu-arm-artifacts + path: | + dist/*.AppImage + dist/*.deb + dist/*.rpm + dist/*.sha256 + retention-days: 5 + if-no-files-found: error + amd64: + name: Ubuntu x64 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + repository: ${{ inputs.repository || github.repository }} + ref: ${{ inputs.ref }} + submodules: recursive + - name: Package and test application in container + uses: shiftkey/desktop-ubuntu-amd64-packaging@33a71a92b43e54694726382d1e4029a91fe894cc + - name: Upload output artifacts + uses: actions/upload-artifact@v4 + with: + name: ubuntu-amd64-artifacts + path: | + dist/*.AppImage + dist/*.deb + dist/*.rpm + dist/*.sha256 + retention-days: 5 + if-no-files-found: error + + publish: + name: Create GitHub release + needs: [arm64, arm, amd64] + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + + - name: Use Node.js 18.14.0 + uses: actions/setup-node@v4 + with: + node-version: 18.14.0 + cache: yarn + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: './artifacts' + + - name: Display structure of downloaded files + run: ls -R + working-directory: './artifacts' + + - name: Get tag name without prefix + run: | + RELEASE_TAG=${GITHUB_REF/refs\/tags\//} + echo "RELEASE_TAG=${RELEASE_TAG}" >> $GITHUB_ENV + tagNameWithoutPrefix="${RELEASE_TAG:8}" + echo "RELEASE_TAG_WITHOUT_PREFIX=${tagNameWithoutPrefix}" >> $GITHUB_ENV + + # TODO: generate release notes + # - pull in default if version matches X.Y.Z-linux1 + # - otherwise stub template + + - name: Generate release notes + run: | + node -v + yarn + node -r ts-node/register script/generate-release-notes.ts "${{ github.workspace }}/artifacts" "${{ env.RELEASE_TAG_WITHOUT_PREFIX }}" + RELEASE_NOTES_FILE=script/release_notes.txt + if [[ ! -f "$RELEASE_NOTES_FILE" ]]; then + echo "$RELEASE_NOTES_FILE does not exist. Something might have gone wrong while generating the release notes." + exit 1 + fi + echo "Release notes:" + echo "---" + cat ${RELEASE_NOTES_FILE} + echo "---" + + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + name: GitHub Desktop for Linux ${{ env.RELEASE_TAG_WITHOUT_PREFIX }} + body_path: script/release_notes.txt + files: | + artifacts/**/*.AppImage + artifacts/**/*.deb + artifacts/**/*.rpm + artifacts/**/*.sha256 + draft: true + fail_on_unmatched_files: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 5f15cfec94f7fa737c4f1ace39b3c47a253eabb2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 10:07:35 -0300 Subject: [PATCH 36/41] Bump electron-packager from 17.1.1 to 17.1.2 (#916) Bumps [electron-packager](https://github.com/electron/electron-packager) from 17.1.1 to 17.1.2. - [Release notes](https://github.com/electron/electron-packager/releases) - [Changelog](https://github.com/electron/electron-packager/blob/main/NEWS.md) - [Commits](https://github.com/electron/electron-packager/compare/v17.1.1...v17.1.2) --- updated-dependencies: - dependency-name: electron-packager dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 127 ++++++++++++++------------------------------------- 2 files changed, 35 insertions(+), 94 deletions(-) diff --git a/package.json b/package.json index d517077e133..1953898929a 100644 --- a/package.json +++ b/package.json @@ -158,7 +158,7 @@ "@types/xml2js": "^0.4.11", "electron": "32.1.2", "electron-builder": "^24.13.3", - "electron-packager": "^17.1.1", + "electron-packager": "^17.1.2", "eslint-plugin-github": "^4.10.1", "markdownlint-cli": "^0.32.2", "patch-package": "^8.0.0", diff --git a/yarn.lock b/yarn.lock index 1a51a298d55..fbd0c0619a8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -602,7 +602,7 @@ debug "^4.1.1" fs-extra "^9.0.1" -"@electron/osx-sign@1.0.5": +"@electron/osx-sign@1.0.5", "@electron/osx-sign@^1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@electron/osx-sign/-/osx-sign-1.0.5.tgz#0af7149f2fce44d1a8215660fd25a9fb610454d8" integrity sha512-k9ZzUQtamSoweGQDV2jILiRIHUu7lYlJ3c6IEmjv1hC17rclE+eb9U+f6UFlOOETo0JzY1HNlXy4YOlCvl+Lww== @@ -614,18 +614,6 @@ minimist "^1.2.6" plist "^3.0.5" -"@electron/osx-sign@^1.0.1": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@electron/osx-sign/-/osx-sign-1.0.4.tgz#8e91442846471636ca0469426a82b253b9170151" - integrity sha512-xfhdEcIOfAZg7scZ9RQPya1G1lWo8/zMCwUXAulq0SfY7ONIW+b9qGyKdMyuMctNYwllrIS+vmxfijSfjeh97g== - dependencies: - compare-version "^0.1.2" - debug "^4.3.4" - fs-extra "^10.0.0" - isbinaryfile "^4.0.8" - minimist "^1.2.6" - plist "^3.0.5" - "@electron/universal@1.5.1": version "1.5.1" resolved "https://registry.yarnpkg.com/@electron/universal/-/universal-1.5.1.tgz#f338bc5bcefef88573cf0ab1d5920fac10d06ee5" @@ -3295,7 +3283,7 @@ debounce@^1.2.1: resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== -debug@4, debug@^4.3.1, debug@^4.3.4: +debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -3309,34 +3297,13 @@ debug@^2.2.0, debug@^2.6.9: dependencies: ms "2.0.0" -debug@^3.1.0, debug@^3.2.7: +debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" -debug@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" - integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== - dependencies: - ms "^2.1.1" - -debug@^4.1.0, debug@^4.1.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== - dependencies: - ms "2.1.2" - -debug@^4.3.2: - version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== - dependencies: - ms "2.1.2" - debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -3693,22 +3660,22 @@ electron-installer-redhat@3.4.0: word-wrap "^1.2.3" yargs "^16.0.2" -electron-packager@^17.1.1: - version "17.1.1" - resolved "https://registry.yarnpkg.com/electron-packager/-/electron-packager-17.1.1.tgz#f156fc63d3a66f4e902e4b42992550a172982d59" - integrity sha512-r1NDtlajsq7gf2EXgjRfblCVPquvD2yeg+6XGErOKblvxOpDi0iulZLVhgYDP4AEF1P5/HgbX/vwjlkEv7PEIQ== +electron-packager@^17.1.2: + version "17.1.2" + resolved "https://registry.yarnpkg.com/electron-packager/-/electron-packager-17.1.2.tgz#18030b28024d242b706d0a8a67ed4cd1a57311aa" + integrity sha512-XofXdikjYI7MVBcnXeoOvRR+yFFFHOLs3J7PF5KYQweigtgLshcH4W660PsvHr4lYZ03JBpLyEcUB8DzHZ+BNw== dependencies: "@electron/asar" "^3.2.1" "@electron/get" "^2.0.0" "@electron/notarize" "^1.2.3" - "@electron/osx-sign" "^1.0.1" + "@electron/osx-sign" "^1.0.5" "@electron/universal" "^1.3.2" cross-spawn-windows-exe "^1.2.0" debug "^4.0.1" extract-zip "^2.0.0" filenamify "^4.1.0" - fs-extra "^10.1.0" - galactus "^0.2.1" + fs-extra "^11.1.0" + galactus "^1.0.0" get-package-info "^1.0.0" junk "^3.1.0" parse-author "^2.0.0" @@ -4577,7 +4544,7 @@ filenamify@^4.1.0: strip-outer "^1.0.1" trim-repeated "^1.0.0" -fill-range@^7.0.1: +fill-range@^7.0.1, fill-range@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== @@ -4633,13 +4600,13 @@ flatted@^3.2.9: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== -flora-colossus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/flora-colossus/-/flora-colossus-1.0.0.tgz#54729c361edecee014dd441679e1a37c1d773a45" - integrity sha1-VHKcNh7ezuAU3UQWeeGjfB13OkU= +flora-colossus@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/flora-colossus/-/flora-colossus-2.0.0.tgz#af1e85db0a8256ef05f3fb531c1235236c97220a" + integrity sha512-dz4HxH6pOvbUzZpZ/yXhafjbR2I8cenK5xL0KtBFb7U2ADsR+OwXifnxZjij/pZWF775uSCMzWVd+jDik2H2IA== dependencies: - debug "^3.1.0" - fs-extra "^4.0.0" + debug "^4.3.4" + fs-extra "^10.1.0" for-each@^0.3.3: version "0.3.3" @@ -4681,14 +4648,14 @@ fs-extra@^10.0.0, fs-extra@^10.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" - integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== +fs-extra@^11.1.0: + version "11.1.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" + integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" fs-extra@^7.0.1: version "7.0.1" @@ -4789,14 +4756,14 @@ functions-have-names@^1.2.2, functions-have-names@^1.2.3: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== -galactus@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/galactus/-/galactus-0.2.1.tgz#cbed2d20a40c1f5679a35908e2b9415733e78db9" - integrity sha1-y+0tIKQMH1Z5o1kI4rlBVzPnjbk= +galactus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/galactus/-/galactus-1.0.0.tgz#c2615182afa0c6d0859b92e56ae36d052827db7e" + integrity sha512-R1fam6D4CyKQGNlvJne4dkNF+PvUUl7TAJInvTGa9fti9qAv95quQz29GXapA4d8Ec266mJJxFVh82M4GIIGDQ== dependencies: - debug "^3.1.0" - flora-colossus "^1.0.0" - fs-extra "^4.0.0" + debug "^4.3.4" + flora-colossus "^2.0.0" + fs-extra "^10.1.0" gar@^1.0.4: version "1.0.4" @@ -7366,7 +7333,7 @@ path-key@^4.0.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== -path-parse@^1.0.5, path-parse@^1.0.7: +path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== @@ -7835,14 +7802,7 @@ resolve.exports@^2.0.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== -resolve@^1.1.6: - version "1.5.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" - integrity sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw== - dependencies: - path-parse "^1.0.5" - -resolve@^1.20.0, resolve@^1.22.0: +resolve@^1.1.6, resolve@^1.20.0, resolve@^1.22.0: version "1.22.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== @@ -8043,26 +8003,7 @@ semver@^6.0.0, semver@^6.2.0, semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.1.1: - version "7.1.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.1.3.tgz#e4345ce73071c53f336445cfc19efb1c311df2a6" - integrity sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA== - -semver@^7.1.3, semver@^7.3.2: - version "7.5.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.0.tgz#ed8c5dc8efb6c629c88b23d41dc9bf40c1d96cd0" - integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== - dependencies: - lru-cache "^6.0.0" - -semver@^7.3.4: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - -semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: +semver@^7.1.1, semver@^7.1.3, semver@^7.3.2, semver@^7.3.4, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== From 2ae7081263af542b5b6defcc6073cfa6fb94d704 Mon Sep 17 00:00:00 2001 From: Adil Hanney Date: Sun, 15 Sep 2024 23:53:23 +0100 Subject: [PATCH 37/41] shells: add Black Box terminal (#1126) --- app/src/lib/shells/linux.ts | 10 ++++++++++ docs/technical/shell-integration.md | 2 ++ 2 files changed, 12 insertions(+) diff --git a/app/src/lib/shells/linux.ts b/app/src/lib/shells/linux.ts index 5800dd1f2f5..af5953e332b 100644 --- a/app/src/lib/shells/linux.ts +++ b/app/src/lib/shells/linux.ts @@ -27,6 +27,7 @@ export enum Shell { Kitty = 'Kitty', LXTerminal = 'LXDE Terminal', Warp = 'Warp', + BlackBox = 'Black Box', } export const Default = Shell.Gnome @@ -73,6 +74,8 @@ function getShellPath(shell: Shell): Promise { return getPathIfAvailable('/usr/bin/lxterminal') case Shell.Warp: return getPathIfAvailable('/usr/bin/warp-terminal') + case Shell.BlackBox: + return getPathIfAvailable('/usr/bin/blackbox-terminal') default: return assertNever(shell, `Unknown shell: ${shell}`) } @@ -98,6 +101,7 @@ export async function getAvailableShells(): Promise< kittyPath, lxterminalPath, warpPath, + blackBoxPath, ] = await Promise.all([ getShellPath(Shell.Gnome), getShellPath(Shell.GnomeConsole), @@ -115,6 +119,7 @@ export async function getAvailableShells(): Promise< getShellPath(Shell.Kitty), getShellPath(Shell.LXTerminal), getShellPath(Shell.Warp), + getShellPath(Shell.BlackBox), ]) const shells: Array> = [] @@ -182,6 +187,10 @@ export async function getAvailableShells(): Promise< shells.push({ shell: Shell.Warp, path: warpPath }) } + if (blackBoxPath) { + shells.push({ shell: Shell.BlackBox, path: blackBoxPath }) + } + return shells } @@ -198,6 +207,7 @@ export function launch( case Shell.Terminator: case Shell.XFCE: case Shell.Alacritty: + case Shell.BlackBox: return spawn(foundShell.path, ['--working-directory', path]) case Shell.Urxvt: return spawn(foundShell.path, ['-cd', path]) diff --git a/docs/technical/shell-integration.md b/docs/technical/shell-integration.md index 14c6c161600..a7d13b3a745 100644 --- a/docs/technical/shell-integration.md +++ b/docs/technical/shell-integration.md @@ -241,6 +241,7 @@ These shells are currently supported: - [Konsole](https://konsole.kde.org/) - [XTerm](http://invisible-island.net/xterm/) - [Terminology](https://www.enlightenment.org/docs/apps/terminology.md) + - [Black Box](https://gitlab.gnome.org/raggesilver/blackbox) These are defined in an enum at the top of the file: @@ -254,6 +255,7 @@ export enum Shell { Konsole = 'Konsole', Xterm = 'XTerm', Terminology = 'Terminology', + BlackBox = 'Black Box', } ``` From dee8f85ffb8919264e4883cb04f3f622a1c5dbc5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 19:53:32 -0300 Subject: [PATCH 38/41] build(deps): bump yaml from 2.5.0 to 2.6.0 (#1123 #1140) Bumps [yaml](https://github.com/eemeli/yaml) from 2.5.0 to 2.6.0. - [Release notes](https://github.com/eemeli/yaml/releases) - [Commits](https://github.com/eemeli/yaml/compare/v2.5.0...v2.6.0) --- updated-dependencies: - dependency-name: yaml dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 1953898929a..7d38a768352 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "webpack-merge": "^6.0.1", "xml2js": "^0.5.0", "xvfb-maybe": "^0.2.1", - "yaml": "^2.5.0" + "yaml": "^2.6.0" }, "devDependencies": { "@github/markdownlint-github": "^0.1.0", diff --git a/yarn.lock b/yarn.lock index fbd0c0619a8..d7b828f4780 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9351,15 +9351,10 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^2.2.2: - version "2.4.1" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.4.1.tgz#2e57e0b5e995292c25c75d2658f0664765210eed" - integrity sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg== - -yaml@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.0.tgz#c6165a721cf8000e91c36490a41d7be25176cf5d" - integrity sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw== +yaml@^2.2.2, yaml@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.6.0.tgz#14059ad9d0b1680d0f04d3a60fe00f3a857303c3" + integrity sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ== yargs-parser@^20.2.2: version "20.2.9" From 0c76a69109985a222ea231ab0b5296cbfe30e137 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 19:53:43 -0300 Subject: [PATCH 39/41] build(deps-dev): bump electron-builder from 24.13.3 to 25.1.8 (#1122 #1138 #1141) Bumps [electron-builder](https://github.com/electron-userland/electron-builder/tree/HEAD/packages/electron-builder) from 24.13.3 to 25.1.8. - [Release notes](https://github.com/electron-userland/electron-builder/releases) - [Changelog](https://github.com/electron-userland/electron-builder/blob/master/packages/electron-builder/CHANGELOG.md) - [Commits](https://github.com/electron-userland/electron-builder/commits/v25.1.8/packages/electron-builder) --- updated-dependencies: - dependency-name: electron-builder dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 849 +++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 725 insertions(+), 126 deletions(-) diff --git a/package.json b/package.json index 7d38a768352..062e342cc05 100644 --- a/package.json +++ b/package.json @@ -157,7 +157,7 @@ "@types/webpack-merge": "^5.0.0", "@types/xml2js": "^0.4.11", "electron": "32.1.2", - "electron-builder": "^24.13.3", + "electron-builder": "^25.1.8", "electron-packager": "^17.1.2", "eslint-plugin-github": "^4.10.1", "markdownlint-cli": "^0.32.2", diff --git a/yarn.lock b/yarn.lock index d7b828f4780..b48f1165815 100644 --- a/yarn.lock +++ b/yarn.lock @@ -570,6 +570,15 @@ glob "^7.1.6" minimatch "^3.0.4" +"@electron/asar@^3.2.7": + version "3.2.10" + resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.2.10.tgz#615cf346b734b23cafa4e0603551010bd0e50aa8" + integrity sha512-mvBSwIBUeiRscrCeJE1LwctAriBj65eUDm0Pc11iE5gRwzkmsdbS7FnZ1XUWjpSeQWL1L5g12Fc/SchPM9DUOw== + dependencies: + commander "^5.0.0" + glob "^7.1.6" + minimatch "^3.0.4" + "@electron/get@^2.0.0": version "2.0.2" resolved "https://registry.yarnpkg.com/@electron/get/-/get-2.0.2.tgz#ae2a967b22075e9c25aaf00d5941cd79c21efd7e" @@ -585,10 +594,10 @@ optionalDependencies: global-agent "^3.0.0" -"@electron/notarize@2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@electron/notarize/-/notarize-2.2.1.tgz#d0aa6bc43cba830c41bfd840b85dbe0e273f59fe" - integrity sha512-aL+bFMIkpR0cmmj5Zgy0LMKEpgy43/hw5zadEArgmAMWWlKc5buwFvFT9G/o/YJkvXAJm5q3iuTuLaiaXW39sg== +"@electron/notarize@2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@electron/notarize/-/notarize-2.5.0.tgz#d4d25356adfa29df4a76bd64a8bd347237cd251e" + integrity sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A== dependencies: debug "^4.1.1" fs-extra "^9.0.1" @@ -602,7 +611,19 @@ debug "^4.1.1" fs-extra "^9.0.1" -"@electron/osx-sign@1.0.5", "@electron/osx-sign@^1.0.5": +"@electron/osx-sign@1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@electron/osx-sign/-/osx-sign-1.3.1.tgz#faf7eeca7ca004a6be541dc4cf7a1bd59ec59b1c" + integrity sha512-BAfviURMHpmb1Yb50YbCxnOY0wfwaLXH5KJ4+80zS0gUkzDX3ec23naTlEqKsN+PwYn+a1cCzM7BJ4Wcd3sGzw== + dependencies: + compare-version "^0.1.2" + debug "^4.3.4" + fs-extra "^10.0.0" + isbinaryfile "^4.0.8" + minimist "^1.2.6" + plist "^3.0.5" + +"@electron/osx-sign@^1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@electron/osx-sign/-/osx-sign-1.0.5.tgz#0af7149f2fce44d1a8215660fd25a9fb610454d8" integrity sha512-k9ZzUQtamSoweGQDV2jILiRIHUu7lYlJ3c6IEmjv1hC17rclE+eb9U+f6UFlOOETo0JzY1HNlXy4YOlCvl+Lww== @@ -614,18 +635,38 @@ minimist "^1.2.6" plist "^3.0.5" -"@electron/universal@1.5.1": - version "1.5.1" - resolved "https://registry.yarnpkg.com/@electron/universal/-/universal-1.5.1.tgz#f338bc5bcefef88573cf0ab1d5920fac10d06ee5" - integrity sha512-kbgXxyEauPJiQQUNG2VgUeyfQNFk6hBF11ISN2PNI6agUgPl55pv4eQmaqHzTAzchBvqZ2tQuRVaPStGf0mxGw== +"@electron/rebuild@3.6.1": + version "3.6.1" + resolved "https://registry.yarnpkg.com/@electron/rebuild/-/rebuild-3.6.1.tgz#59e8e36c3f6e6b94a699425dfb61f0394c3dd4df" + integrity sha512-f6596ZHpEq/YskUd8emYvOUne89ij8mQgjYFA5ru25QwbrRO+t1SImofdDv7kKOuWCmVOuU5tvfkbgGxIl3E/w== dependencies: - "@electron/asar" "^3.2.1" - "@malept/cross-spawn-promise" "^1.1.0" + "@malept/cross-spawn-promise" "^2.0.0" + chalk "^4.0.0" + debug "^4.1.1" + detect-libc "^2.0.1" + fs-extra "^10.0.0" + got "^11.7.0" + node-abi "^3.45.0" + node-api-version "^0.2.0" + node-gyp "^9.0.0" + ora "^5.1.0" + read-binary-file-arch "^1.0.6" + semver "^7.3.5" + tar "^6.0.5" + yargs "^17.0.1" + +"@electron/universal@2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@electron/universal/-/universal-2.0.1.tgz#7b070ab355e02957388f3dbd68e2c3cd08c448ae" + integrity sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA== + dependencies: + "@electron/asar" "^3.2.7" + "@malept/cross-spawn-promise" "^2.0.0" debug "^4.3.1" - dir-compare "^3.0.0" - fs-extra "^9.0.1" - minimatch "^3.0.4" - plist "^3.0.4" + dir-compare "^4.2.0" + fs-extra "^11.1.1" + minimatch "^9.0.3" + plist "^3.1.0" "@electron/universal@^1.3.2": version "1.3.4" @@ -686,6 +727,11 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.55.0.tgz#b721d52060f369aa259cf97392403cb9ce892ec6" integrity sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA== +"@gar/promisify@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" + integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== + "@github/browserslist-config@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@github/browserslist-config/-/browserslist-config-1.0.0.tgz#952fe6da3e6b8ed6a368f3a1a08a9d2ef84e8d04" @@ -992,6 +1038,13 @@ dependencies: cross-spawn "^7.0.1" +"@malept/cross-spawn-promise@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz#d0772de1aa680a0bfb9ba2f32b4c828c7857cb9d" + integrity sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg== + dependencies: + cross-spawn "^7.0.1" + "@malept/flatpak-bundler@^0.4.0": version "0.4.0" resolved "https://registry.yarnpkg.com/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz#e8a32c30a95d20c2b1bb635cc580981a06389858" @@ -1023,6 +1076,22 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@npmcli/fs@^2.1.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-2.1.2.tgz#a9e2541a4a2fec2e69c29b35e6060973da79b865" + integrity sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ== + dependencies: + "@gar/promisify" "^1.1.3" + semver "^7.3.5" + +"@npmcli/move-file@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-2.0.1.tgz#26f6bdc379d87f75e55739bab89db525b06100e4" + integrity sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + "@pkgjs/parseargs@^0.11.0": version "0.11.0" resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" @@ -2065,6 +2134,11 @@ "@webassemblyjs/ast" "1.12.1" "@xtuc/long" "4.2.2" +"@xmldom/xmldom@^0.8.8": + version "0.8.10" + resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99" + integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw== + "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" @@ -2085,6 +2159,11 @@ abab@^2.0.6: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== +abbrev@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + acorn-globals@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-7.0.1.tgz#0dbf05c44fa7c94332914c02066d5beff62c40c3" @@ -2125,7 +2204,7 @@ acorn@^8.1.0, acorn@^8.8.1, acorn@^8.9.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== -agent-base@6: +agent-base@6, agent-base@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== @@ -2139,6 +2218,21 @@ agent-base@^7.0.2, agent-base@^7.1.0: dependencies: debug "^4.3.4" +agentkeepalive@^4.2.1: + version "4.5.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" + integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== + dependencies: + humanize-ms "^1.2.1" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + airbnb-browser-shims@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/airbnb-browser-shims/-/airbnb-browser-shims-3.0.0.tgz#7978e65fa106f7436a6ae2cad9ad871982e13c7d" @@ -2296,49 +2390,67 @@ anymatch@^3.0.3, anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" -app-builder-bin@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-4.0.0.tgz#1df8e654bd1395e4a319d82545c98667d7eed2f0" - integrity sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA== +app-builder-bin@5.0.0-alpha.10: + version "5.0.0-alpha.10" + resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-5.0.0-alpha.10.tgz#cf12e593b6b847fb9d04027fa755c6c6610d778b" + integrity sha512-Ev4jj3D7Bo+O0GPD2NMvJl+PGiBAfS7pUGawntBNpCbxtpncfUixqFj9z9Jme7V7s3LBGqsWZZP54fxBX3JKJw== -app-builder-lib@24.13.3: - version "24.13.3" - resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-24.13.3.tgz#36e47b65fecb8780bb73bff0fee4e0480c28274b" - integrity sha512-FAzX6IBit2POXYGnTCT8YHFO/lr5AapAII6zzhQO3Rw4cEDOgK+t1xhLc5tNcKlicTHlo9zxIwnYCX9X2DLkig== +app-builder-lib@25.1.8: + version "25.1.8" + resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-25.1.8.tgz#ae376039c5f269c7d562af494a087e5bc6310f1b" + integrity sha512-pCqe7dfsQFBABC1jeKZXQWhGcCPF3rPCXDdfqVKjIeWBcXzyC1iOWZdfFhGl+S9MyE/k//DFmC6FzuGAUudNDg== dependencies: "@develar/schema-utils" "~2.6.5" - "@electron/notarize" "2.2.1" - "@electron/osx-sign" "1.0.5" - "@electron/universal" "1.5.1" + "@electron/notarize" "2.5.0" + "@electron/osx-sign" "1.3.1" + "@electron/rebuild" "3.6.1" + "@electron/universal" "2.0.1" "@malept/flatpak-bundler" "^0.4.0" "@types/fs-extra" "9.0.13" async-exit-hook "^2.0.1" bluebird-lst "^1.0.9" - builder-util "24.13.1" - builder-util-runtime "9.2.4" + builder-util "25.1.7" + builder-util-runtime "9.2.10" chromium-pickle-js "^0.2.0" + config-file-ts "0.2.8-rc1" debug "^4.3.4" + dotenv "^16.4.5" + dotenv-expand "^11.0.6" ejs "^3.1.8" - electron-publish "24.13.1" + electron-publish "25.1.7" form-data "^4.0.0" fs-extra "^10.1.0" hosted-git-info "^4.1.0" is-ci "^3.0.0" isbinaryfile "^5.0.0" js-yaml "^4.1.0" + json5 "^2.2.3" lazy-val "^1.0.5" - minimatch "^5.1.1" - read-config-file "6.3.2" + minimatch "^10.0.0" + resedit "^1.7.0" sanitize-filename "^1.6.3" semver "^7.3.8" tar "^6.1.12" temp-file "^3.4.0" +"aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + are-docs-informative@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/are-docs-informative/-/are-docs-informative-0.0.2.tgz#387f0e93f5d45280373d387a59d34c96db321963" integrity sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig== +are-we-there-yet@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" + integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -2675,6 +2787,15 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== +bl@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + bluebird-lst@^1.0.9: version "1.0.9" resolved "https://registry.yarnpkg.com/bluebird-lst/-/bluebird-lst-1.0.9.tgz#a64a0e4365658b9ab5fe875eb9dfb694189bb41c" @@ -2792,7 +2913,7 @@ buffer-from@^1.1.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== -buffer@^5.1.0: +buffer@^5.1.0, buffer@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -2800,30 +2921,30 @@ buffer@^5.1.0: base64-js "^1.3.1" ieee754 "^1.1.13" -builder-util-runtime@9.2.4: - version "9.2.4" - resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz#13cd1763da621e53458739a1e63f7fcba673c42a" - integrity sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA== +builder-util-runtime@9.2.10: + version "9.2.10" + resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.2.10.tgz#a0f7d9e214158402e78b74a745c8d9f870c604bc" + integrity sha512-6p/gfG1RJSQeIbz8TK5aPNkoztgY1q5TgmGFMAXcY8itsGW6Y2ld1ALsZ5UJn8rog7hKF3zHx5iQbNQ8uLcRlw== dependencies: debug "^4.3.4" sax "^1.2.4" -builder-util@24.13.1: - version "24.13.1" - resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-24.13.1.tgz#4a4c4f9466b016b85c6990a0ea15aa14edec6816" - integrity sha512-NhbCSIntruNDTOVI9fdXz0dihaqX2YuE1D6zZMrwiErzH4ELZHE6mdiB40wEgZNprDia+FghRFgKoAqMZRRjSA== +builder-util@25.1.7: + version "25.1.7" + resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-25.1.7.tgz#a07b404f0cb1a635aa165902be65297d58932ff8" + integrity sha512-7jPjzBwEGRbwNcep0gGNpLXG9P94VA3CPAZQCzxkFXiV2GMQKlziMbY//rXPI7WKfhsvGgFXjTcXdBEwgXw9ww== dependencies: "7zip-bin" "~5.2.0" "@types/debug" "^4.1.6" - app-builder-bin "4.0.0" + app-builder-bin "5.0.0-alpha.10" bluebird-lst "^1.0.9" - builder-util-runtime "9.2.4" + builder-util-runtime "9.2.10" chalk "^4.1.2" cross-spawn "^7.0.3" debug "^4.3.4" fs-extra "^10.1.0" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.1" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.0" is-ci "^3.0.0" js-yaml "^4.1.0" source-map-support "^0.5.19" @@ -2842,6 +2963,30 @@ bundle-name@^3.0.0: dependencies: run-applescript "^5.0.0" +cacache@^16.1.0: + version "16.1.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.3.tgz#a02b9f34ecfaf9a78c9f4bc16fceb94d5d67a38e" + integrity sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ== + dependencies: + "@npmcli/fs" "^2.1.0" + "@npmcli/move-file" "^2.0.0" + chownr "^2.0.0" + fs-minipass "^2.1.0" + glob "^8.0.1" + infer-owner "^1.0.4" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + mkdirp "^1.0.4" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^9.0.0" + tar "^6.1.11" + unique-filename "^2.0.0" + cacheable-lookup@^5.0.3: version "5.0.4" resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" @@ -3006,6 +3151,23 @@ clean-css@^5.2.2: dependencies: source-map "~0.6.0" +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-spinners@^2.5.0: + version "2.9.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== + cli-truncate@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" @@ -3048,6 +3210,11 @@ clone-response@^1.0.2: dependencies: mimic-response "^1.0.0" +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -3082,6 +3249,11 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + colorette@^2.0.10: version "2.0.16" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" @@ -3134,13 +3306,18 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -config-file-ts@^0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/config-file-ts/-/config-file-ts-0.2.4.tgz#6c0741fbe118a7cf786c65f139030f0448a2cc99" - integrity sha512-cKSW0BfrSaAUnxpgvpXPLaaW/umg4bqg4k3GO1JqlRfpx+d5W0GDXznCMkWotJQek5Mmz1MJVChQnz3IVaeMZQ== +config-file-ts@0.2.8-rc1: + version "0.2.8-rc1" + resolved "https://registry.yarnpkg.com/config-file-ts/-/config-file-ts-0.2.8-rc1.tgz#fb7fc6ccb2e313f69dbeb78f1db0b00038049de0" + integrity sha512-GtNECbVI82bT4RiDIzBSVuTKoSHufnU7Ce7/42bkWZJZFLjmDF2WBpVsvRkhKCfKBnTBb3qZrBwPpFBU/Myvhg== dependencies: - glob "^7.1.6" - typescript "^4.0.2" + glob "^10.3.12" + typescript "^5.4.3" + +console-control-strings@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== console-polyfill@^0.3.0: version "0.3.0" @@ -3304,6 +3481,13 @@ debug@^3.2.7: dependencies: ms "^2.1.1" +debug@^4.3.3: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -3359,6 +3543,13 @@ default-browser@^4.0.0: execa "^7.1.1" titleize "^3.0.0" +defaults@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" + integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== + dependencies: + clone "^1.0.2" + defer-to-connect@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" @@ -3425,11 +3616,21 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + dequal@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== +detect-libc@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" + integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== + detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" @@ -3466,6 +3667,14 @@ dir-compare@^3.0.0: buffer-equal "^1.0.0" minimatch "^3.0.4" +dir-compare@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dir-compare/-/dir-compare-4.2.0.tgz#d1d4999c14fbf55281071fdae4293b3b9ce86f19" + integrity sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ== + dependencies: + minimatch "^3.0.5" + p-limit "^3.1.0 " + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -3473,14 +3682,14 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" -dmg-builder@24.13.3: - version "24.13.3" - resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-24.13.3.tgz#95d5b99c587c592f90d168a616d7ec55907c7e55" - integrity sha512-rcJUkMfnJpfCboZoOOPf4L29TRtEieHNOeAbYPWPxlaBw/Z1RKrRA86dOI9rwaI4tQSc/RD82zTNHprfUHXsoQ== +dmg-builder@25.1.8: + version "25.1.8" + resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-25.1.8.tgz#41f3b725edd896156e891016a44129e1bd580430" + integrity sha512-NoXo6Liy2heSklTI5OIZbCgXC1RzrDQsZkeEwXhdOro3FT1VBOvbubvscdPnjVuQ4AMwwv61oaH96AbiYg9EnQ== dependencies: - app-builder-lib "24.13.3" - builder-util "24.13.1" - builder-util-runtime "9.2.4" + app-builder-lib "25.1.8" + builder-util "25.1.7" + builder-util-runtime "9.2.10" fs-extra "^10.1.0" iconv-lite "^0.6.2" js-yaml "^4.1.0" @@ -3567,15 +3776,17 @@ dot-case@^3.0.4: no-case "^3.0.4" tslib "^2.0.3" -dotenv-expand@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" - integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== +dotenv-expand@^11.0.6: + version "11.0.6" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-11.0.6.tgz#f2c840fd924d7c77a94eff98f153331d876882d3" + integrity sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g== + dependencies: + dotenv "^16.4.4" -dotenv@^9.0.2: - version "9.0.2" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-9.0.2.tgz#dacc20160935a37dea6364aa1bef819fb9b6ab05" - integrity sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg== +dotenv@^16.4.4, dotenv@^16.4.5: + version "16.4.5" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== duplexer@^0.1.2: version "0.1.2" @@ -3599,20 +3810,19 @@ ejs@^3.1.8: dependencies: jake "^10.8.5" -electron-builder@^24.13.3: - version "24.13.3" - resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-24.13.3.tgz#c506dfebd36d9a50a83ee8aa32d803d83dbe4616" - integrity sha512-yZSgVHft5dNVlo31qmJAe4BVKQfFdwpRw7sFp1iQglDRCDD6r22zfRJuZlhtB5gp9FHUxCMEoWGq10SkCnMAIg== +electron-builder@^25.1.8: + version "25.1.8" + resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-25.1.8.tgz#b0e310f1600787610bb84c3f39bc7aadb2548486" + integrity sha512-poRgAtUHHOnlzZnc9PK4nzG53xh74wj2Jy7jkTrqZ0MWPoHGh1M2+C//hGeYdA+4K8w4yiVCNYoLXF7ySj2Wig== dependencies: - app-builder-lib "24.13.3" - builder-util "24.13.1" - builder-util-runtime "9.2.4" + app-builder-lib "25.1.8" + builder-util "25.1.7" + builder-util-runtime "9.2.10" chalk "^4.1.2" - dmg-builder "24.13.3" + dmg-builder "25.1.8" fs-extra "^10.1.0" is-ci "^3.0.0" lazy-val "^1.0.5" - read-config-file "6.3.2" simple-update-notifier "2.0.0" yargs "^17.6.2" @@ -3685,14 +3895,14 @@ electron-packager@^17.1.2: semver "^7.1.3" yargs-parser "^21.1.1" -electron-publish@24.13.1: - version "24.13.1" - resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-24.13.1.tgz#57289b2f7af18737dc2ad134668cdd4a1b574a0c" - integrity sha512-2ZgdEqJ8e9D17Hwp5LEq5mLQPjqU3lv/IALvgp+4W8VeNhryfGhYEQC/PgDPMrnWUp+l60Ou5SJLsu+k4mhQ8A== +electron-publish@25.1.7: + version "25.1.7" + resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-25.1.7.tgz#14e50c2a3fafdc1c454eadbbc47ead89a48bb554" + integrity sha512-+jbTkR9m39eDBMP4gfbqglDd6UvBC7RLh5Y0MhFSsc6UkGHj9Vj9TWobxevHYMMqmoujL11ZLjfPpMX+Pt6YEg== dependencies: "@types/fs-extra" "^9.0.11" - builder-util "24.13.1" - builder-util-runtime "9.2.4" + builder-util "25.1.7" + builder-util-runtime "9.2.10" chalk "^4.1.2" fs-extra "^10.1.0" lazy-val "^1.0.5" @@ -3753,6 +3963,13 @@ emojis-list@^3.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== +encoding@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -4425,6 +4642,11 @@ expect@^29.0.0, expect@^29.7.0: jest-message-util "^29.7.0" jest-util "^29.7.0" +exponential-backoff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" + integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== + extract-zip@^2.0.0, extract-zip@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" @@ -4648,10 +4870,10 @@ fs-extra@^10.0.0, fs-extra@^10.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^11.1.0: - version "11.1.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" - integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== +fs-extra@^11.1.0, fs-extra@^11.1.1: + version "11.2.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" @@ -4685,7 +4907,7 @@ fs-extra@^9.0.0, fs-extra@^9.0.1: jsonfile "^6.0.1" universalify "^2.0.0" -fs-minipass@^2.0.0: +fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== @@ -4770,6 +4992,20 @@ gar@^1.0.4: resolved "https://registry.yarnpkg.com/gar/-/gar-1.0.4.tgz#f777bc7db425c0572fdeb52676172ca1ae9888b8" integrity sha512-w4n9cPWyP7aHxKxYHFQMegj7WIAsL/YX/C4Bs5Rr8s1H9M1rNtRWRsw+ovYMkXDQ5S4ZbYHsHAPmevPjPgw44w== +gauge@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" + integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.3" + console-control-strings "^1.1.0" + has-unicode "^2.0.1" + signal-exit "^3.0.7" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.5" + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -4882,6 +5118,18 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== +glob@^10.3.12: + version "10.4.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" + integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== + dependencies: + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" + glob@^11.0.0: version "11.0.0" resolved "https://registry.yarnpkg.com/glob/-/glob-11.0.0.tgz#6031df0d7b65eaa1ccb9b29b5ced16cea658e77e" @@ -4930,6 +5178,17 @@ glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^8.0.1: + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + glob@~8.0.3: version "8.0.3" resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e" @@ -4998,7 +5257,7 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -got@^11.8.5: +got@^11.7.0, got@^11.8.5: version "11.8.6" resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== @@ -5020,7 +5279,7 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.6, graceful-fs@^4.2.0: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== -graceful-fs@^4.1.2, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -5115,6 +5374,11 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" +has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== + has@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" @@ -5204,7 +5468,7 @@ htmlparser2@^6.1.0: domutils "^2.5.2" entities "^2.0.0" -http-cache-semantics@^4.0.0: +http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== @@ -5234,7 +5498,7 @@ http2-wrapper@^1.0.0-beta.5.2: quick-lru "^5.1.1" resolve-alpn "^1.0.0" -https-proxy-agent@^5.0.1: +https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== @@ -5260,6 +5524,13 @@ human-signals@^4.3.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== + dependencies: + ms "^2.0.0" + iconv-corefoundation@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz#31065e6ab2c9272154c8b0821151e2c88f1b002a" @@ -5321,6 +5592,16 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -5329,7 +5610,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2: +inherits@2, inherits@^2.0.3, inherits@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -5362,6 +5643,14 @@ interpret@^1.0.1: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.4.tgz#820cdd588b868ffb191a809506d6c9c8f212b1b0" integrity sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA= +ip-address@^9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a" + integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g== + dependencies: + jsbn "1.1.0" + sprintf-js "^1.1.3" + is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" @@ -5518,6 +5807,16 @@ is-inside-container@^1.0.0: dependencies: is-docker "^3.0.0" +is-interactive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== + +is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" + integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== + is-map@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" @@ -5637,6 +5936,11 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: dependencies: which-typed-array "^1.1.11" +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + is-weakmap@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" @@ -5758,6 +6062,15 @@ iterator.prototype@^1.1.2: reflect.getprototypeof "^1.0.4" set-function-name "^2.0.1" +jackspeak@^3.1.2: + version "3.4.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" + integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + jackspeak@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.0.1.tgz#9fca4ce961af6083e259c376e9e3541431f5287b" @@ -6206,6 +6519,11 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" +jsbn@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" + integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A== + jsdoc-type-pratt-parser@~4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz#136f0571a99c184d84ec84662c45c29ceff71114" @@ -6300,7 +6618,7 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.2.0, json5@^2.2.3: +json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -6417,7 +6735,7 @@ language-tags@=1.0.5: dependencies: language-subtag-registry "~0.3.2" -lazy-val@^1.0.4, lazy-val@^1.0.5: +lazy-val@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.5.tgz#6cf3b9f5bc31cee7ee3e369c0832b7583dcd923d" integrity sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q== @@ -6576,6 +6894,14 @@ lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17 resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +log-symbols@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -6595,6 +6921,11 @@ lowercase-keys@^2.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== +lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + lru-cache@^11.0.0: version "11.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.0.0.tgz#15d93a196f189034d7166caf9fe55e7384c98a21" @@ -6614,6 +6945,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lru-cache@^7.7.1: + version "7.18.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + make-dir@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.2.tgz#04a1acbf22221e1d6ef43559f43e05a90dbb4392" @@ -6631,6 +6967,28 @@ make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.0.tgz#52ad3a339ccf10ce62b4040b708fe707244b8b96" integrity sha1-Uq06M5zPEM5itAQLcI/nByRLi5Y= +make-fetch-happen@^10.0.3: + version "10.2.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" + integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w== + dependencies: + agentkeepalive "^4.2.1" + cacache "^16.1.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-fetch "^2.0.3" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + promise-retry "^2.0.1" + socks-proxy-agent "^7.0.0" + ssri "^9.0.0" + makeerror@1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" @@ -6793,10 +7151,10 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@^5.1.1: - version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== +minimatch@^9.0.3, minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== dependencies: brace-expansion "^2.0.1" @@ -6817,7 +7175,46 @@ minimist@^1.2.0, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== -minipass@^3.0.0: +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-fetch@^2.0.3: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-2.1.2.tgz#95560b50c472d81a3bc76f20ede80eaed76d8add" + integrity sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA== + dependencies: + minipass "^3.1.6" + minipass-sized "^1.0.3" + minizlib "^2.1.2" + optionalDependencies: + encoding "^0.1.13" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.1, minipass@^3.1.6: version "3.3.6" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== @@ -6829,12 +7226,12 @@ minipass@^5.0.0: resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== -minipass@^7.1.2: +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== -minizlib@^2.1.1: +minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== @@ -6849,7 +7246,7 @@ mkdirp@^0.5.1: dependencies: minimist "0.0.8" -mkdirp@^1.0.3: +mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -6869,7 +7266,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.1.1: +ms@^2.0.0, ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -6884,6 +7281,11 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +negotiator@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" @@ -6897,11 +7299,42 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" +node-abi@^3.45.0: + version "3.67.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.67.0.tgz#1d159907f18d18e18809dbbb5df47ed2426a08df" + integrity sha512-bLn/fU/ALVBE9wj+p4Y21ZJWYFjUXLXPi/IewyLZkx3ApxKDNBWCKdReeKOtD8dWpOdDCeMyLh6ZewzcLsG2Nw== + dependencies: + semver "^7.3.5" + node-addon-api@^1.6.3: version "1.7.2" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.7.2.tgz#3df30b95720b53c24e59948b49532b662444f54d" integrity sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg== +node-api-version@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/node-api-version/-/node-api-version-0.2.0.tgz#5177441da2b1046a4d4547ab9e0972eed7b1ac1d" + integrity sha512-fthTTsi8CxaBXMaBAD7ST2uylwvsnYxh2PfaScwpMhos6KlSFajXQPcM4ogNE1q2s3Lbz9GCGqeIHC+C6OZnKg== + dependencies: + semver "^7.3.5" + +node-gyp@^9.0.0: + version "9.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.1.tgz#8a1023e0d6766ecb52764cc3a734b36ff275e185" + integrity sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ== + dependencies: + env-paths "^2.2.0" + exponential-backoff "^3.1.1" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^10.0.3" + nopt "^6.0.0" + npmlog "^6.0.0" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.2" + which "^2.0.2" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -6921,6 +7354,13 @@ node-releases@^2.0.18, node-releases@^2.0.6: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== +nopt@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d" + integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== + dependencies: + abbrev "^1.0.0" + normalize-package-data@^2.0.0, normalize-package-data@^2.3.2: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" @@ -6955,6 +7395,16 @@ npm-run-path@^5.1.0: dependencies: path-key "^4.0.0" +npmlog@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" + integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== + dependencies: + are-we-there-yet "^3.0.0" + console-control-strings "^1.1.0" + gauge "^4.0.3" + set-blocking "^2.0.0" + nth-check@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" @@ -7101,7 +7551,7 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -onetime@^5.1.2: +onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== @@ -7150,6 +7600,21 @@ optionator@^0.9.3: prelude-ls "^1.2.1" type-check "^0.4.0" +ora@^5.1.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" + integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== + dependencies: + bl "^4.1.0" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-spinners "^2.5.0" + is-interactive "^1.0.0" + is-unicode-supported "^0.1.0" + log-symbols "^4.1.0" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -7172,7 +7637,7 @@ p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-limit@^3.0.2, p-limit@^3.1.0: +p-limit@^3.0.2, p-limit@^3.1.0, "p-limit@^3.1.0 ": version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -7200,6 +7665,13 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + p-try@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" @@ -7338,6 +7810,14 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-scurry@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.0.tgz#9f052289f23ad8bf9397a2a0425e7b8615c58580" @@ -7358,6 +7838,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pe-library@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/pe-library/-/pe-library-0.4.1.tgz#e269be0340dcb13aa6949d743da7d658c3e2fbea" + integrity sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw== + pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" @@ -7408,6 +7893,15 @@ plist@^3.0.0, plist@^3.0.4, plist@^3.0.5: base64-js "^1.5.1" xmlbuilder "^15.1.1" +plist@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/plist/-/plist-3.1.0.tgz#797a516a93e62f5bde55e0b9cc9c967f860893c9" + integrity sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ== + dependencies: + "@xmldom/xmldom" "^0.8.8" + base64-js "^1.5.1" + xmlbuilder "^15.1.1" + pluralize@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" @@ -7512,6 +8006,11 @@ progress@^2.0.3: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== + promise-retry@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" @@ -7625,17 +8124,12 @@ react-is@^18.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== -read-config-file@6.3.2: - version "6.3.2" - resolved "https://registry.yarnpkg.com/read-config-file/-/read-config-file-6.3.2.tgz#556891aa6ffabced916ed57457cb192e61880411" - integrity sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q== +read-binary-file-arch@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/read-binary-file-arch/-/read-binary-file-arch-1.0.6.tgz#959c4637daa932280a9b911b1a6766a7e44288fc" + integrity sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg== dependencies: - config-file-ts "^0.2.4" - dotenv "^9.0.2" - dotenv-expand "^5.1.0" - js-yaml "^4.1.0" - json5 "^2.2.0" - lazy-val "^1.0.4" + debug "^4.3.4" read-installed@4.0.3: version "4.0.3" @@ -7680,6 +8174,15 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" +readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdir-scoped-modules@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz#9fafa37d286be5d92cbaebdee030dc9b5f406747" @@ -7770,6 +8273,13 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== +resedit@^1.7.0: + version "1.7.1" + resolved "https://registry.yarnpkg.com/resedit/-/resedit-1.7.1.tgz#150c101000210968730141ae2eb504ca0aead165" + integrity sha512-/FJ6/gKAXbcHtivannhecWsa43kGVFK3aHHv9Jm3x0eFiM31MoGihkAOWbm3UsvjYLRVw0zTkfARy2dI96JL1Q== + dependencies: + pe-library "^0.4.1" + reserved-words@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/reserved-words/-/reserved-words-0.1.2.tgz#00a0940f98cd501aeaaac316411d9adc52b31ab1" @@ -7827,6 +8337,14 @@ responselike@^2.0.0: dependencies: lowercase-keys "^2.0.0" +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" @@ -7917,7 +8435,7 @@ safe-array-concat@^1.0.1: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@^5.1.0: +safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -8010,7 +8528,7 @@ semver@^7.1.1, semver@^7.1.3, semver@^7.3.2, semver@^7.3.4, semver@^7.3.7, semve dependencies: lru-cache "^6.0.0" -semver@^7.5.0, semver@^7.6.3: +semver@^7.3.5, semver@^7.5.0, semver@^7.6.3: version "7.6.3" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== @@ -8029,6 +8547,11 @@ serialize-javascript@^6.0.1: dependencies: randombytes "^2.1.0" +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + set-function-length@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" @@ -8088,7 +8611,7 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.3, signal-exit@^3.0.7: +signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== @@ -8148,7 +8671,7 @@ slide@~1.1.3: resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= -smart-buffer@^4.0.2: +smart-buffer@^4.0.2, smart-buffer@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== @@ -8158,6 +8681,23 @@ smoothscroll-polyfill@^0.3.6: resolved "https://registry.yarnpkg.com/smoothscroll-polyfill/-/smoothscroll-polyfill-0.3.6.tgz#492be845195157cdc2fc529a95d89e7a71509172" integrity sha1-SSvoRRlRV83C/FKaldieenFQkXI= +socks-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" + integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== + dependencies: + agent-base "^6.0.2" + debug "^4.3.3" + socks "^2.6.2" + +socks@^2.6.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.3.tgz#1ebd0f09c52ba95a09750afe3f3f9f724a800cb5" + integrity sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw== + dependencies: + ip-address "^9.0.5" + smart-buffer "^4.2.0" + source-map-js@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" @@ -8224,11 +8764,23 @@ sprintf-js@^1.1.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== +sprintf-js@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a" + integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= +ssri@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057" + integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== + dependencies: + minipass "^3.1.1" + stack-utils@^2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" @@ -8249,7 +8801,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -8381,6 +8933,13 @@ string.prototype.trimstart@^1.0.7: define-properties "^1.2.0" es-abstract "^1.22.1" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -8519,6 +9078,18 @@ tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tar@^6.0.5, tar@^6.1.11, tar@^6.1.2: + version "6.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" + integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + tar@^6.1.12: version "6.1.15" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.15.tgz#c9738b0b98845a3b344d334b8fa3041aaba53a69" @@ -8848,10 +9419,10 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" -typescript@^4.0.2: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +typescript@^5.4.3: + version "5.5.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" + integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== typescript@^5.6.3: version "5.6.3" @@ -8898,6 +9469,20 @@ undici-types@~6.19.2: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== +unique-filename@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-2.0.1.tgz#e785f8675a9a7589e0ac77e0b5c34d2eaeac6da2" + integrity sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A== + dependencies: + unique-slug "^3.0.0" + +unique-slug@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-3.0.0.tgz#6d347cf57c8a7a7a6044aabd0e2d74e4d76dc7c9" + integrity sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w== + dependencies: + imurmurhash "^0.1.4" + universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" @@ -8951,7 +9536,7 @@ utf8-byte-length@^1.0.1: resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61" integrity sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA== -util-deprecate@^1.0.2: +util-deprecate@^1.0.1, util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= @@ -9045,6 +9630,13 @@ watchpack@^2.4.1: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== + dependencies: + defaults "^1.0.3" + webidl-conversions@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" @@ -9231,6 +9823,13 @@ which@^2.0.1, which@^2.0.2: dependencies: isexe "^2.0.0" +wide-align@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + wildcard@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" @@ -9379,7 +9978,7 @@ yargs@^16.0.2: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@^17.3.1, yargs@^17.6.2: +yargs@^17.0.1, yargs@^17.3.1, yargs@^17.6.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== From 6b8442f457b935a450bca75c0324e0d63467cbaa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 19:53:56 -0300 Subject: [PATCH 40/41] build(deps): bump peter-evans/create-pull-request from 6.1.0 to 7.0.5 (#1121 #1130 #1132) Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6.1.0 to 7.0.5. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/v6.1.0...v7.0.5) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index 72f2ea0cad9..3e3bf6e140e 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -37,7 +37,7 @@ jobs: private_key: ${{ secrets.DESKTOP_RELEASES_APP_PRIVATE_KEY }} - name: Create Release Pull Request - uses: peter-evans/create-pull-request@v6.1.0 + uses: peter-evans/create-pull-request@v7.0.5 if: | startsWith(github.ref, 'refs/heads/releases/') && !contains(github.ref, 'test') with: From d00a4149918e552180e7a78fd0bab1d82dc13c51 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Fri, 8 Nov 2024 17:41:22 -0400 Subject: [PATCH 41/41] remove windows-argv-parser package and related code (#1156) --- app/package.json | 1 - app/src/lib/custom-integration.ts | 3 +-- app/yarn.lock | 10 ---------- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/app/package.json b/app/package.json index c7aba52d449..ed795085377 100644 --- a/app/package.json +++ b/app/package.json @@ -66,7 +66,6 @@ "tslib": "^2.0.0", "untildify": "^3.0.2", "uuid": "^3.0.1", - "windows-argv-parser": "file:../vendor/windows-argv-parser", "winston": "^3.6.0" }, "devDependencies": { diff --git a/app/src/lib/custom-integration.ts b/app/src/lib/custom-integration.ts index 55a9a57d6b9..dfead4b2525 100644 --- a/app/src/lib/custom-integration.ts +++ b/app/src/lib/custom-integration.ts @@ -1,5 +1,4 @@ import { ChildProcess, SpawnOptions, spawn } from 'child_process' -import { parseCommandLineArgv } from 'windows-argv-parser' import stringArgv from 'string-argv' import { promisify } from 'util' import { exec } from 'child_process' @@ -29,7 +28,7 @@ export interface ICustomIntegration { export function parseCustomIntegrationArguments( args: string ): ReadonlyArray { - return __WIN32__ ? parseCommandLineArgv(args) : stringArgv(args) + return stringArgv(args) } // Function to retrieve, on macOS, the bundleId of an app given its path diff --git a/app/yarn.lock b/app/yarn.lock index 0fe33fd0eee..d004b535ab8 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -843,11 +843,6 @@ node-addon-api@^5.0.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.0.0.tgz#7d7e6f9ef89043befdb20c1989c905ebde18c501" integrity sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA== -node-addon-api@^7.0.0: - version "7.1.1" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.1.1.tgz#1aba6693b0f255258a049d621329329322aad558" - integrity sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ== - noop-logger@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" @@ -1532,11 +1527,6 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" -"windows-argv-parser@file:../vendor/windows-argv-parser": - version "0.0.1" - dependencies: - node-addon-api "^7.0.0" - winston-transport@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.5.0.tgz#6e7b0dd04d393171ed5e4e4905db265f7ab384fa"