Merge branch 'development' into update-eslint-dependencies

This commit is contained in:
William Shepherd 2019-06-10 11:02:17 -05:00 committed by GitHub
commit dc5bb72afa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 336 additions and 89 deletions

View file

@ -3,7 +3,7 @@
"productName": "GitHub Desktop",
"bundleID": "com.github.GitHubClient",
"companyName": "GitHub, Inc.",
"version": "1.7.1-beta1",
"version": "2.0.4-beta0",
"main": "./main.js",
"repository": {
"type": "git",

View file

@ -91,5 +91,5 @@ export function enableStashing(): boolean {
* protected branch?
*/
export function enableBranchProtectionWarning(): boolean {
return enableBetaFeatures()
return true
}

View file

@ -69,10 +69,10 @@ export async function getRecentBranches(
* Returns a map keyed on branch names
*
* @param repository the repository who's reflog you want to check
* @param afterDate the minimum date a checkout has to occur
* @param afterDate filters checkouts so that only those occuring on or after this date are returned
* @returns map of branch name -> checkout date
*/
export async function getCheckoutsAfterDate(
export async function getBranchCheckouts(
repository: Repository,
afterDate: Date
): Promise<Map<string, Date>> {

View file

@ -75,7 +75,7 @@ export class AccountsStore extends TypedBaseStore<ReadonlyArray<Account>> {
/**
* Add the account to the store.
*/
public async addAccount(account: Account): Promise<void> {
public async addAccount(account: Account): Promise<Account | null> {
await this.loadingPromise
let updated = account
@ -103,12 +103,13 @@ export class AccountsStore extends TypedBaseStore<ReadonlyArray<Account>> {
} else {
this.emitError(e)
}
return
return null
}
this.accounts = [...this.accounts, updated]
this.save()
return updated
}
/** Refresh all accounts by fetching their latest info from the API. */

View file

@ -171,15 +171,16 @@ export class ApiRepositoriesStore extends BaseStore {
* the provided account has explicit permissions to access.
*/
public async loadRepositories(account: Account) {
const existingRepositories = this.accountState.get(account)
const existingAccount = resolveAccount(account, this.accountState)
const existingRepositories = this.accountState.get(existingAccount)
if (existingRepositories !== undefined && existingRepositories.loading) {
return
}
this.updateAccount(account, { loading: true })
this.updateAccount(existingAccount, { loading: true })
const api = API.fromAccount(account)
const api = API.fromAccount(existingAccount)
const repositories = await api.fetchRepositories()
if (repositories === null) {

View file

@ -4449,7 +4449,7 @@ export class AppStore extends TypedBaseStore<IAppState> {
log.info(
`[AppStore] adding account ${account.login} (${account.name}) to store`
)
await this.accountsStore.addAccount(account)
const storedAccount = await this.accountsStore.addAccount(account)
const selectedState = this.getState().selectedState
if (selectedState && selectedState.type === SelectionType.Repository) {
@ -4466,8 +4466,8 @@ export class AppStore extends TypedBaseStore<IAppState> {
// a refresh of the repositories available for cloning straight away
// in order to have the list of repositories ready for them when they
// get to the blankslate.
if (this.showWelcomeFlow) {
this.apiRepositoriesStore.loadRepositories(account)
if (this.showWelcomeFlow && storedAccount !== null) {
this.apiRepositoriesStore.loadRepositories(storedAccount)
}
}
@ -5228,6 +5228,14 @@ export class AppStore extends TypedBaseStore<IAppState> {
return Promise.resolve()
}
public async _testPruneBranches() {
if (this.currentBranchPruner === null) {
return
}
await this.currentBranchPruner.testPrune()
}
}
/**

View file

@ -4,7 +4,7 @@ import { Branch } from '../../../models/branch'
import { GitStoreCache } from '../git-store-cache'
import {
getMergedBranches,
getCheckoutsAfterDate,
getBranchCheckouts,
getSymbolicRef,
IMergedBranch,
formatAsLocalRef,
@ -28,6 +28,31 @@ const ReservedRefs = [
'refs/heads/release',
]
/**
* Behavior flags for the branch prune execution, to aid with testing and
* verifying locally.
*/
type PruneRuntimeOptions = {
/**
* By default the branch pruner will only run every 24 hours
*
* Set this flag to `false` to ignore this check.
*/
readonly enforcePruneThreshold: boolean
/**
* By default the branch pruner will also delete the branches it believes can
* be pruned safely.
*
* Set this to `false` to keep these in your repository.
*/
readonly deleteBranch: boolean
}
const DefaultPruneOptions: PruneRuntimeOptions = {
enforcePruneThreshold: true,
deleteBranch: true,
}
export class BranchPruner {
private timer: number | null = null
@ -48,9 +73,9 @@ export class BranchPruner {
)
}
await this.pruneLocalBranches()
await this.pruneLocalBranches(DefaultPruneOptions)
this.timer = window.setInterval(
() => this.pruneLocalBranches(),
() => this.pruneLocalBranches(DefaultPruneOptions),
BackgroundPruneMinimumInterval
)
}
@ -64,6 +89,13 @@ export class BranchPruner {
this.timer = null
}
public async testPrune(): Promise<void> {
return this.pruneLocalBranches({
enforcePruneThreshold: false,
deleteBranch: false,
})
}
private async findBranchesMergedIntoDefaultBranch(
repository: Repository,
defaultBranch: Branch
@ -87,7 +119,14 @@ export class BranchPruner {
)
}
private async pruneLocalBranches(): Promise<void> {
/**
* Prune the local branches for the repository
*
* @param options configure the behaviour of the branch pruning process
*/
private async pruneLocalBranches(
options: PruneRuntimeOptions
): Promise<void> {
if (this.repository.gitHubRepository === null) {
return
}
@ -103,9 +142,13 @@ export class BranchPruner {
// Using type coelescing behavior to deal with Dexie returning `undefined`
// for records that haven't been updated with the new field yet
if (lastPruneDate != null && threshold.isBefore(lastPruneDate)) {
if (
options.enforcePruneThreshold &&
lastPruneDate != null &&
threshold.isBefore(lastPruneDate)
) {
log.info(
`Last prune took place ${moment(lastPruneDate).from(
`[BranchPruner] Last prune took place ${moment(lastPruneDate).from(
dateNow
)} - skipping`
)
@ -126,7 +169,7 @@ export class BranchPruner {
)
if (mergedBranches.length === 0) {
log.info('No branches to prune.')
log.info('[BranchPruner] No branches to prune.')
return
}
@ -134,7 +177,7 @@ export class BranchPruner {
const twoWeeksAgo = moment()
.subtract(2, 'weeks')
.toDate()
const recentlyCheckedOutBranches = await getCheckoutsAfterDate(
const recentlyCheckedOutBranches = await getBranchCheckouts(
this.repository,
twoWeeksAgo
)
@ -152,7 +195,7 @@ export class BranchPruner {
)
log.info(
`Pruning ${
`[BranchPruner] Pruning ${
branchesReadyForPruning.length
} branches that have been merged into the default branch, ${
defaultBranch.name
@ -169,12 +212,18 @@ export class BranchPruner {
const branchName = branch.canonicalRef.substr(branchRefPrefix.length)
const isDeleted = await gitStore.performFailableOperation(() =>
deleteLocalBranch(this.repository, branchName)
)
if (options.deleteBranch) {
const isDeleted = await gitStore.performFailableOperation(() =>
deleteLocalBranch(this.repository, branchName)
)
if (isDeleted) {
log.info(`Pruned branch ${branchName} (was ${branch.sha})`)
if (isDeleted) {
log.info(
`[BranchPruner] Pruned branch ${branchName} (was ${branch.sha})`
)
}
} else {
log.info(`[BranchPruner] Branch '${branchName}' marked for deletion`)
}
}

View file

@ -9,7 +9,7 @@ import {
import { GitHubRepository } from '../../models/github-repository'
import { Account } from '../../models/account'
import { API, IAPIPullRequest, MaxResultsError } from '../api'
import { fatalError, forceUnwrap } from '../fatal-error'
import { fatalError } from '../fatal-error'
import { RepositoriesStore } from './repositories-store'
import { PullRequest, PullRequestRef } from '../../models/pull-request'
import { structuralEquals } from '../equality'
@ -69,7 +69,16 @@ export class PullRequestStore {
/** Loads all pull requests against the given repository. */
public refreshPullRequests(repo: GitHubRepository, account: Account) {
const dbId = forceUnwrap("Can't refresh PRs, no dbId", repo.dbID)
const dbId = repo.dbID
if (dbId === null) {
// This can happen when the `repositoryWithRefreshedGitHubRepository`
// method in AppStore fails to retrieve API information about the current
// repository either due to the user being signed out or the API failing
// to provide a response. There's nothing for us to do when that happens
// so instead of crashing we'll bail here.
return Promise.resolve()
}
const currentOp = this.currentRefreshOperations.get(dbId)
@ -182,8 +191,13 @@ export class PullRequestStore {
/** Gets all stored pull requests for the given repository. */
public async getAll(repository: GitHubRepository) {
if (repository.dbID == null) {
return fatalError("Can't fetch PRs for repository, no dbId")
if (repository.dbID === null) {
// This can happen when the `repositoryWithRefreshedGitHubRepository`
// method in AppStore fails to retrieve API information about the current
// repository either due to the user being signed out or the API failing
// to provide a response. There's nothing for us to do when that happens
// so instead of crashing we'll bail here.
return []
}
const records = await this.db.getAllPullRequestsInRepository(repository)

View file

@ -58,10 +58,23 @@ function handleUncaughtException(error: Error) {
showUncaughtException(isLaunchError, error)
}
/**
* Calculates the number of seconds the app has been running
*/
function getUptimeInSeconds() {
return (now() - launchTime) / 1000
}
function getExtraErrorContext(): Record<string, string> {
return {
uptime: getUptimeInSeconds().toFixed(3),
time: new Date().toString(),
}
}
process.on('uncaughtException', (error: Error) => {
error = withSourceMappedStack(error)
reportError(error)
reportError(error, getExtraErrorContext())
handleUncaughtException(error)
})
@ -447,7 +460,10 @@ app.on('ready', () => {
event: Electron.IpcMessageEvent,
{ error, extra }: { error: Error; extra: { [key: string]: string } }
) => {
reportError(error, extra)
reportError(error, {
...getExtraErrorContext(),
...extra,
})
}
)

View file

@ -9,10 +9,8 @@ import { log } from '../log'
import { openDirectorySafe } from '../shell'
import { enableRebaseDialog, enableStashing } from '../../lib/feature-flag'
import { MenuLabelsEvent } from '../../models/menu-labels'
import { DefaultEditorLabel } from '../../ui/lib/context-menu'
const defaultEditorLabel = __DARWIN__
? 'Open in External Editor'
: 'Open in external editor'
const defaultShellLabel = __DARWIN__
? 'Open in Terminal'
: 'Open in Command Prompt'
@ -57,7 +55,7 @@ export function buildDefaultMenu({
const editorLabel =
selectedExternalEditor === null
? defaultEditorLabel
? DefaultEditorLabel
: `Open in ${selectedExternalEditor}`
const template = new Array<Electron.MenuItemConstructorOptions>()
@ -286,7 +284,7 @@ export function buildDefaultMenu({
{
label: removeRepoLabel,
id: 'remove-repository',
accelerator: 'CmdOrCtrl+Delete',
accelerator: 'CmdOrCtrl+Backspace',
click: emit('remove-repository'),
},
separator,
@ -353,6 +351,7 @@ export function buildDefaultMenu({
{
label: __DARWIN__ ? 'Discard All Changes…' : 'Discard all changes…',
id: 'discard-all-changes',
accelerator: 'CmdOrCtrl+Shift+Backspace',
click: emit('discard-all-changes'),
},
separator,
@ -497,6 +496,10 @@ export function buildDefaultMenu({
click: emit('show-release-notes-popup'),
},
],
},
{
label: 'Prune branches',
click: emit('test-prune-branches'),
}
)
}

View file

@ -34,3 +34,4 @@ export type MenuEvent =
| 'show-release-notes-popup'
| 'show-stashed-changes'
| 'hide-stashed-changes'
| 'test-prune-branches'

View file

@ -365,6 +365,8 @@ export class App extends React.Component<IAppProps, IAppState> {
return this.showStashedChanges()
case 'hide-stashed-changes':
return this.hideStashedChanges()
case 'test-prune-branches':
return this.testPruneBranches()
}
return assertNever(name, `Unknown menu event name: ${name}`)
@ -425,6 +427,14 @@ export class App extends React.Component<IAppProps, IAppState> {
}
}
private testPruneBranches() {
if (!__DEV__) {
return
}
this.props.appStore._testPruneBranches()
}
/**
* Handler for the 'select-all' menu event, dispatches
* a custom DOM event originating from the element which
@ -473,18 +483,14 @@ export class App extends React.Component<IAppProps, IAppState> {
}
private getDotComAccount(): Account | null {
const state = this.props.appStore.getState()
const accounts = state.accounts
const dotComAccount = accounts.find(
const dotComAccount = this.state.accounts.find(
a => a.endpoint === getDotComAPIEndpoint()
)
return dotComAccount || null
}
private getEnterpriseAccount(): Account | null {
const state = this.props.appStore.getState()
const accounts = state.accounts
const enterpriseAccount = accounts.find(
const enterpriseAccount = this.state.accounts.find(
a => a.endpoint !== getDotComAPIEndpoint()
)
return enterpriseAccount || null

View file

@ -142,15 +142,24 @@ export class BlankSlateView extends React.Component<
this.ensureRepositoriesForAccount(this.getSelectedAccount())
}
public componentDidUpdate(prevProps: IBlankSlateProps) {
this.ensureRepositoriesForAccount(this.getSelectedAccount())
public componentDidUpdate(
prevProps: IBlankSlateProps,
prevState: IBlankSlateState
) {
if (
prevProps.dotComAccount !== this.props.dotComAccount ||
prevProps.enterpriseAccount !== this.props.enterpriseAccount ||
prevState.selectedTab !== this.state.selectedTab
) {
this.ensureRepositoriesForAccount(this.getSelectedAccount())
}
}
private ensureRepositoriesForAccount(account: Account | null) {
if (account !== null) {
const accountState = this.props.apiRepositories.get(account)
if (accountState === undefined || accountState.repositories === null) {
if (accountState === undefined) {
this.props.onRefreshRepositories(account)
}
}

View file

@ -35,7 +35,7 @@ import {
} from '../lib/stores'
import { GitHubUserDatabase } from '../lib/databases'
import { URLActionType } from '../lib/parse-app-url'
import { SelectionType } from '../lib/app-state'
import { SelectionType, IAppState } from '../lib/app-state'
import { StatsDatabase, StatsStore } from '../lib/stats'
import {
IssuesDatabase,
@ -89,6 +89,10 @@ if (!process.env.TEST_ENV) {
require('../../styles/desktop.scss')
}
let currentState: IAppState | null = null
let lastUnhandledRejection: string | null = null
let lastUnhandledRejectionTime: Date | null = null
process.once('uncaughtException', (error: Error) => {
error = withSourceMappedStack(error)
@ -99,15 +103,100 @@ process.once('uncaughtException', (error: Error) => {
`An uncaught exception was thrown. If this were a production build it would be reported to Central. Instead, maybe give it a lil lookyloo.`
)
} else {
sendErrorReport(error, {
const extra: Record<string, string> = {
osVersion: getOS(),
guid: getGUID(),
})
}
try {
if (currentState) {
if (currentState.currentBanner !== null) {
extra.currentBanner = currentState.currentBanner.type
}
if (currentState.currentPopup !== null) {
extra.currentPopup = `${currentState.currentPopup.type}`
}
if (currentState.selectedState !== null) {
extra.selectedState = `${currentState.selectedState.type}`
if (currentState.selectedState.type === SelectionType.Repository) {
extra.selectedRepositorySection = `${
currentState.selectedState.state.selectedSection
}`
}
}
if (currentState.currentFoldout !== null) {
extra.currentFoldout = `${currentState.currentFoldout.type}`
}
if (currentState.showWelcomeFlow) {
extra.inWelcomeFlow = 'true'
}
if (currentState.windowZoomFactor !== 1) {
extra.windowZoomFactor = `${currentState.windowZoomFactor}`
}
if (currentState.errors.length > 0) {
extra.activeAppErrors = `${currentState.errors.length}`
}
if (
lastUnhandledRejection !== null &&
lastUnhandledRejectionTime !== null
) {
extra.lastUnhandledRejection = lastUnhandledRejection
extra.lastUnhandledRejectionTime = lastUnhandledRejectionTime.toString()
}
extra.repositoryCount = `${currentState.repositories.length}`
extra.windowState = currentState.windowState
extra.accounts = `${currentState.accounts.length}`
if (__DARWIN__) {
extra.automaticallySwitchTheme = `${
currentState.automaticallySwitchTheme
}`
}
}
} catch (err) {
/* ignore */
}
sendErrorReport(error, extra)
}
reportUncaughtException(error)
})
/**
* Chromium won't crash on an unhandled rejection (similar to how
* it won't crash on an unhandled error). We've taken the approach
* that unhandled errors should crash the app and very likely we
* should do the same thing for unhandled promise rejections but
* that's a bit too risky to do until we've established some sense
* of how often it happens. For now this simply stores the last
* rejection so that we can pass it along with the crash report
* if the app does crash. Note that this does not prevent the
* default browser behavior of logging since we're not calling
* `preventDefault` on the event.
*
* See https://developer.mozilla.org/en-US/docs/Web/API/Window/unhandledrejection_event
*/
window.addEventListener('unhandledrejection', ev => {
if (ev.reason !== null && ev.reason !== undefined) {
try {
lastUnhandledRejection = `${ev.reason}`
lastUnhandledRejectionTime = new Date()
} catch (err) {
/* ignore */
}
}
})
const gitHubUserStore = new GitHubUserStore(
new GitHubUserDatabase('GitHubUserDatabase')
)
@ -150,6 +239,10 @@ const appStore = new AppStore(
apiRepositoriesStore
)
appStore.onDidUpdate(state => {
currentState = state
})
const dispatcher = new Dispatcher(
appStore,
repositoryStateManager,

View file

@ -7,13 +7,12 @@ import { IMenuItem } from '../../lib/menu-item'
import { HighlightText } from '../lib/highlight-text'
import { IMatches } from '../../lib/fuzzy-find'
import { IAheadBehind } from '../../models/branch'
import { RevealInFileManagerLabel } from '../lib/context-menu'
import {
RevealInFileManagerLabel,
DefaultEditorLabel,
} from '../lib/context-menu'
import { enableGroupRepositoriesByOwner } from '../../lib/feature-flag'
const defaultEditorLabel = __DARWIN__
? 'Open in External Editor'
: 'Open in external editor'
interface IRepositoryListItemProps {
readonly repository: Repositoryish
@ -137,7 +136,7 @@ export class RepositoryListItem extends React.Component<
const missing = repository instanceof Repository && repository.missing
const openInExternalEditor = this.props.externalEditorLabel
? `Open in ${this.props.externalEditorLabel}`
: defaultEditorLabel
: DefaultEditorLabel
const items: ReadonlyArray<IMenuItem> = [
{

View file

@ -5,7 +5,7 @@ import {
createBranch,
checkoutBranch,
renameBranch,
getCheckoutsAfterDate,
getBranchCheckouts,
} from '../../../src/lib/git'
import { setupFixtureRepository } from '../../helpers/repositories'
import * as moment from 'moment'
@ -75,7 +75,7 @@ describe('git/reflog', () => {
await createAndCheckout(repository, 'branch-1')
await createAndCheckout(repository, 'branch-2')
const branches = await getCheckoutsAfterDate(
const branches = await getBranchCheckouts(
repository,
moment()
.add(1, 'day')
@ -89,7 +89,7 @@ describe('git/reflog', () => {
await createAndCheckout(repository, 'branch-1')
await createAndCheckout(repository, 'branch-2')
const branches = await getCheckoutsAfterDate(
const branches = await getBranchCheckouts(
repository,
moment()
.subtract(1, 'hour')

View file

@ -1,5 +1,64 @@
{
"releases": {
"2.0.4-beta0": [
"[Added] Extend crash reports with more information about application state for troubleshooting - #7693",
"[Fixed] Crash when attempting to update pull requests with partially updated repository information - #7688",
"[Fixed] Crash when loading repositories after signing in through the welcome flow - #7699"
],
"2.0.3": [
"[Fixed] Crash when loading repositories after signing in through the welcome flow - #7699"
],
"2.0.2": [
"[Added] Extend crash reports with more information about application state for troubleshooting - #7693"
],
"2.0.1": [
"[Fixed] Crash when attempting to update pull requests with partially updated repository information - #7688"
],
"2.0.0": [
"[New] You can now choose to bring your changes with you to a new branch or stash them on the current branch when switching branches - #6107",
"[New] Rebase your current branch onto another branch using a guided flow - #5953",
"[New] Repositories grouped by owner, and recent repositories listed at top - #6923 #7132",
"[New] Suggested next steps now includes suggestion to create a pull request after publishing a branch - #7505",
"[Added] .resx syntax highlighting - #7235. Thanks @say25!",
"[Added] \"Exit\" menu item now has accelerator and access key - #6507. Thanks @AndreiMaga!",
"[Added] Help menu entry to view documentation about keyboard shortcuts - #7184",
"[Added] \"Discard all changes\" action under Branch menu - #7394. Thanks @ahuth!",
"[Fixed] \"Esc\" key does not close Repository or Branch list - #7177. Thanks @roottool!",
"[Fixed] Attempting to revert commits not on current branch results in an error - #6300. Thanks @msftrncs!",
"[Fixed] Emoji rendering in app when account name has special characters - #6909",
"[Fixed] Files staged outside Desktop for deletion are incorrectly marked as modified after committing - #4133",
"[Fixed] Horizontal scroll bar appears unnecessarily when switching branches - #7212",
"[Fixed] Icon accessibility labels fail when multiple icons are visible at the same time - #7174",
"[Fixed] Incorrectly encoding URLs affects issue filtering - #7506",
"[Fixed] License templates do not end with newline character - #6999",
"[Fixed] Conflicts banners do not hide after aborting operation outside Desktop - #7046",
"[Fixed] Missing tooltips for change indicators in the sidebar - #7174",
"[Fixed] Mistaken classification of all crashes being related to launch - #7126",
"[Fixed] Unable to switch keyboard layout and retain keyboard focus while using commit form - #6366. Thanks @AndreiMaga!",
"[Fixed] Prevent console errors due to underlying component unmounts - #6970",
"[Fixed] Menus disabled by activity in inactive repositories - #6313",
"[Fixed] Race condition with Git remote lookup may cause push to incorrect remote - #6986",
"[Fixed] Restore GitHub Desktop to main screen if external monitor removed - #7418 #2107. Thanks @say25!",
"[Fixed] Tab Bar focus ring outlines clip into other elements - #5802. Thanks @Daniel-McCarthy!",
"[Improved] \"Automatically Switch Theme\" on macOS checks theme on launch - #7116. Thanks @say25!",
"[Improved] \"Add\" button in repository list should always be visible - #6646",
"[Improved] Pull Requests list loads and updates pull requests from GitHub more quickly - #7501 #7163",
"[Improved] Indicator hidden in Pull Requests list when there are no open pull requests - #7258",
"[Improved] Manually refresh pull requests instead of having to wait for a fetch - #7027",
"[Improved] Accessibility attributes for dialog - #6496. Thanks @HirdayGupta!",
"[Improved] Alignment of icons in repository list - #7133",
"[Improved] Command line interface warning when using \"github open\" with a remote URL - #7452. Thanks @msztech!",
"[Improved] Error message when unable to publish private repository to an organization - #7472",
"[Improved] Initiate cloning by pressing \"Enter\" when a repository is selected - #6570. Thanks @Daniel-McCarthy!",
"[Improved] Lowercase pronoun in \"Revert this commit\" menu item - #7534",
"[Improved] Styles for manual resolution button in \"Resolve Conflicts\" dialog - #7302",
"[Improved] Onboarding language for blank slate components - #6638. Thanks @jamesgeorge007!",
"[Improved] Explanation for manually conflicted text files in diff viewer - #7611",
"[Improved] Visual progress on \"Remove Repository\" and \"Discard Changes\" dialogs - #7015. Thanks @HashimotoYT!",
"[Improved] Menu items now aware of force push state and preference to confirm repository removal - #4976 #7138",
"[Removed] Branch and pull request filter text persistence - #7437",
"[Removed] \"Discard all changes\" context menu item from Changes list - #7394. Thanks @ahuth!"
],
"1.7.1-beta1": [
"[Fixed] Tab Bar focus ring outlines clip into other elements - #5802. Thanks @Daniel-McCarthy!",
"[Improved] Show explanation for manually conflicted text files in diff viewer - #7611",

View file

@ -1,13 +1,13 @@
### Download Desktop
- [ ] User can download latest (Mac & Windows) Desktop from https://desktop.github.com/
- [ ] Mac: https://central.github.com/deployments/desktop/desktop/latest/darwin
- [ ] [User can download latest (Mac & Windows) Desktop](https://desktop.github.com/)
- [ ] [Mac](https://central.github.com/deployments/desktop/desktop/latest/darwin)
- [ ] Homebrew package manager: `brew cask install github-desktop`
- [ ] Windows: https://central.github.com/deployments/desktop/desktop/latest/win32
- [ ] [Windows](https://central.github.com/deployments/desktop/desktop/latest/win32)
- [ ] Chocolatey package manager: `choco install github-desktop`
- [ ] 64-bit and up
- [ ] Data is retained if you download and open a fresh copy
- [ ] Release notes page is up-to-date in app and here https://desktop.github.com/release-notes/
- [ ] Help page is accessible https://help.github.com/desktop/
- [ ] Release notes page is up-to-date in app and can be accessed from [here](https://desktop.github.com/release-notes/)
- [ ] [Help page](https://help.github.com/desktop/) is accessible
- [ ] 'Please update' notification shown in Classic apps
### Welcome Flow

View file

@ -51,7 +51,7 @@
},
"license": "MIT",
"engines": {
"node": ">= 8.11 < 12.0.0",
"node": ">= 8.11",
"yarn": ">= 1.9"
},
"dependencies": {
@ -91,7 +91,7 @@
"klaw-sync": "^3.0.0",
"legal-eagle": "0.16.0",
"mini-css-extract-plugin": "^0.4.0",
"node-sass": "^4.11.0",
"node-sass": "^4.12.0",
"octicons": "^8.2.0",
"parallel-webpack": "^2.3.0",
"prettier": "1.16.0",

View file

@ -6310,16 +6310,11 @@ lodash._reinterpolate@~3.0.0:
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
lodash.assign@^4.0.8, lodash.assign@^4.2.0:
lodash.assign@^4.0.8:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7"
integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=
lodash.clonedeep@^4.3.2:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
lodash.endswith@^4.0.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/lodash.endswith/-/lodash.endswith-4.2.1.tgz#fed59ac1738ed3e236edd7064ec456448b37bc09"
@ -6340,11 +6335,6 @@ lodash.isplainobject@^4.0.6:
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
lodash.mergewith@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz#150cf0a16791f5903b8891eab154609274bdea55"
integrity sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU=
lodash.some@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"
@ -6826,10 +6816,10 @@ mute-stream@0.0.7:
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
nan@^2.10.0:
version "2.11.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.0.tgz#574e360e4d954ab16966ec102c0c049fd961a099"
integrity sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw==
nan@^2.13.2:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
nan@^2.9.2:
version "2.10.0"
@ -7009,10 +6999,10 @@ node-pre-gyp@^0.9.0:
semver "^5.3.0"
tar "^4"
node-sass@^4.11.0:
version "4.11.0"
resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.11.0.tgz#183faec398e9cbe93ba43362e2768ca988a6369a"
integrity sha512-bHUdHTphgQJZaF1LASx0kAviPH7sGlcyNhWade4eVIpFp6tsn7SV8xNMTbsQFpEV9VXpnwTTnNYlfsZXgGgmkA==
node-sass@^4.12.0:
version "4.12.0"
resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.12.0.tgz#0914f531932380114a30cc5fa4fa63233a25f017"
integrity sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ==
dependencies:
async-foreach "^0.1.3"
chalk "^1.1.1"
@ -7021,12 +7011,10 @@ node-sass@^4.11.0:
get-stdin "^4.0.1"
glob "^7.0.3"
in-publish "^2.0.0"
lodash.assign "^4.2.0"
lodash.clonedeep "^4.3.2"
lodash.mergewith "^4.6.0"
lodash "^4.17.11"
meow "^3.7.0"
mkdirp "^0.5.1"
nan "^2.10.0"
nan "^2.13.2"
node-gyp "^3.8.0"
npmlog "^4.0.0"
request "^2.88.0"