Add msi, gpo, new CI and runtime/sandbox hardening

* Add msi installer via Wixtoolset
* Add PowerShell Makefile
* [MM-18135] merge lint and test step, use -quiet, clarify changing debugging port
* [MM-18135] use no sandbox, separate linting, circle 2.1
* [MM-18137] Add MSI installer job
* [MM-18137] Add windows signing
* [MM-18152] Desktop notifications (#1040)
* [MM-18345] use non-dangerous wix version
* [MM-18348] add code signing to windows build (#1044)
* [MM-18348] fix review comments
* [MM-18851] runtime/sandbox hardening (#1042)
* [MM-18906] remove GPU acceleration option from GPO settings (#1047)
* Other minor refinements
This commit is contained in:
William Gathoye 2019-10-01 14:10:25 +02:00 committed by GitHub
parent 4d7f5ab417
commit a5368a9587
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 2282 additions and 68 deletions

View file

@ -1,13 +1,21 @@
version: 2.1
orbs:
win: circleci/windows@1.0.0
executors:
wine-chrome:
working_directory: ~/mattermost-desktop
docker:
- image: electronuserland/builder:wine-chrome
environment:
TAR_OPTIONS: --no-same-owner
wine-mono:
working_directory: ~/mattermost-desktop
docker:
- image: electronuserland/builder:wine-mono
mac:
working_directory: ~/mattermost-desktop
macos:
xcode: "10.3.0"
commands:
update_image:
description: "Update base image"
@ -19,9 +27,41 @@ commands:
- run: apt-get update && apt-get -y install << parameters.apt_opts >>
- run: npm install
win_make:
description: "Run mattermost's makefile.ps1 on ./scripts/"
parameters:
operation:
type: string
default: ""
steps:
- run:
command: ./scripts/Makefile.ps1 << parameters.operation >>
name: << parameters.operation >>
shell: powershell
build:
description: "Building << parameters.os >> app"
parameters:
os:
type: string
default: "linux"
path:
type: string
default: "./dist/linux"
subpath:
type: string
default: "./linux/"
steps:
- run: npm run build
- run: npm run package:<< parameters.os >>
- run: mkdir -p << parameters.path >>
- run: bash -x ./scripts/cp_artifacts.sh release << parameters.path >>
- persist_to_workspace:
root: ./dist
paths:
- "./<< parameters.subpath >>/"
jobs:
check:
executor: wine-chrome
executor: wine-chrome
steps:
- checkout
- update_image:
@ -40,23 +80,20 @@ jobs:
- "node_modules"
- "src/node_modules"
build:
build-linux:
executor: wine-mono
steps:
- checkout
- run: mkdir -p ./dist
- attach_workspace:
at: ./dist
- restore_cache:
key: npm-{{ arch }}-{{ .Branch }}-{{ checksum "package-lock.json" }}
- restore_cache:
key: npm-{{ arch }}-{{ .Branch }}-{{ checksum "src/package-lock.json" }}
- update_image:
apt_opts: "--no-install-recommends jq icnsutils graphicsmagick tzdata"
- run: npm run build
- run: npm run package:windows
- run: jq '.mac.target=["zip"]' electron-builder.json > /tmp/electron-builder.json && cp /tmp/electron-builder.json .
- run: npm run package:mac
- run: npm run package:linux
- run: mkdir -p /tmp/artifacts
- run: sh -x ./scripts/cp_artifacts.sh release /tmp/artifacts
- build
- save_cache:
key: npm-{{ arch }}-{{ .Branch }}-{{ checksum "package-lock.json" }}
paths:
@ -67,19 +104,173 @@ jobs:
key: npm-{{ arch }}-{{ .Branch }}-{{ checksum "src/package-lock.json" }}
paths:
- "src/node_modules"
build-win-no-installer:
executor: wine-mono
steps:
- checkout
- run: mkdir -p ./dist
- attach_workspace:
at: ./dist
- restore_cache:
key: npm-{{ arch }}-{{ .Branch }}-{{ checksum "package-lock.json" }}
- restore_cache:
key: npm-{{ arch }}-{{ .Branch }}-{{ checksum "src/package-lock.json" }}
- update_image:
apt_opts: "--no-install-recommends jq icnsutils graphicsmagick tzdata"
- build:
os: windows
path: ./dist/win
subpath: ./win/
- save_cache:
key: npm-{{ arch }}-{{ .Branch }}-{{ checksum "package-lock.json" }}
paths:
- "node_modules"
- "~/.cache/electron"
- "~/.cache/electron-builder"
- save_cache:
key: npm-{{ arch }}-{{ .Branch }}-{{ checksum "src/package-lock.json" }}
paths:
- "src/node_modules"
build-mac-no-dmg:
executor: wine-mono
steps:
- checkout
- run: mkdir -p ./dist
- attach_workspace:
at: ./dist
- restore_cache:
key: npm-{{ arch }}-{{ .Branch }}-{{ checksum "package-lock.json" }}
- restore_cache:
key: npm-{{ arch }}-{{ .Branch }}-{{ checksum "src/package-lock.json" }}
- update_image:
apt_opts: "--no-install-recommends jq icnsutils graphicsmagick tzdata"
- run: jq '.mac.target=["zip"]' electron-builder.json > /tmp/electron-builder.json && cp /tmp/electron-builder.json .
- build:
os: mac
path: ./dist/macos
subpath: ./macos/
- save_cache:
key: npm-{{ arch }}-{{ .Branch }}-{{ checksum "package-lock.json" }}
paths:
- "node_modules"
- "~/.cache/electron"
- "~/.cache/electron-builder"
- save_cache:
key: npm-{{ arch }}-{{ .Branch }}-{{ checksum "src/package-lock.json" }}
paths:
- "src/node_modules"
msi_installer:
executor: win/vs2019
steps:
- checkout
- run: mkdir -p ./dist/
- attach_workspace:
at: ./dist
- win_make:
operation: optimize
- win_make:
operation: "install-deps"
- win_make:
operation: "build"
- run: mkdir -p ./dist/win-release
- run: cp -r release/*.exe ./dist/win-release
- run: cp -r release/*.zip ./dist/win-release
- run: cp -r release/*.msi ./dist/win-release
- run: cp -r release/*.blockmap ./dist/win-release
- persist_to_workspace:
root: ./dist/
paths:
- "./win-release/"
mac_installer:
executor: mac
steps:
- checkout
- run: mkdir -p ./dist
- attach_workspace:
at: ./dist
- run:
name: Installing npm dependencies
command: npm install
- build:
os: mac
path: ./dist/macos-release
subpath: ./macos-release/
store_artifacts:
executor: wine-chrome
steps:
- attach_workspace:
at: ./dist
- store_artifacts:
path: /tmp/artifacts/
path: ./dist
destination: packages
- run: ./node_modules/.bin/build-storybook -c src/.storybook -o storybook
- store_artifacts:
path: storybook/
destination: storybook
workflows:
version: 2
build_and_test:
jobs:
- check
- build:
- build-linux:
requires:
- check
- build-win-no-installer:
requires:
- check
filters:
branches:
ignore:
- /^release-\d+\.\d+\.\d+?(-rc.*)?/
- build-mac-no-dmg:
requires:
- check
filters:
branches:
ignore:
- /^release-\d+\.\d+(\.\d+)?(-rc.*)?/
- msi_installer:
requires:
- check
context: windows-codesign
filters:
branches:
only:
# only for release and release candidates
# release-XX.YY.ZZ
# release-XX.YY.ZZ-rc-something
- /^release-\d+\.\d+\.\d+?(-rc.*)?/
- mac_installer:
requires:
- check
context: codesign-certificates
filters:
branches:
only:
- /^release-\d+\.\d+\.\d+?(-rc.*)?/
- store_artifacts:
# for master/PR builds
requires:
- build-linux
- build-win-no-installer
- build-mac-no-dmg
filters:
branches:
ignore:
- /^release-\d+\.\d+\.\d+?(-rc.*)?/
- store_artifacts:
# for release and rc builds
requires:
- msi_installer
- mac_installer
- build-linux
filters:
branches:
only:
- /^release-\d+\.\d+\.\d+?(-rc.*)?/

View file

@ -20,7 +20,9 @@
"protocols": [
{
"name": "Mattermost",
"schemes": ["mattermost"]
"schemes": [
"mattermost"
]
}
],
"deb": {
@ -64,7 +66,9 @@
"NOTICE.txt"
]
}
]
],
"hardenedRuntime": true,
"entitlements": "./resources/osx/entitlements.mac.inherit.plist"
},
"dmg": {
"background": "resources/osx/DMG_BG.png",
@ -93,3 +97,4 @@
"artifactName": "${name}-setup-${version}-win.${ext}"
}
}

View file

@ -28,9 +28,9 @@
"test": "npm-run-all lint:js test:*",
"test:app": "cross-env NODE_ENV=production npm run build && mocha -r @babel/register --reporter mocha-circleci-reporter --recursive test/specs",
"package:all": "cross-env NODE_ENV=production npm-run-all check-build-config package:windows package:mac package:linux",
"package:windows": "cross-env NODE_ENV=production npm-run-all check-build-config build && build --win --x64 --ia32 --publish=never",
"package:mac": "cross-env NODE_ENV=production npm-run-all check-build-config build && build --mac --publish=never",
"package:linux": "cross-env NODE_ENV=production npm-run-all check-build-config build && build --linux --x64 --ia32 --publish=never",
"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 --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 .",
"lint:js-quiet": "eslint --ignore-path .gitignore --ignore-pattern node_modules --ext .js --ext .jsx . --quiet",
"fix:js": "eslint --ignore-path .gitignore --ignore-pattern node_modules --quiet --ext .js --ext .jsx . --fix",
@ -53,7 +53,7 @@
"css-loader": "^1.0.1",
"devtron": "^1.4.0",
"electron": "^5.0.10",
"electron-builder": "^20.44.4",
"electron-builder": "^21.2.0",
"electron-connect": "^0.6.3",
"eslint": "^5.9.0",
"eslint-config-mattermost": "github:mattermost/eslint-config-mattermost",
@ -77,3 +77,4 @@
"webpack-merge": "^4.1.4"
}
}

View file

@ -0,0 +1,13 @@
<?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.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/>
</dict>
</plist>

View file

@ -1,31 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<policyDefinitionResources revision="0.1" schemaVersion="1.0" >
<policyDefinitionResources revision="0.1" schemaVersion="1.0">
<displayName/>
<description/>
<resources >
<stringTable >
<string id="SUPPORTED_MMD43">Mattermost Desktop Application 4.3 or later</string>
<string id="RequiresMattermost43">Requires Mattermost Desktop 4.3 or later</string>
<string id="mattermost">Mattermost</string>
<string id="DisableAutoUpdate">Disable Auto Updater</string>
<string id="DisableAutoUpdate_Explain">If this policy is enabled, the Mattermost Desktop Application does not receive udpates.
<string id="EnableAutoUpdater">EnableAutoUpdater</string>
<string id="EnableAutoUpdaterDescription">If this policy is enabled, users will receive notifications when new versions of the desktop app are available. System Administrator privilages on the computer are required to install the update.</string>
<string id="EnableServerManagement">EnableServerManagement</string>
<string id="EnableServerManagementDescription">If this policy is enabled, users can add or remove servers in their app settings, even if default servers are configured in DefaultServerList.
If this policy is disabled or not configured, the Mattermost Desktop Application receives updates.</string>
<string id="PreventAddNewServer">Prevent adding new Mattermost server</string>
<string id="PreventAddNewServer_Explain">If this policy is enabled, it is not possible to add new servers.
If this policy is disabled or not configured, it is possible to add new servers.</string>
<string id="ServerURL">Server addresses</string>
<string id="ServerURL_Explain">If this policy is enabled, you can set one or more Mattermost server addresses.
If this policy is disabled or not configured, no servers are preconfigured.</string>
<string id="PreventGPU">Disable GPU hardware acceleration</string>
<string id="PreventGPU_Explain">If this policy is enabled, the Mattermost Desktop Application does not use the GPU for hardware acceleration.
If this policy is disabled or not configured, the Mattermost Desktop Application does use the GPU for hardware acceleration.</string>
If this policy is disabled, the Server Management section is hidden in the app settings and only servers defined by Group Policy can be used.</string>
<string id="DefaultServerList">DefaultServerList</string>
<string id="DefaultServerListDescription">If this policy is enabled, you can define one or more Mattermost servers that will be pre-configured for users when they launch the app.</string>
</stringTable>
<presentationTable>
<presentation id="ServerURL">
<listBox refId="ServerURL">List of servers:</listBox>
<presentation id="DefaultServerList">
<listBox refId="DefaultServerList">List of default Mattermost servers:</listBox>
</presentation>
</presentationTable>
</resources>

View file

@ -6,16 +6,16 @@
<resources minRequiredRevision="0.1"/>
<supportedOn>
<definitions>
<definition name="SUPPORTED_MMD43" displayName="$(string.SUPPORTED_MMD43)"/>
<definition name="RequiresMattermost43" displayName="$(string.RequiresMattermost43)"/>
</definitions>
</supportedOn>
<categories>
<category displayName="$(string.mattermost)" name="mattermost"></category>
</categories>
<policies>
<policy name="DisableAutoUpdate" class="Machine" displayName="$(string.DisableAutoUpdate)" explainText="$(string.DisableAutoUpdate_Explain)" key="Software\Policies\Mattermost" valueName="DisableAutoUpdate">
<policy name="EnableAutoUpdater" class="Machine" displayName="$(string.EnableAutoUpdater)" explainText="$(string.EnableAutoUpdaterDescription)" key="Software\Policies\Mattermost" valueName="EnableAutoUpdater">
<parentCategory ref="mattermost"/>
<supportedOn ref="SUPPORTED_MMD43"/>
<supportedOn ref="RequiresMattermost43"/>
<enabledValue>
<decimal value="1"/>
</enabledValue>
@ -23,9 +23,9 @@
<decimal value="0"/>
</disabledValue>
</policy>
<policy name="PreventAddNewServer" class="Both" displayName="$(string.PreventAddNewServer)" explainText="$(string.PreventAddNewServer_Explain)" key="Software\Policies\Mattermost" valueName="PreventAddNewServer">
<policy name="EnableServerManagement" class="Both" displayName="$(string.EnableServerManagement)" explainText="$(string.EnableServerManagementDescription)" key="Software\Policies\Mattermost" valueName="EnableServerManagement">
<parentCategory ref="mattermost"/>
<supportedOn ref="SUPPORTED_MMD43"/>
<supportedOn ref="RequiresMattermost43"/>
<enabledValue>
<decimal value="1"/>
</enabledValue>
@ -33,22 +33,12 @@
<decimal value="0"/>
</disabledValue>
</policy>
<policy name="ServerURL" class="Both" displayName="$(string.ServerURL)" explainText="$(string.ServerURL_Explain)" presentation="$(presentation.ServerURL)" key="Software\Policies\Mattermost">
<policy name="DefaultServerList" class="Both" displayName="$(string.DefaultServerList)" explainText="$(string.DefaultServerListDescription)" presentation="$(presentation.DefaultServerList)" key="Software\Policies\Mattermost">
<parentCategory ref="mattermost" />
<supportedOn ref="SUPPORTED_MMD43" />
<supportedOn ref="RequiresMattermost43" />
<elements>
<list id="ServerURL" key="Software\Policies\Mattermost\DefaultServerList" additive="true" explicitValue="true" />
<list id="DefaultServerList" key="Software\Policies\Mattermost\DefaultServerList" additive="true" explicitValue="true" />
</elements>
</policy>
<policy name="PreventGPU" class="Machine" displayName="$(string.PreventGPU)" explainText="$(string.PreventGPU_Explain)" key="Software\Policies\Mattermost" valueName="PreventGPU">
<parentCategory ref="mattermost"/>
<supportedOn ref="SUPPORTED_MMD43"/>
<enabledValue>
<decimal value="1"/>
</enabledValue>
<disabledValue>
<decimal value="0"/>
</disabledValue>
</policy>
</policies>
</policyDefinitions>

View file

@ -0,0 +1,56 @@
{\rtf1\ansi\deff0\nouicompat{\fonttbl{\f0\fnil\fcharset0 Courier New;}}\pard\qj\f0\fs18
\b Terms of Service\b0
\par\par
The below are the Conditions of Use (End Users) for Mattermost, the software that powers the online service you are using, not for the service itself.
\par\par
\b Mattermost Conditions of Use (End Users)\b0
\par\par
This instance of the Mattermost platform is provided to you for your use by a third party entity who is not Mattermost, Inc. Mattermost, Inc. owns some of the intellectual property required for use of the Mattermost platform, and as such, the third party has agreed that your use of our IP is allowed only if you agree and comply with the following terms and conditions.
\par\par
Your promise to comply with these conditions in exchange for access to the Mattermost IP via the Mattermost platform provided by a third party entity are an Agreement by and between you and Mattermost, Inc. (the “Agreement”).
\par\par
If you do not agree to these conditions, you may not use the Mattermost platform.
\par\par
1. Your Mattermost Account
\par\par
You may not use your Account in violation of any law or policies instituted by the entity providing you access to this Service.
\par\par
2. Responsibility of Contributors
\par\par
If you choose to make content available on the Mattermost platform (“Content”), you must ensure that the following is true:
\par\par
the downloading, copying and use of the Content will not infringe the proprietary rights, including but not limited to the copyright, patent, trademark or trade secret rights, of any third party;
\par\par
if your employer has rights to intellectual property you create, you have either (i) received permission from your employer to post or make available the Content, including but not limited to any software, or (ii) secured from your employer a waiver as to all rights in or to the Content;
\par\par
you have fully complied with any third-party licenses relating to the Content, and have done all things necessary to successfully pass through to end users any required terms;
\par\par
the Content does not contain or install any viruses, worms, malware, Trojan horses or other harmful or destructive content;
\par\par
the Content is not spam, is not machine- or randomly-generated, and does not contain unethical or unwanted commercial content designed to drive traffic to third party sites or boost the search engine rankings of third party sites, or to further unlawful acts (such as phishing) or mislead recipients as to the source of the material (such as spoofing);
\par\par
the Content is not pornographic, does not contain threats or incite violence, and does not violate the privacy or publicity rights of any third party;
\par\par
your content is not getting advertised via unwanted electronic messages such as spam links on newsgroups, email lists, blogs and web sites, and similar unsolicited promotional methods;
\par\par
your content is not named in a manner that misleads your readers into thinking that you are another person or company; and
\par\par
you have, in the case of Content that includes computer code, accurately categorized and/or described the type, nature, uses and effects of the materials, whether requested to do so by Mattermost or otherwise.
\par\par
3. Intellectual Property
\par\par
Your use of the Mattermost platform does not transfer from Mattermost to you any Mattermost or third party intellectual property, and all right, title and interest in and to such property will remain (as between the parties) solely with Mattermost. Mattermost, mattermost.com, the mattermost.com logo, and all other trademarks, service marks, graphics and logos used in connection with mattermost.com, or the Mattermost platform are trademarks or registered trademarks of Mattermost or Mattermosts licensors. Other trademarks, service marks, graphics and logos used in connection with the Platform may be the trademarks of other third parties.
\par\par
4. Disclaimer of Warranties
\par\par
THE MATTERMOST PLATFORM IS PROVIDED “AS IS.” MATTERMOST AND ITS SUPPLIERS AND LICENSORS HEREBY DISCLAIM ALL WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. NEITHER MATTERMOST NOR ITS SUPPLIERS AND LICENSORS, MAKES ANY WARRANTY THAT THE MATTERMOST PLATFORM WILL BE ERROR FREE OR THAT SERVICES USING IT WILL BE CONTINUOUS OR UNINTERRUPTED.
\par\par
5. Limitation of Liability
\par\par
IN NO EVENT WILL MATTERMOST, OR ITS SUPPLIERS OR LICENSORS, BE LIABLE TO YOU UNDER ANY THEORY OF CONTRACT, NEGLIGENCE, STRICT LIABILITY OR OTHER LEGAL OR EQUITABLE THEORY FOR: (I) ANY SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES; (II) THE COST OF PROCUREMENT FOR SUBSTITUTE PRODUCTS OR SERVICES; (III) INTERRUPTION OF USE OR LOSS OR CORRUPTION OF DATA; OR (IV) ANY AMOUNTS IN EXCESS OF $50 USD.
\par\par
6. Indemnification
\par\par
You agree to indemnify and hold harmless Mattermost, its contractors, and its licensors, and their respective directors, officers, employees and agents from and against any and all claims and expenses, including attorneys fees, arising out of your use of the Mattermost platform, including but not limited to your violation of this Agreement.
\par\par
7. This Agreement constitutes the entire agreement between Mattermost and you concerning you use of the Mattermost platform provided by a third party. Except to the extent applicable law, if any, provides otherwise, this Agreement will be governed by the laws of the state of California, U.S.A., excluding its conflict of law provisions, and the proper venue for any disputes arising out of or relating to any of the same will be the state and federal courts located in San Francisco County, California. Except for claims for injunctive or equitable relief or claims regarding intellectual property rights (which may be brought in any competent court without the posting of a bond), any dispute arising under this Agreement shall be finally settled in accordance with the Comprehensive Arbitration Rules of the Judicial Arbitration and Mediation Service, Inc. (“JAMS”) by one arbitrator appointed in accordance with such Rules. The arbitration shall take place in San Francisco, California, in the English language and the arbitral decision may be enforced in any court. The prevailing party in any action or proceeding to enforce this Agreement shall be entitled to costs and attorneys fees. If any part of this Agreement is held invalid or unenforceable, that part will be construed to reflect the parties original intent, and the remaining portions will remain in full force and effect. A waiver by either party of any term or condition of this Agreement or any breach thereof, in any one instance, will not waive such term or condition or any subsequent breach thereof.

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
<String Id="LANG" Overridable="yes">1033</String>
<String Id="OsRequirements" Overridable="yes">Windows 7 or higher is required to run [ProductName].</String>
<String Id="Requires64Bit" Overridable="yes">This install package only supports 64-bit operating systems</String>
<String Id="Requires32Bit" Overridable="yes">This install package only supports 32-bit operating systems</String>
<String Id="WelcomeDlgInstructions" Overridable="yes">Welcome to the [ProductName] [Installer]!
Click Install to proceed with a standard installation, or click Advanced to change the installation directory and access other customizations.</String>
<String Id="MaintenanceWelcomeDlgInstructions" Overridable="yes">[ProductName] [Installer]!
This wizard will help you install, modify, repair or uninstall the [ProductName] application on this computer.</String>
<String Id="WelcomeDlgAcceptLicenseCheckBox" Overridable="yes">I accept the terms in the License Agreement</String>
<String Id="AdvancedDlgInstructions" Overridable="yes">Change the installation directory, create application shortcuts and choose whether to launch the application after installation. Click Cancel to exit the installer.</String>
<String Id="AdvancedDlgLocationLabel" Overridable="yes">Location:</String>
<String Id="AdvancedDlgBrowse" Overridable="yes">Browse</String>
<String Id="AdvancedDlgAddDesktopShortcut" Overridable="yes">Add a shortcut to the desktop</String>
<String Id="AdvancedDlgAddStartMenuShortcut" Overridable="yes">Add a shortcut to the Start menu</String>
<String Id="AdvancedDlgLaunchAppAfterInstall" Overridable="yes">Launch [ProductName] after installation</String>
<String Id="BrowseDlgInstructions" Overridable="yes">Select the directory you want [ProductName] be installed to.</String>
<String Id="BrowseDlgNewFolder" Overridable="yes">Create a new folder</String>
<String Id="BrowseDlgUp" Overridable="yes">Go thte parent folder</String>
<String Id="BrowseDlgPathLabel" Overridable="yes">Currently defined installation directory:</String>
<String Id="CancelDlgText" Overridable="yes">Are you sure you want to cancel [ProductName] installation?</String>
<String Id="UserExitDlgInstructions" Overridable="yes">[ProductName] installation was interrupted and your system has not been modified.
To install [ProductName] in the future, please run the installer again.</String>
<String Id="ProgressDlgInstructions" Overridable="yes">[Progress1] [ProductName]. This may take several minutes.</String>
<String Id="ProgressDlgStatusLabel" Overridable="yes">Status:</String>
<String Id="SuccessDlgInstructions" Overridable="yes">[Progress2] successful. Click Finish to exit the installer.</String>
</WixLocalization>

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

539
scripts/Makefile.ps1 Normal file
View file

@ -0,0 +1,539 @@
# We would have preferred to put this main section to the end of the script,
# but PowerSchell script arguments must be defined as the first statement in
# a PowerShell script.
Param (
[parameter(Position=0)]$makeRule
)
# imports
# these should be better with modules, but we would have to install them on circleci servers
# import tools
. .\scripts\tools.ps1
# import dependencies functions
. .\scripts\dependencies.ps1
################################################################################
# Appveyor related functions
################################################################################
#region
function Is-AppVeyor {
if ($env:APPVEYOR -eq $True) {
return $True
}
return $False
}
function Enable-AppVeyorRDP {
if (-not (Is-AppVeyor)) {
Print-Error "You are not running on AppVeyor. Enabling RDP will be bypassed."
return
}
# src.: https://www.appveyor.com/docs/how-to/rdp-to-build-worker/
$blockRdp = $true;
iex ((new-object net.webclient).DownloadString(
"https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1"
))
}
#endregion
################################################################################
# Mattermost related functions
################################################################################
#region
function Prepare-Path {
# As we may need to install new dependencies, make sure the PATH env
# variable is not too large. Some CI envs like AppVeyor have already the
# PATH env variable defined at the maximum which prevents new strings to
# be added to it. We will remove all the stuff added for programs in
# Program Files (64 bits and 32 bits variants) except the path of our
# dependencies.
# src.: https://gist.github.com/wget/a102f89c301014836aaa49a98dd06ee2
$oldPath = $env:Path
[array]$newPath
# Cleanup the PATH from everything contained in Program Files...
$newPath = ($env:Path -split ';') | Where-Object { $_ -notlike "C:\Program Files*" }
# ...except from Git
$newPath += ($env:Path -split ';') | Where-Object { $_ -like "C:\Program Files*\*Git*" }
$env:Path = $newPath -join ';'
Print-Info "Reducing and reordering PATH from `n ""$oldPath""`n to`n ""$env:Path"""
# Prepending ensures we are using our own path here to avoid the paths the
# user might have defined to interfere.
# Prepend the PATH with npm/nodejs dir
Print-Info "Checking if npm dir is already in the PATH..."
$env:Path = "$(Get-NpmDir)" + ";" + $env:Path
# Prepend the PATH with wix dir
Print-Info "Checking if wix dir is already in the PATH..."
$env:Path = "$(Get-WixDir)" + ";" + $env:Path
# Prepend the PATH with signtool dir
Print-Info "Checking if signtool dir is already in the PATH..."
$env:Path = "$(Get-SignToolDir)" + ";" + $env:Path
}
function Catch-Interruption {
[console]::TreatControlCAsInput = $true
while ($true) {
if ([console]::KeyAvailable) {
$key = Read-Host
#$key = [system.console]::readkey($true)
if (($key.modifiers -band [consolemodifiers]"control") -and
($key.key -eq "C")) {
Print-Warning "Ctrl-C pressed. Cancelling the build process and restoring computer state..."
Restore-ComputerState
exit
}
}
}
}
function Backup-ComputerState {
$env:COM_MATTERMOST_MAKEFILE_PATH_BACKUP = $env:Path
Push-Location "$(Get-RootDir)"
# Needed because for native apps, PowerShell doesn't change the
# process current path location
#src.: https://stackoverflow.com/a/4725090/3514658
[Environment]::CurrentDirectory = $PWD
# Refresh path because it might have been made durty in the current shell
Refresh-Path
}
function Restore-ComputerState {
Print-Info "Restoring PATH..."
$env:Path = $env:COM_MATTERMOST_MAKEFILE_PATH_BACKUP
Print-Info "Restoring current working directory..."
Pop-location
[Environment]::CurrentDirectory = $PWD
# Remove all COM_MATTERMOST_MAKEFILE_ prefixed env variable
foreach ($item in (Get-Item -Path Env:*)) {
if ($item.Name -imatch 'COM_MATTERMOST_MAKEFILE_') {
Print-Info "Removing Mattermost env variable: $($item.Name)..."
Remove-Item env:\$($item.Name)
}
}
}
function Optimize-Build {
Print-Info "Checking if Windows Search is running..."
if ((Get-Service -Name "Windows Search").Status -eq "Running") {
Print-Info "Windows Search is running. Disabling it..."
Stop-Service "Windows Search"
Print-Warning "WARNING: This makefile disabled Windows Search, to reenable it, type in an administror Powershell: Start-Service ""Windows Search"""
} else {
Print-Info "Windows Search has already been disabled."
}
Print-Info "Checking if Windows Defender realtime protection is active..."
if (!(Get-MpPreference).DisableRealtimeMonitoring) {
Print-Info "Windows Defender realtime protection is active. Disabling it..."
Set-MpPreference -DisableRealtimeMonitoring $true
Print-Warning "WARNING: This makefile disabled Windows Defender realtime protection, to reenable it, type in an administror Powershell: Set-MpPreference -DisableRealtimeMonitoring `$false"
} else {
Print-Info "Windows Defender realtime protection has already been disabled."
}
}
function Run-BuildId {
Print-Info -NoNewLine "Getting build date..."
$env:COM_MATTERMOST_MAKEFILE_BUILD_DATE = (Get-Date).ToUniversalTime().ToString("yyyy-MM-dd")
Print " [$env:COM_MATTERMOST_MAKEFILE_BUILD_DATE]"
# Generate build version ids
#
# nodejs/npm does require to have semver parsable versions:
# major.minor.patch
# Non number values are allowed only if they are not starting the dot verion.
# 4.3.0-rc2 is allowed but 4.3.rc2 is not
#
# wix toolset supports semver up to the revision dot syntax:
# major.minor.patch.revision.
# ProductVersion Property is defined as
# [0-255].[0-255].[0-65535]
# 8 , 8 , 16 signed bit
# File Version is defined as
# [0-65535].[0-65535].[0-65535].[0-65535]
# 16 , 16 , 16 , 16 signed bit
#
# Other chars other than numbers should be removed.
# Versions like v4.3.0-rc0 shoud be. We are thus forcing to
# have a format like 4.3.0.rc0.
# When the last tag is not present or not a parsable semver version, we are
# taking the number of revisions reachable from the HEAD of the current branch
# (other branches are not taken into account).
# Example:
# $ git rev-list --count --first-parent HEAD
# 645
# Using the date is unreliable, because this requires to have a precision at
# seconds, leading to an overflow of the integer range supported by wix.
# 4.3.0.20190512074020 is not accepted and fails with the following error:
# candle.exe : error CNDL0001 : Value was either too large or too small for an Int32.
# Exception Type: System.OverflowException
# Add the revision only if we are not building a tag
Print-Info "Checking build id tag..."
if ($env:APPVEYOR_REPO_TAG -eq $true) {
$version = "$env:APPVEYOR_REPO_TAG_NAME"
} else {
$version = "$(git describe --tags $(git rev-list --tags --max-count=1))"
}
Print-Info "Checking build id tag validity... [$version]"
[version]$appVersion = New-Object -TypeName System.Version
[void][version]::TryParse($($version -Replace '-','.' -Replace '[^0-9.]'), [ref]$appVersion)
if (!($appVersion)) {
Print-Error "Non parsable tag detected. Fallbacking to version 0.0.0."
$version = "0.0.0"
}
Print-Info -NoNewLine "Getting build id version..."
$env:COM_MATTERMOST_MAKEFILE_BUILD_ID = $version
Print " [$env:COM_MATTERMOST_MAKEFILE_BUILD_ID]"
Print-Info -NoNewLine "Getting build id version for msi..."
$env:COM_MATTERMOST_MAKEFILE_BUILD_ID_MSI = ($version -Replace '-','.' -Replace '[^0-9.]').Split('.')[0..3] -Join '.'
Print " [$env:COM_MATTERMOST_MAKEFILE_BUILD_ID_MSI]"
Print-Info -NoNewLine "Getting build id version for node/npm..."
$env:COM_MATTERMOST_MAKEFILE_BUILD_ID_NODE = ($version -Replace '^v').Split('.')[0..2] -Join '.'
Print " [$env:COM_MATTERMOST_MAKEFILE_BUILD_ID_NODE]"
Print-Info "Patching version from msi xml descriptor..."
$msiDescriptorFileName = "scripts\msi_installer.wxs"
$msiDescriptor = [xml](Get-Content $msiDescriptorFileName)
$msiDescriptor.Wix.Product.Version = [string]$env:COM_MATTERMOST_MAKEFILE_BUILD_ID_MSI
$msiDescriptor.Save($msiDescriptorFileName)
Print-Info "Patching version from electron package.json..."
$packageFileName = "package.json"
$package = Get-Content $packageFileName -Raw | ConvertFrom-Json
$package.version = [string]$env:COM_MATTERMOST_MAKEFILE_BUILD_ID_NODE
$package | ConvertTo-Json | Set-Content $packageFileName
Print-Info "Patching version from electron src\package.json..."
$packageFileName = "src\package.json"
$package = Get-Content $packageFileName -Raw | ConvertFrom-Json
$package.version = [string]$env:COM_MATTERMOST_MAKEFILE_BUILD_ID_NODE
$package | ConvertTo-Json | Set-Content $packageFileName
}
function Run-BuildChangelog {
Print-Info "Getting list of commits for changelog..."
$previousTag = $(Invoke-Expression "git describe --abbrev=0 --tags $(git describe --abbrev=0)^")
if ($env:APPVEYOR_REPO_TAG -eq $true) {
$currentTag = [string]$(git describe --abbrev=0)
} else {
$currentTag = [string]"HEAD"
}
$changelogRaw = "$(git log --oneline --since=""$(git log -1 ""$previousTag"" --pretty=%ad)"" --until=""$(git log -1 "$currentTag" --pretty=%ad)"")"
$changelog = "";
foreach ($i in $changelogRaw) {
$changelog += "* $i`n"
}
$env:COM_MATTERMOST_MAKEFILE_BUILD_CHANGELOG = $changelog
}
function Run-BuildElectron {
Print-Info "Installing nodejs/electron dependencies (running npm install)..."
npm install
#npm install --prefix="$(Get-RootDir)" "$(Get-RootDir)"
Print-Info "Building nodejs/electron code (running npm run build)..."
npm run build
#npm run build --prefix="$(Get-RootDir)" "$(Get-RootDir)"
Print-Info "Packaging nodejs/electron for Windows (running npm run package:windows)..."
npm run package:windows
#npm run package:windows --prefix="$(Get-RootDir)" "$(Get-RootDir)"
Print-Info "Cleaning build dir..."
Remove-Item "release\win-ia32-unpacked\resources\app.asar.unpacked\" -Force -Recurse
Remove-Item "release\win-unpacked\resources\app.asar.unpacked\" -Force -Recurse
}
function Run-BuildForceSignature {
# Only sign the executable and .dll if this is a release and not a pull request
# check.
if ($env:APPVEYOR_REPO_TAG -eq $true) {
Print-Info "Enforcing signature of the executable and dll..."
# Decrypt the certificate. The decrypted version will be at
# .\resources\windows\certificate\mattermost-desktop-windows.pfx
iex ((New-Object Net.WebClient).DownloadString(
"https://raw.githubusercontent.com/appveyor/secure-file/master/install.ps1"
))
# Secure variables are never decoded during Pull Request
# except if the repo is private and a secure org has been created
# src.: https://www.appveyor.com/docs/build-configuration/#secure-variables
& "appveyor-tools\secure-file" -decrypt "resources\windows\certificate\mattermost-desktop-windows.pfx.enc" -secret "$env:COM_MATTERMOST_MAKEFILE_CERTIFICATE_DECRYPTION_KEY_ENCRYPTED"
foreach ($archPath in "release\win-unpacked", "release\win-ia32-unpacked") {
# Note: The C++ redistribuable files will be resigned again even if they have a
# correct signature from Microsoft. Windows doesn't seem to complain, but we
# don't know whether this is authorized by the Microsoft EULA.
Get-ChildItem -Path $archPath -recurse "*.dll" | ForEach-Object {
Print-Info "Signing $($_.Name) (waiting for 2 * 15 seconds)..."
# Waiting for at least 15 seconds is needed because these time
# servers usually have rate limits and signtool can fail with the
# following error message:
# "SignTool Error: The specified timestamp server either could not be reached or returned an invalid response.
# src.: https://web.archive.org/web/20190306223053/https://github.com/electron-userland/electron-builder/issues/2795#issuecomment-466831315
Start-Sleep -s 15
signtool.exe sign /f "resources\windows\certificate\mattermost-desktop-windows.pfx" /p "$env:COM_MATTERMOST_MAKEFILE_CERTIFICATE_PRIVATE_KEY_ENCRYPTED" /tr "http://timestamp.digicert.com" /fd sha1 /td sha1 "$($_.FullName)"
Start-Sleep -s 15
signtool.exe sign /f "resources\windows\certificate\mattermost-desktop-windows.pfx" /p "$env:COM_MATTERMOST_MAKEFILE_CERTIFICATE_PRIVATE_KEY_ENCRYPTED" /tr "http://timestamp.digicert.com" /fd sha256 /td sha256 /as "$($_.FullName)"
}
Print-Info "Signing Mattermost.exe (waiting for 2 * 15 seconds)..."
Start-Sleep -s 15
signtool.exe sign /f "resources\windows\certificate\mattermost-desktop-windows.pfx" /p "$env:COM_MATTERMOST_MAKEFILE_CERTIFICATE_PRIVATE_KEY_ENCRYPTED" /tr "http://timestamp.digicert.com" /fd sha1 /td sha1 "$archPath\Mattermost.exe"
Start-Sleep -s 15
signtool.exe sign /f "resources\windows\certificate\mattermost-desktop-windows.pfx" /p "$env:COM_MATTERMOST_MAKEFILE_CERTIFICATE_PRIVATE_KEY_ENCRYPTED" /tr "http://timestamp.digicert.com" /fd sha256 /td sha256 /as "$archPath\Mattermost.exe"
}
} elseif (Test-Path 'env:PFX') {
Print-Info "Signing"
foreach ($archPath in "release\win-unpacked", "release\win-ia32-unpacked") {
# Note: The C++ redistribuable files will be resigned again even if they have a
# correct signature from Microsoft. Windows doesn't seem to complain, but we
# don't know whether this is authorized by the Microsoft EULA.
Get-ChildItem -Path $archPath -recurse "*.dll" | ForEach-Object {
Print-Info "Signing $($_.Name) (waiting for 2 * 15 seconds)..."
# Waiting for at least 15 seconds is needed because these time
# servers usually have rate limits and signtool can fail with the
# following error message:
# "SignTool Error: The specified timestamp server either could not be reached or returned an invalid response.
# src.: https://web.archive.org/web/20190306223053/https://github.com/electron-userland/electron-builder/issues/2795#issuecomment-466831315
Start-Sleep -s 15
signtool.exe sign /f "./mattermost-desktop-windows.pfx" /p "$env:PFX_KEY" /tr "http://timestamp.digicert.com" /fd sha1 /td sha1 "$($_.FullName)"
Start-Sleep -s 15
signtool.exe sign /f "./mattermost-desktop-windows.pfx" /p "$env:PFX_KEY" /tr "http://timestamp.digicert.com" /fd sha256 /td sha256 /as "$($_.FullName)"
}
Print-Info "Signing Mattermost.exe (waiting for 2 * 15 seconds)..."
Start-Sleep -s 15
signtool.exe sign /f "./mattermost-desktop-windows.pfx" /p "$env:PFX_KEY" /tr "http://timestamp.digicert.com" /fd sha1 /td sha1 "$archPath\Mattermost.exe"
Start-Sleep -s 15
signtool.exe sign /f "./mattermost-desktop-windows.pfx" /p "$env:PFX_KEY" /tr "http://timestamp.digicert.com" /fd sha256 /td sha256 /as "$archPath\Mattermost.exe"
}
} else {
Print-Info "DLLs not signed"
}
}
function Run-BuildLicense {
# Convert license to RTF
$licenseTxtFile = "LICENSE.txt";
$licenseRtfFile = "resources/windows/license.rtf";
$licenseNewParagraph = "\par" + [Environment]::NewLine;
$sw = [System.IO.File]::CreateText($licenseRtfFile);
$sw.WriteLine("{\rtf1\ansi\deff0\nouicompat{\fonttbl{\f0\fnil\fcharset0 Courier New;}}\pard\qj\f0\fs18");
$lineToAdd = "";
$gapDetected = 0;
# We are relying on introspected C#/.NET rather than the buggy Get-Content
# cmdlet because Get-Content considers by default a `-Delimiter` to '\n'
# and thus breaks the purpose of the parser.
foreach ($line in [System.IO.File]::ReadLines($licenseTxtFile)) {
# trim() is equivalent to .replace("\ \s+", "")
# We replace one backslash by two. Since the first arg is a regex,
# we need to escape it.
# src.: https://stackoverflow.com/a/31324570/3514658
$sanitizedLine = $line.trim().replace("\\", "\\").replace("{", "\{").replace("}", "\}");
# Print previous string gathered if gap detected.
if ([string]::IsNullOrEmpty($sanitizedLine)) {
$gapDetected++;
# For first line keep paragraph definition from document head.
if ($gapDetected -eq 1) {
$sw.Write($lineToAdd);
} elseif ($gapDetected -eq 2) {
$sw.Write($licenseNewParagraph + $lineToAdd);
} else {
$sw.Write($licenseNewParagraph + $lineToAdd + $licenseNewParagraph);
}
$lineToAdd = "";
continue;
}
# Keep carriage return for first two blocks comprising Copyright and
# license name statements.
if ($gapDetected -lt 3) {
$lineToAdd += $sanitizedLine + $licenseNewParagraph;
continue;
}
# Do not add heading space if the line begins a new paragraph.
if ($lineToAdd -eq "") {
$lineToAdd += $sanitizedLine;
continue;
}
$lineToAdd += " " + $sanitizedLine;
}
if ($lineToAdd -ne "") {
$sw.Write([Environment]::NewLine + $licenseNewParagraph + $lineToAdd + "\par");
}
$sw.Close();
}
function Run-BuildMsi {
Print-Info "Building 32 bits msi installer..."
heat.exe dir "release\win-ia32-unpacked\" -o "scripts\msi_installer_files.wxs" -scom -frag -srd -sreg -gg -cg MattermostDesktopFiles -t "scripts\msi_installer_files_replace_id.xslt" -dr INSTALLDIR
candle.exe -dPlatform=x86 "scripts\msi_installer.wxs" "scripts\msi_installer_files.wxs" -o "scripts\"
light.exe "scripts\msi_installer.wixobj" "scripts\msi_installer_files.wixobj" -loc "resources\windows\msi_i18n\en_US.wxl" -o "release\mattermost-desktop-$($env:COM_MATTERMOST_MAKEFILE_BUILD_ID)-x86.msi" -b "release\win-ia32-unpacked\"
Print-Info "Building 64 bits msi installer..."
heat.exe dir "release\win-unpacked\" -o "scripts\msi_installer_files.wxs" -scom -frag -srd -sreg -gg -cg MattermostDesktopFiles -t "scripts\msi_installer_files_replace_id.xslt" -t "scripts\msi_installer_files_set_win64.xslt" -dr INSTALLDIR
candle.exe -dPlatform=x64 "scripts\msi_installer.wxs" "scripts\msi_installer_files.wxs" -o "scripts\"
light.exe "scripts\msi_installer.wixobj" "scripts\msi_installer_files.wixobj" -loc "resources\windows\msi_i18n\en_US.wxl" -o "release\mattermost-desktop-$($env:COM_MATTERMOST_MAKEFILE_BUILD_ID)-x64.msi" -b "release\win-unpacked\"
# Only sign the executable and .dll if this is a release and not a pull request
# check.
if ($env:APPVEYOR_REPO_TAG -eq $true) {
Print-Info "Signing mattermost-desktop-$($env:COM_MATTERMOST_MAKEFILE_BUILD_ID)-x86.msi (waiting for 15 seconds)..."
Start-Sleep -s 15
# Dual signing is not supported on msi files. Is it recommended to sign with 256 hash.
# src.: https://security.stackexchange.com/a/124685/84134
# src.: https://social.msdn.microsoft.com/Forums/windowsdesktop/en-us/d4b70ecd-a883-4289-8047-cc9cde28b492#0b3e3b80-6b3b-463f-ac1e-1bf0dc831952
signtool.exe sign /f "resources\windows\certificate\mattermost-desktop-windows.pfx" /p "$env:COM_MATTERMOST_MAKEFILE_CERTIFICATE_PRIVATE_KEY_ENCRYPTED" /tr "http://timestamp.digicert.com" /fd sha256 /td sha256 "release\mattermost-desktop-$($env:COM_MATTERMOST_MAKEFILE_BUILD_ID)-x86.msi"
Print-Info "Signing mattermost-desktop-$($env:COM_MATTERMOST_MAKEFILE_BUILD_ID)-x64.msi (waiting for 15 seconds)..."
Start-Sleep -s 15
signtool.exe sign /f "resources\windows\certificate\mattermost-desktop-windows.pfx" /p "$env:COM_MATTERMOST_MAKEFILE_CERTIFICATE_PRIVATE_KEY_ENCRYPTED" /tr "http://timestamp.digicert.com" /fd sha256 /td sha256 "release\mattermost-desktop-$($env:COM_MATTERMOST_MAKEFILE_BUILD_ID)-x64.msi"
} elseif (Test-Path 'env:PFX') {
Print-Info "Signing mattermost-desktop-$($env:COM_MATTERMOST_MAKEFILE_BUILD_ID)-x86.msi (waiting for 15 seconds)..."
Start-Sleep -s 15
# Dual signing is not supported on msi files. Is it recommended to sign with 256 hash.
# src.: https://security.stackexchange.com/a/124685/84134
# src.: https://social.msdn.microsoft.com/Forums/windowsdesktop/en-us/d4b70ecd-a883-4289-8047-cc9cde28b492#0b3e3b80-6b3b-463f-ac1e-1bf0dc831952
signtool.exe sign /f "./mattermost-desktop-windows.pfx" /p "$env:PFX_KEY" /tr "http://timestamp.digicert.com" /fd sha256 /td sha256 "release\mattermost-desktop-$($env:COM_MATTERMOST_MAKEFILE_BUILD_ID)-x86.msi"
Print-Info "Signing mattermost-desktop-$($env:COM_MATTERMOST_MAKEFILE_BUILD_ID)-x64.msi (waiting for 15 seconds)..."
Start-Sleep -s 15
signtool.exe sign /f "./mattermost-desktop-windows.pfx" /p "$env:PFX_KEY" /tr "http://timestamp.digicert.com" /fd sha256 /td sha256 "release\mattermost-desktop-$($env:COM_MATTERMOST_MAKEFILE_BUILD_ID)-x64.msi"
} else {
Print-Info "Not signing msi"
}
}
function Get-Cert {
if (Test-Path 'env:PFX') {
Print-Info "Getting windows certificate"
[IO.File]::WriteAllBytes("./mattermost-desktop-windows.pfx", [Convert]::FromBase64String($env:PFX))
$password = "$env:PFX_KEY" | convertto-securestring -asplaintext -force
Print-Info "Importing certificate into the machine"
Import-PfxCertificate -filepath "./mattermost-desktop-windows.pfx" cert:\localMachine\my -password $password
} else {
Print-Warning "No variable environment found, build will not be signed"
}
}
function Remove-Cert {
if (Test-Path $env:PFX) {
Print-Info "Removing windows certificate"
Remove-Item -path "./mattermost-desktop-windows.pfx"
}
}
function Run-Build {
Check-Deps -Verbose -Throwable
Prepare-Path
Run-BuildId
Run-BuildChangelog
Run-BuildElectron
Get-Cert
Run-BuildForceSignature
Run-BuildLicense
Run-BuildMsi
Remove-Cert
}
function Run-Test {
Check-Deps -Verbose -Throwable
Prepare-Path
npm test
}
#endregion
################################################################################
# Main function
################################################################################
#region
function Main {
try {
if ($makeRule -eq $null) {
Print-Info "No argument passed to the make file. Executing ""all"" rule."
$makeRule = "all"
}
Backup-ComputerState
switch ($makeRule.toLower()) {
"all" {
Install-Deps
Run-Build
}
"build" {
Run-Build
}
"test" {
Run-Test
}
"install-deps" {
Install-Deps
}
"optimize" {
Optimize-Build
}
"debug" {
Enable-AppVeyorRDP
}
default {
Print-Error "Makefile argument ""$_"" is invalid. Build process aborted."
}
}
$env:COM_MATTERMOST_MAKEFILE_EXECUTION_SUCCESS = $true
$exitcode = 0
} catch {
switch ($_.Exception.Message) {
"com.mattermost.makefile.deps.missing" {
Print-Error "The following dependencies are missing: $($missing -Join ', ').`n Please install dependencies as an administrator:`n # makefile.ps1 install-deps"
$exitcode = -1
}
"com.mattermost.makefile.deps.notadmin" {
Print-Error "Installing dependencies requires admin privileges. Operation aborted.`n Please reexecute this makefile as an administrator:`n # makefile.ps1 install-deps"
$exitcode = -2
}
"com.mattermost.makefile.deps.wix" {
Print-Error "There was nothing wrong with your source code,but we found a problem installing wix toolset and couldn't continue. please try re-running the job."
$exitcode = -3
}
default {
Print-Error "Another error occurred: $_"
$exitcode = -100
}
}
} finally {
if (!($env:COM_MATTERMOST_MAKEFILE_EXECUTION_SUCCESS)) {
Print-Warning "Makefile interrupted by Ctrl + C or by another interruption handler."
}
Restore-ComputerState
exit $exitcode
}
}
Main
#endregion

View file

@ -1,14 +1,51 @@
#!/bin/sh
#!/usr/bin/env bash
set -eu
VERSION=`cat package.json | jq -r '.version'`
SRC=$1
DEST=$2
VERSION=$(cat package.json | jq -r '.version')
SRC="${1}"
DEST="${2}"
SOMETHING_COPIED=0
if [[ ! -d "${DEST}" ]]; then
echo "Can't find destination. Creating ${DEST}"
mkdir -p ${DEST}
fi
if [[ -f "${SRC}/mattermost-desktop-${VERSION}-win-ia32.zip" ]]; then
echo "Copying Win32\n"
cp "${SRC}/mattermost-desktop-${VERSION}-win-ia32.zip" "${DEST}/mattermost-desktop-${VERSION}-win32.zip"
SOMETHING_COPIED=1
fi
if [[ -f "${SRC}/mattermost-desktop-${VERSION}-win-x64.zip" ]]; then
echo "Copying Win64\n"
cp "${SRC}/mattermost-desktop-${VERSION}-win-x64.zip" "${DEST}/mattermost-desktop-${VERSION}-win64.zip"
SOMETHING_COPIED=$(($SOMETHING_COPIED + 2))
fi
if [[ -f "${SRC}/mattermost-desktop-setup-${VERSION}-win.exe" ]]; then
echo "Copying win-no-arch\n"
cp "${SRC}/mattermost-desktop-setup-${VERSION}-win.exe" "${DEST}/"
SOMETHING_COPIED=$(($SOMETHING_COPIED + 4))
fi
if [[ -f "${SRC}"/mattermost-desktop-${VERSION}-mac.zip ]]; then
echo "Copying mac\n"
cp "${SRC}"/mattermost-desktop-*-mac.* "${DEST}/"
if [[ -f "${SRC}"/mattermost-desktop-${VERSION}-mac.dmg ]]; then
cp "${SRC}"/*.blockmap "${DEST}/"
fi
SOMETHING_COPIED=$(($SOMETHING_COPIED + 8))
fi
if [[ -f "${SRC}"/mattermost-desktop-${VERSION}-linux-x64.tar.gz ]]; then
echo "Copying linux"
cp "${SRC}"/mattermost-desktop-*-linux-* "${DEST}/"
SOMETHING_COPIED=$(($SOMETHING_COPIED + 16))
fi
if [[ $SOMETHING_COPIED -eq 0 ]]; then
echo "didn't find anything to copy, seems like something failed"
exit -1
fi
cp "${SRC}/mattermost-desktop-${VERSION}-win-ia32.zip" "${DEST}/mattermost-desktop-${VERSION}-win32.zip"
cp "${SRC}/mattermost-desktop-${VERSION}-win-x64.zip" "${DEST}/mattermost-desktop-${VERSION}-win64.zip"
cp "${SRC}/mattermost-desktop-setup-${VERSION}-win.exe" "${DEST}/"
cp "${SRC}"/mattermost-desktop-*-mac.* "${DEST}/"
cp "${SRC}"/mattermost-desktop-*-linux-* "${DEST}/"
cp "${SRC}"/*.yml "${DEST}/"
cp "${SRC}"/*.blockmap "${DEST}/"
# exit $SOMETHING_COPIED
exit 0

136
scripts/dependencies.ps1 Normal file
View file

@ -0,0 +1,136 @@
# import tools
. .\scripts\tools.ps1
# src: https://superuser.com/a/756696/456258
function Is-Admin {
return ([Security.Principal.WindowsPrincipal] `
[Security.Principal.WindowsIdentity]::GetCurrent() `
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
function Check-Deps {
Param (
[Switch]
$verbose,
[Switch]
$throwable
)
if ($PSVersionTable.PSVersion.Major -lt 5) {
Print-Error "You need at least PowerShell 5.0 to execute this Makefile. Operation aborted."
exit
}
[array]$missing = @()
if ($verbose) { Print-Info "Checking choco dependency..." }
if (!(Check-Command "choco")) {
if ($verbose) { Print-Error "choco dependency missing." }
$missing += "choco"
}
if ($verbose) { Print-Info "Checking git dependency..." }
if (!(Check-Command "git")) {
if ($verbose) { Print-Error "git dependency missing." }
$missing += "git"
}
if ($verbose) { Print-Info "Checking nodejs/npm dependency..." }
# Testing if the folder is not empty first is needed otherwise if there is
# a file called like that in the path where the makefile is invocated, the
# check will succeed while it is plain wrong.
if ([string]::IsNullOrEmpty($(Get-NpmDir)) -or
# We could have used the builtin Test-Path cmdlet instead but it is
# tested for folders as well. We need to test for a file existence
# here.
![System.IO.File]::Exists("$(Get-NpmDir)\npm.cmd") -or
![System.IO.File]::Exists("$(Get-NpmDir)\node.exe")) {
if ($verbose) { Print-Error "nodejs/npm dependency missing." }
$missing += "npm"
}
if ($verbose) { Print-Info "Checking wix dependency..." }
if ([string]::IsNullOrEmpty($(Get-WixDir)) -or
![System.IO.File]::Exists("$(Get-WixDir)\heat.exe") -or
![System.IO.File]::Exists("$(Get-WixDir)\candle.exe") -or
![System.IO.File]::Exists("$(Get-WixDir)\light.exe")) {
if ($verbose) { Print-Error "wix dependency missing." }
$missing += "wix"
}
if ($verbose) { Print-Info "Checking signtool dependency..." }
if ([string]::IsNullOrEmpty($(Get-SignToolDir)) -or
![System.IO.File]::Exists("$(Get-SignToolDir)\signtool.exe")) {
if ($verbose) { Print-Error "signtool dependency missing." }
$missing += "signtool"
}
if ($throwable -and $missing.Count -gt 0) {
throw "com.mattermost.makefile.deps.missing"
}
return $missing
}
function Install-Wix {
Print-Info "Downloading wixtoolset..."
# choco is using 3.11 which causes problems building on remote ssh due to dotnet3.5
# choco install wixtoolset --yes
$WebClient = New-Object System.Net.WebClient
# if they ever fix the installer we can move to 3.11
#$WebClient.DownloadFile("https://github.com/wixtoolset/wix3/releases/download/wix3111rtm/wix311.exe",".\scripts\wix.exe")
$WebClient.DownloadFile("https://github.com/wixtoolset/wix3/releases/download/wix3104rtm/wix310.exe",".\scripts\wix.exe")
Print-Info "Installing wixtoolset..."
# todo: check hash
.\scripts\wix.exe -q
if ($LastExitCode -ne $null) {
throw "com.mattermost.makefile.deps.wix"
}
Print-Info "wixtoolset installed!"
}
function Install-Deps {
[array]$missing = Check-Deps -Verbose
if ($missing -eq $null) {
Print-Info "All dependencies met; exiting dependencies installation..."
return
}
if (-not (Is-Admin)) {
throw "com.mattermost.makefile.deps.notadmin"
}
foreach ($missingItem in $missing) {
switch ($missingItem) {
"choco" {
Print-Info "Installing chocolatey..."
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
break;
}
"git" {
Print-Info "Installing git..."
choco install git --yes
break;
}
"wix" {
Install-Wix
break;
}
"signtool" {
Print-Info "Installing Windows 10 SDK (for signtool)..."
choco install windows-sdk-10.1 --yes
break;
}
"npm" {
Print-Info "Installing nodejs-lts (with npm)..."
choco install nodejs-lts --yes
break;
}
}
Print-Info "Refreshing PATH..."
Refresh-Path
}
}

1004
scripts/msi_installer.wxs Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,20 @@
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wi="http://schemas.microsoft.com/wix/2006/wi">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<!-- src.: https://stackoverflow.com/a/19259647/3514658 -->
<xsl:template match="wi:ComponentGroup[@Id='MattermostDesktopFiles']/wi:Component/wi:File[contains(@Source,'Mattermost.exe')]">
<xsl:copy>
<xsl:attribute name="Id">MattermostDesktopEXE</xsl:attribute>
<xsl:copy-of select="@*[name()!='Id']"/>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

View file

@ -0,0 +1,20 @@
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wi="http://schemas.microsoft.com/wix/2006/wi">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<!-- src.: https://stackoverflow.com/a/4825010/3514658 -->
<xsl:template match="wi:ComponentGroup[@Id='MattermostDesktopFiles']/wi:Component">
<xsl:copy>
<xsl:attribute name="Win64">yes</xsl:attribute>
<xsl:copy-of select="@*"/>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

165
scripts/tools.ps1 Normal file
View file

@ -0,0 +1,165 @@
################################################################################
# Logging functions
################################################################################
#region
function Print {
Param (
[String]$message,
[Switch]$NoNewLine
)
if ($NoNewLine) {
Write-Host " $message" -NoNewLine
} else {
Write-Host " $message"
}
}
function Print-Info {
Param (
[String]$message,
[Switch]$NoNewLine
)
if ([String]::IsNullOrEmpty($message)) {
return
}
Write-Host "[" -NoNewLine
Write-Host "+" -NoNewLine -ForegroundColor Green
Write-Host "]" -NoNewLine
if ($NoNewLine) {
Write-Host " $message" -NoNewLine
} else {
Write-Host " $message"
}
}
function Print-Warning {
Param (
[String]$message,
[Switch]$NoNewLine
)
if ([String]::IsNullOrEmpty($message)) {
return
}
Write-Host "[" -NoNewLine
Write-Host "!" -NoNewLine -ForegroundColor Magenta
Write-Host "]" -NoNewLine
if ($NoNewLine) {
Write-Host " $message" -NoNewLine
} else {
Write-Host " $message"
}
}
# Avoid stacktrace to be displayed along side the error message.
# We want things simplistic.
# src.: https://stackoverflow.com/q/38064704/3514658
# src.: https://stackoverflow.com/a/38064769
# We won't use [Console]::*Write* not $host.ui.Write* statements
# as they are UI items
# src.: https://web.archive.org/web/20190720224207/https://docs.microsoft.com/en-us/powershell/developer/cmdlet/types-of-cmdlet-output
# Rewriting the error printing function in C# and calling it from Posh is not
# working either because the redirection to stderr doesn't work under Posh but
# is working when the Posh script is run from cmd.exe. We are giving up here
# and simply using Write-Host without stderr redirection.
function Print-Error {
Param (
[String]$message,
[Switch]$NoNewLine
)
if ([String]::IsNullOrEmpty($message)) {
return
}
Write-Host "[" -NoNewLine
Write-Host "-" -NoNewLine -ForegroundColor Red
Write-Host "]" -NoNewLine
if ($NoNewLine) {
Write-Host " $message" -NoNewLine
} else {
Write-Host " $message"
}
}
# endregion
################################################################################
# OS related functions
################################################################################
# region
function Check-Command($cmdname) {
return [bool](Get-Command -Name $cmdname -ErrorAction SilentlyContinue)
}
function Refresh-Path {
$env:Path =
[System.Environment]::GetEnvironmentVariable("Path", "Machine") +
";" +
[System.Environment]::GetEnvironmentVariable("Path", "User")
}
function Get-RootDir {
return "$(Split-Path $PSCommandPath)\..\"
}
# endregion
################################################################################
# finding tools related functions
################################################################################
# region
function Get-WixDir {
$progFile = (${env:ProgramFiles(x86)}, ${env:ProgramFiles} -ne $null)[0]
$wixDirs = @(Get-ChildItem -Path $progFile -Recurse -Filter "*wix toolset*" -Attributes Directory -Depth 2 -ErrorAction SilentlyContinue)
if ($wixDirs[0] -eq $null) {
return $null
}
$wixDir = Join-Path -Path "$progFile" -ChildPath "$($wixDirs[0])"
$wixDir = Join-Path -Path "$wixDir" -ChildPath "bin"
return $wixDir
}
function Get-SignToolDir {
$progFile = (${env:ProgramFiles(x86)}, ${env:ProgramFiles} -ne $null)[0]
$signToolDir = Join-Path -Path "$progFile" -ChildPath "Windows Kits\10\bin\"
# Check if we are on 64 bits or not.
if ($env:PROCESSOR_ARCHITECTURE -ilike '*64*') {
$arch = "x64"
} else {
$arch = "x86"
}
[array]$signToolExes = (
Get-ChildItem -Path "$signToolDir" -Filter "signtool.exe" -Recurse -ErrorAction SilentlyContinue -Force | % {
if ($_.FullName -ilike '*x64*') {
return $_.FullName;
}
}
)
if ($signToolExes -eq $null -or
[string]::IsNullOrEmpty($signToolExes[0])) {
return $null
}
if (Test-Path $signToolExes[0]) {
return Split-Path $signToolExes[0]
}
return $null
}
function Get-NpmDir {
# npm is always installed as a nodejs dependency. 64 bits version available.
# C:\Program Files\nodejs\npm with a shortcut leading to
# C:\Program Files\nodejs\node_modules\npm\bin
$progFile = ${env:ProgramFiles}
$npmDir = Join-Path -Path "$progFile" -ChildPath "nodejs"
if ([System.IO.File]::Exists("$npmDir\npm.cmd")) {
return $npmDir
}
return $null
}
# endregion

2
scripts/wix311.sha Normal file
View file

@ -0,0 +1,2 @@
3f619089b46df893f55e58832ce442678fb0635f *./wix311.exe