[MM-42538] Submit nightly builds to TestFlight for macOS (#2023)
* Initial MAS build, working on TestFlight * Migration of old configs to MAS * Ignore fastlane files * Add mac app store build to nightly build * Revert Me - For testing in PR * Don't need to install fastlane * BIG D * Fix patch updater script to allow for no yml * Nevermind, do this instead * Update xcode * Let's try a fake version that works * Revert version and rename for test flight * Use Xcode 13.0.0 * Use CircleCI build number when available * Revert testing changes * Remove notarize for MAS * Change vars to MACOS instead of IOS * Revert electron-builder to v22 * Revert package-lock.json Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
This commit is contained in:
parent
bc7f82fbf3
commit
0a7be91576
|
@ -28,7 +28,7 @@ executors:
|
|||
mac:
|
||||
working_directory: ~/mattermost-desktop
|
||||
macos:
|
||||
xcode: "10.3.0"
|
||||
xcode: "13.0.0"
|
||||
aws:
|
||||
working_directory: ~/mattermost-desktop
|
||||
docker:
|
||||
|
@ -352,6 +352,34 @@ jobs:
|
|||
paths:
|
||||
- "./macos-release/"
|
||||
|
||||
mac_app_store_testflight:
|
||||
executor: mac
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
- run: mkdir -p ./build
|
||||
- attach_workspace:
|
||||
at: ./build
|
||||
- run:
|
||||
name: Update node to v16
|
||||
command: brew upgrade node || true
|
||||
- run:
|
||||
name: Install yq
|
||||
command: brew install yq
|
||||
- run:
|
||||
name: Installing npm dependencies
|
||||
command: npm ci
|
||||
- run:
|
||||
name: Copy provisioning profile
|
||||
command: echo $MAS_PROFILE | base64 -D > ./mas.provisionprofile
|
||||
- run:
|
||||
name: Patch version number for MAS
|
||||
command: ./scripts/patch_mas_version.sh
|
||||
- run: npm run package:mas
|
||||
- run:
|
||||
name: 'Upload to App Store Connect'
|
||||
command: fastlane publish_test path:"$(find . -name \*.pkg -print -quit)"
|
||||
|
||||
store_artifacts:
|
||||
executor: wine-chrome
|
||||
steps:
|
||||
|
@ -596,6 +624,7 @@ workflows:
|
|||
# release-XX.YY.ZZ
|
||||
# release-XX.YY.ZZ-rc-something
|
||||
- /^release-\d+(\.\d+){1,2}(-rc.*)?/
|
||||
|
||||
build-for-pr:
|
||||
jobs:
|
||||
- build-windows-pr:
|
||||
|
@ -620,6 +649,8 @@ workflows:
|
|||
context: windows-codesign
|
||||
- mac_installer:
|
||||
context: codesign-certificates
|
||||
- mac_app_store_testflight:
|
||||
context: desktop-mac-app-store
|
||||
- store_artifacts:
|
||||
context: desktop_browserview
|
||||
# for master/PR builds
|
||||
|
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -17,3 +17,8 @@ test_config.json
|
|||
testUserData
|
||||
|
||||
.gitattributes
|
||||
|
||||
fastlane/README.md
|
||||
fastlane/report.xml
|
||||
|
||||
*.provisionprofile
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
{
|
||||
"publish": [{
|
||||
"publish": [
|
||||
{
|
||||
"provider": "generic",
|
||||
"url": "https://releases.mattermost.com/desktop"
|
||||
}],
|
||||
}
|
||||
],
|
||||
"appId": "Mattermost.Desktop",
|
||||
"artifactName": "${version}/${name}-${version}-${os}-${arch}.${ext}",
|
||||
"directories": {
|
||||
|
@ -39,7 +41,13 @@
|
|||
"deb": {
|
||||
"artifactName": "${version}/${name}_${version}-1_${arch}.${ext}",
|
||||
"synopsis": "Mattermost Desktop App",
|
||||
"depends": ["gconf2", "gconf-service", "libnotify4", "libxtst6", "libnss3"],
|
||||
"depends": [
|
||||
"gconf2",
|
||||
"gconf-service",
|
||||
"libnotify4",
|
||||
"libxtst6",
|
||||
"libnss3"
|
||||
],
|
||||
"category": "contrib/net",
|
||||
"priority": "optional"
|
||||
},
|
||||
|
@ -93,6 +101,19 @@
|
|||
"LSFileQuarantineEnabled": true
|
||||
}
|
||||
},
|
||||
"mas": {
|
||||
"hardenedRuntime": false,
|
||||
"entitlements": "./entitlements.mas.plist",
|
||||
"entitlementsInherit": "./entitlements.mas.inherit.plist",
|
||||
"entitlementsLoginHelper": "./entitlements.mas.inherit.plist",
|
||||
"provisioningProfile": "./mas.provisionprofile",
|
||||
"extendInfo": {
|
||||
"ITSAppUsesNonExemptEncryption": false
|
||||
}
|
||||
},
|
||||
"masDev": {
|
||||
"provisioningProfile": "./mas-dev.provisionprofile"
|
||||
},
|
||||
"dmg": {
|
||||
"background": "src/assets/osx/DMG_BG.png",
|
||||
"contents": [
|
||||
|
|
10
entitlements.mas.inherit.plist
Normal file
10
entitlements.mas.inherit.plist
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.security.inherit</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
36
entitlements.mas.plist
Normal file
36
entitlements.mas.plist
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.device.microphone</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.camera</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.audio-input</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.server</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.user-selected.read-only</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.user-selected.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>UQ8HT4Q2XM.Mattermost.Desktop</string>
|
||||
</array>
|
||||
<key>com.apple.application-identifier</key>
|
||||
<string>UQ8HT4Q2XM.Mattermost.Desktop</string>
|
||||
<key>com.apple.developer.team-identifier</key>
|
||||
<string>UQ8HT4Q2XM</string>
|
||||
</dict>
|
||||
</plist>
|
35
fastlane/Fastfile
Normal file
35
fastlane/Fastfile
Normal file
|
@ -0,0 +1,35 @@
|
|||
fastlane_version '2.71.0'
|
||||
fastlane_require 'aws-sdk-s3'
|
||||
fastlane_require 'erb'
|
||||
fastlane_require 'json'
|
||||
fastlane_require 'pathname'
|
||||
|
||||
lane :publish_test do |options|
|
||||
api_key = ''
|
||||
unless ENV['MACOS_API_KEY_ID'].nil? || ENV['MACOS_API_KEY_ID'].empty? ||
|
||||
ENV['MACOS_API_ISSUER_ID'].nil? || ENV['MACOS_API_ISSUER_ID'].empty? ||
|
||||
ENV['MACOS_API_KEY'].nil? || ENV['MACOS_API_KEY'].empty?
|
||||
api_key_path = "#{ENV['MACOS_API_KEY_ID']}.p8"
|
||||
File.open("../#{api_key_path}", 'w') do |f|
|
||||
key_string = ENV['MACOS_API_KEY']
|
||||
p8_array = key_string.split('\n')
|
||||
p8_array.each_with_index do |value, index|
|
||||
f.write(value)
|
||||
f.write("\n") unless index == p8_array.length - 1
|
||||
end
|
||||
end
|
||||
|
||||
api_key = app_store_connect_api_key(
|
||||
key_id: ENV['MACOS_API_KEY_ID'],
|
||||
issuer_id: ENV['MACOS_API_ISSUER_ID'],
|
||||
key_filepath: "./#{api_key_path}",
|
||||
in_house: ENV['MACOS_IN_HOUSE'] == 'true', # optional but may be required if using match/sigh
|
||||
)
|
||||
|
||||
File.delete("../#{api_key_path}")
|
||||
end
|
||||
pilot(
|
||||
pkg: options[:path],
|
||||
api_key: api_key
|
||||
)
|
||||
end
|
|
@ -50,6 +50,8 @@
|
|||
"package:windows": "cross-env NODE_ENV=production npm-run-all check-build-config build && electron-builder --win --x64 --ia32 --publish=never",
|
||||
"package:mac": "cross-env NODE_ENV=production npm-run-all check-build-config build && electron-builder --mac --x64 --arm64 --publish=never",
|
||||
"package:mac-with-universal": "cross-env NODE_ENV=production npm-run-all check-build-config build && electron-builder --mac --x64 --arm64 --universal --publish=never",
|
||||
"package:mas": "cross-env NODE_ENV=production IS_MAC_APP_STORE=true npm-run-all check-build-config build && electron-builder --mac mas --universal --publish=never",
|
||||
"package:mas-dev": "cross-env NODE_ENV=production IS_MAC_APP_STORE=true npm-run-all check-build-config build && electron-builder --mac mas-dev --universal --publish=never",
|
||||
"package:linux": "cross-env NODE_ENV=production npm-run-all check-build-config build && electron-builder --linux --x64 --ia32 --publish=never",
|
||||
"lint:js": "eslint --ignore-path .gitignore --ignore-pattern node_modules --ext .js --ext .jsx --ext .ts --ext .tsx .",
|
||||
"lint:js-quiet": "eslint --ignore-path .gitignore --ignore-pattern node_modules --ext .js --ext .jsx --ext .ts --ext .tsx . --quiet",
|
||||
|
@ -83,7 +85,8 @@
|
|||
"globals": {
|
||||
"__HASH_VERSION__": "5.0.0",
|
||||
"__CAN_UPGRADE__": false,
|
||||
"__IS_NIGHTLY_BUILD__": false
|
||||
"__IS_NIGHTLY_BUILD__": false,
|
||||
"__IS_MAC_APP_STORE__": false
|
||||
},
|
||||
"setupFiles": [
|
||||
"./src/jestSetup.js"
|
||||
|
|
|
@ -27,6 +27,7 @@ function getAppFileName(context) {
|
|||
case 'win32':
|
||||
return 'Mattermost.exe';
|
||||
case 'darwin':
|
||||
case 'mas':
|
||||
return 'Mattermost.app';
|
||||
case 'linux':
|
||||
return context.packager.executableName;
|
||||
|
|
|
@ -9,6 +9,7 @@ const config = require('../electron-builder.json');
|
|||
|
||||
exports.default = async function notarizing(context) {
|
||||
const {electronPlatformName, appOutDir} = context;
|
||||
|
||||
if (electronPlatformName !== 'darwin' || process.platform !== 'darwin') {
|
||||
return;
|
||||
}
|
||||
|
|
18
scripts/patch_mas_version.sh
Executable file
18
scripts/patch_mas_version.sh
Executable file
|
@ -0,0 +1,18 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
STABLE_VERSION=$(./node_modules/.bin/semver $(jq -r .version package.json) -c)
|
||||
BUILD_VERSION=$(jq -r .version package.json | sed "s/$STABLE_VERSION-.*\.//g")
|
||||
|
||||
if [ "$BUILD_VERSION" == "" ]; then
|
||||
BUILD_VERSION=$STABLE_VERSION
|
||||
fi
|
||||
|
||||
if [ "$CIRCLE_BUILD_NUM" != "" ]; then
|
||||
BUILD_VERSION=$CIRCLE_BUILD_NUM
|
||||
fi
|
||||
|
||||
temp_file="$(mktemp -t electron-builder.json)"
|
||||
jq -r --arg version "$STABLE_VERSION" '.mac.bundleShortVersion = $version' electron-builder.json > "${temp_file}" && mv "${temp_file}" electron-builder.json
|
||||
jq -r --arg version "$BUILD_VERSION" '.mac.bundleVersion = $version' electron-builder.json > "${temp_file}" && mv "${temp_file}" electron-builder.json
|
Binary file not shown.
|
@ -91,6 +91,7 @@ import {
|
|||
updateSpellCheckerLocales,
|
||||
wasUpdated,
|
||||
initCookieManager,
|
||||
migrateMacAppStore,
|
||||
} from './utils';
|
||||
|
||||
export const mainProtocol = protocols?.[0]?.schemes?.[0];
|
||||
|
@ -118,6 +119,13 @@ export async function initialize() {
|
|||
return;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
if (__IS_MAC_APP_STORE__) {
|
||||
migrateMacAppStore();
|
||||
}
|
||||
|
||||
// initialization that should run once the app is ready
|
||||
initializeInterCommunicationEventListeners();
|
||||
initializeAfterAppReady();
|
||||
|
@ -198,10 +206,15 @@ function initializeBeforeAppReady() {
|
|||
refreshTrayImages(Config.trayIconTheme);
|
||||
|
||||
// If there is already an instance, quit this one
|
||||
const gotTheLock = app.requestSingleInstanceLock();
|
||||
if (!gotTheLock) {
|
||||
app.exit();
|
||||
global.willAppQuit = true;
|
||||
// eslint-disable-next-line no-undef
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
if (!__IS_MAC_APP_STORE__) {
|
||||
const gotTheLock = app.requestSingleInstanceLock();
|
||||
if (!gotTheLock) {
|
||||
app.exit();
|
||||
global.willAppQuit = true;
|
||||
}
|
||||
}
|
||||
|
||||
AllowProtocolDialog.init();
|
||||
|
|
|
@ -1,27 +1,58 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import fs from 'fs';
|
||||
|
||||
import {dialog} from 'electron';
|
||||
|
||||
import Config from 'common/config';
|
||||
import JsonFileManager from 'common/JsonFileManager';
|
||||
import {TAB_MESSAGING, TAB_FOCALBOARD, TAB_PLAYBOOKS} from 'common/tabs/TabView';
|
||||
import Utils from 'common/utils/util';
|
||||
|
||||
import {updatePaths} from 'main/constants';
|
||||
import {ServerInfo} from 'main/server/serverInfo';
|
||||
|
||||
import {getDeeplinkingURL, updateServerInfos, resizeScreen} from './utils';
|
||||
import {getDeeplinkingURL, updateServerInfos, resizeScreen, migrateMacAppStore} from './utils';
|
||||
|
||||
jest.mock('fs', () => ({
|
||||
readFileSync: jest.fn(),
|
||||
writeFileSync: jest.fn(),
|
||||
existsSync: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('electron', () => ({
|
||||
app: {
|
||||
getPath: () => '/path/to/data',
|
||||
getAppPath: () => '/path/to/app',
|
||||
},
|
||||
nativeImage: {
|
||||
createFromPath: jest.fn(),
|
||||
},
|
||||
dialog: {
|
||||
showOpenDialogSync: jest.fn(),
|
||||
showMessageBoxSync: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('electron-log', () => ({
|
||||
info: jest.fn(),
|
||||
error: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('common/config', () => ({
|
||||
set: jest.fn(),
|
||||
}));
|
||||
jest.mock('common/JsonFileManager');
|
||||
jest.mock('common/utils/util', () => ({
|
||||
isVersionGreaterThanOrEqualTo: jest.fn(),
|
||||
getDisplayBoundaries: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('main/autoUpdater', () => ({}));
|
||||
jest.mock('main/constants', () => ({
|
||||
updatePaths: jest.fn(),
|
||||
}));
|
||||
jest.mock('main/menus/app', () => ({}));
|
||||
jest.mock('main/menus/tray', () => ({}));
|
||||
jest.mock('main/server/serverInfo', () => ({
|
||||
|
@ -190,4 +221,73 @@ describe('main/app/utils', () => {
|
|||
expect(browserWindow.center).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('migrateMacAppStore', () => {
|
||||
it('should skip migration if already migrated', () => {
|
||||
JsonFileManager.mockImplementation(() => ({
|
||||
getValue: () => true,
|
||||
}));
|
||||
migrateMacAppStore();
|
||||
expect(dialog.showMessageBoxSync).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should skip migration if folder does not exist', () => {
|
||||
JsonFileManager.mockImplementation(() => ({
|
||||
getValue: () => false,
|
||||
}));
|
||||
fs.existsSync.mockReturnValue(false);
|
||||
migrateMacAppStore();
|
||||
expect(fs.existsSync).toHaveBeenCalled();
|
||||
expect(dialog.showMessageBoxSync).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should skip migration and set value if the user rejects import', () => {
|
||||
const migrationPrefs = {
|
||||
getValue: () => false,
|
||||
setValue: jest.fn(),
|
||||
};
|
||||
JsonFileManager.mockImplementation(() => migrationPrefs);
|
||||
fs.existsSync.mockReturnValue(true);
|
||||
dialog.showMessageBoxSync.mockReturnValue(1);
|
||||
migrateMacAppStore();
|
||||
expect(migrationPrefs.setValue).toHaveBeenCalledWith('masConfigs', true);
|
||||
expect(dialog.showOpenDialogSync).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should do nothing if no directory is chosen, or if the dialog is closed', () => {
|
||||
JsonFileManager.mockImplementation(() => ({
|
||||
getValue: () => false,
|
||||
}));
|
||||
fs.existsSync.mockReturnValue(true);
|
||||
dialog.showMessageBoxSync.mockReturnValue(0);
|
||||
dialog.showOpenDialogSync.mockReturnValue([]);
|
||||
migrateMacAppStore();
|
||||
expect(dialog.showOpenDialogSync).toHaveBeenCalled();
|
||||
expect(updatePaths).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should copy all of the configs when they exist to the new directory', () => {
|
||||
const migrationPrefs = {
|
||||
getValue: () => false,
|
||||
setValue: jest.fn(),
|
||||
};
|
||||
JsonFileManager.mockImplementation(() => migrationPrefs);
|
||||
fs.readFileSync.mockReturnValue('config-data');
|
||||
fs.existsSync.mockImplementation((path) => {
|
||||
if (path === '/Library/Application Support/Mattermost') {
|
||||
return true;
|
||||
}
|
||||
return ['config', 'app-state', 'bounds-info', 'migration-info'].some((filename) => path.endsWith(`${filename}.json`));
|
||||
});
|
||||
dialog.showMessageBoxSync.mockReturnValue(0);
|
||||
dialog.showOpenDialogSync.mockReturnValue(['/old/data/path']);
|
||||
migrateMacAppStore();
|
||||
expect(fs.readFileSync).toHaveBeenCalledWith('/old/data/path/config.json');
|
||||
expect(fs.writeFileSync).toHaveBeenCalledWith('/path/to/data/config.json', 'config-data');
|
||||
expect(fs.readFileSync).not.toHaveBeenCalledWith('/old/data/path/allowedProtocols.json');
|
||||
expect(fs.writeFileSync).not.toHaveBeenCalledWith('/path/to/data/allowedProtocols.json', 'config-data');
|
||||
expect(updatePaths).toHaveBeenCalled();
|
||||
expect(migrationPrefs.setValue).toHaveBeenCalledWith('masConfigs', true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,20 +1,26 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {app, BrowserWindow, Menu, Rectangle, Session, session} from 'electron';
|
||||
import fs from 'fs';
|
||||
|
||||
import path from 'path';
|
||||
|
||||
import {app, BrowserWindow, Menu, Rectangle, Session, session, dialog, nativeImage} from 'electron';
|
||||
import log from 'electron-log';
|
||||
|
||||
import {TeamWithTabs} from 'types/config';
|
||||
import {MigrationInfo, TeamWithTabs} from 'types/config';
|
||||
import {RemoteInfo} from 'types/server';
|
||||
import {Boundaries} from 'types/utils';
|
||||
|
||||
import Config from 'common/config';
|
||||
import JsonFileManager from 'common/JsonFileManager';
|
||||
import {MattermostServer} from 'common/servers/MattermostServer';
|
||||
import {TAB_FOCALBOARD, TAB_MESSAGING, TAB_PLAYBOOKS} from 'common/tabs/TabView';
|
||||
import urlUtils from 'common/utils/url';
|
||||
import Utils from 'common/utils/util';
|
||||
|
||||
import updateManager from 'main/autoUpdater';
|
||||
import {migrationInfoPath, updatePaths} from 'main/constants';
|
||||
import {createMenu as createAppMenu} from 'main/menus/app';
|
||||
import {createMenu as createTrayMenu} from 'main/menus/tray';
|
||||
import {ServerInfo} from 'main/server/serverInfo';
|
||||
|
@ -23,6 +29,12 @@ import WindowManager from 'main/windows/windowManager';
|
|||
|
||||
import {mainProtocol} from './initialize';
|
||||
|
||||
const configFileNames = ['config', 'allowedProtocols', 'app-state', 'certificate', 'trustedOrigins', 'bounds-info', 'migration-info'];
|
||||
|
||||
const assetsDir = path.resolve(app.getAppPath(), 'assets');
|
||||
const appIconURL = path.resolve(assetsDir, 'appicon_with_spacing_32.png');
|
||||
const appIcon = nativeImage.createFromPath(appIconURL);
|
||||
|
||||
export function openDeepLink(deeplinkingUrl: string) {
|
||||
try {
|
||||
WindowManager.showMainWindow(deeplinkingUrl);
|
||||
|
@ -177,3 +189,62 @@ export function initCookieManager(session: Session) {
|
|||
flushCookiesStore(session);
|
||||
});
|
||||
}
|
||||
|
||||
export function migrateMacAppStore() {
|
||||
const migrationPrefs = new JsonFileManager<MigrationInfo>(migrationInfoPath);
|
||||
const oldPath = path.join(app.getPath('userData'), '../../../../../../../Library/Application Support/Mattermost');
|
||||
|
||||
// Check if we've already migrated
|
||||
if (migrationPrefs.getValue('masConfigs')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the files are there to migrate
|
||||
try {
|
||||
const exists = fs.existsSync(oldPath);
|
||||
if (!exists) {
|
||||
log.info('MAS: No files to migrate, skipping');
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
log.error('MAS: Failed to check for existing Mattermost Desktop install, skipping', e);
|
||||
return;
|
||||
}
|
||||
|
||||
const cancelImport = dialog.showMessageBoxSync({
|
||||
title: 'Mattermost',
|
||||
message: 'Import Existing Configuration',
|
||||
detail: 'It appears that an existing Mattermost configuration exists, would you like to import it? You will be asked to pick the correct configuration directory.',
|
||||
icon: appIcon,
|
||||
buttons: ['Select Directory and Import', 'Don\'t Import'],
|
||||
type: 'info',
|
||||
defaultId: 0,
|
||||
cancelId: 1,
|
||||
});
|
||||
|
||||
if (cancelImport) {
|
||||
migrationPrefs.setValue('masConfigs', true);
|
||||
return;
|
||||
}
|
||||
|
||||
const result = dialog.showOpenDialogSync({
|
||||
defaultPath: oldPath,
|
||||
properties: ['openDirectory'],
|
||||
});
|
||||
if (!(result && result[0])) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
for (const fileName of configFileNames) {
|
||||
if (fs.existsSync(path.resolve(result[0], `${fileName}.json`))) {
|
||||
const contents = fs.readFileSync(path.resolve(result[0], `${fileName}.json`));
|
||||
fs.writeFileSync(path.resolve(app.getPath('userData'), `${fileName}.json`), contents);
|
||||
}
|
||||
}
|
||||
updatePaths(true);
|
||||
migrationPrefs.setValue('masConfigs', true);
|
||||
} catch (e) {
|
||||
log.error('MAS: An error occurred importing the existing configuration', e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,4 +126,5 @@ export type LocalConfiguration = Config & {
|
|||
|
||||
export type MigrationInfo = {
|
||||
updateTrayIconWin32: boolean;
|
||||
masConfigs: boolean;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ const codeDefinitions = {
|
|||
__HASH_VERSION__: !isRelease && JSON.stringify(VERSION),
|
||||
__CAN_UPGRADE__: JSON.stringify(true), // we should set this to false when working on a store version. Hardcoding for now.
|
||||
__IS_NIGHTLY_BUILD__: JSON.stringify(process.env.CIRCLE_BRANCH === 'nightly'),
|
||||
__IS_MAC_APP_STORE__: JSON.stringify(process.env.IS_MAC_APP_STORE === 'true'),
|
||||
};
|
||||
codeDefinitions['process.env.NODE_ENV'] = JSON.stringify(process.env.NODE_ENV);
|
||||
|
||||
|
|
Loading…
Reference in a new issue