mirror of
https://github.com/servo/servo.git
synced 2025-07-31 11:10:22 +01:00
Properly sign UWP package
This commit is contained in:
parent
e1f6dfd716
commit
f50f4df496
7 changed files with 77 additions and 18 deletions
|
@ -311,6 +311,8 @@ def windows_arm64():
|
||||||
return (
|
return (
|
||||||
windows_build_task("UWP dev build", arch="arm64", package=False)
|
windows_build_task("UWP dev build", arch="arm64", package=False)
|
||||||
.with_treeherder("Windows arm64", "UWP-Dev")
|
.with_treeherder("Windows arm64", "UWP-Dev")
|
||||||
|
.with_features("taskclusterProxy")
|
||||||
|
.with_scopes("secrets:get:project/servo/windows-codesign-cert/latest")
|
||||||
.with_script(
|
.with_script(
|
||||||
"python mach build --dev --target=aarch64-uwp-windows-msvc",
|
"python mach build --dev --target=aarch64-uwp-windows-msvc",
|
||||||
"python mach package --dev --target aarch64-uwp-windows-msvc --uwp=arm64",
|
"python mach package --dev --target aarch64-uwp-windows-msvc --uwp=arm64",
|
||||||
|
@ -324,6 +326,8 @@ def windows_uwp_x64():
|
||||||
return (
|
return (
|
||||||
windows_build_task("UWP dev build", package=False)
|
windows_build_task("UWP dev build", package=False)
|
||||||
.with_treeherder("Windows x64", "UWP-Dev")
|
.with_treeherder("Windows x64", "UWP-Dev")
|
||||||
|
.with_features("taskclusterProxy")
|
||||||
|
.with_scopes("secrets:get:project/servo/windows-codesign-cert/latest")
|
||||||
.with_script(
|
.with_script(
|
||||||
"python mach build --dev --target=x86_64-uwp-windows-msvc",
|
"python mach build --dev --target=x86_64-uwp-windows-msvc",
|
||||||
"python mach package --dev --target=x86_64-uwp-windows-msvc --uwp=x64",
|
"python mach package --dev --target=x86_64-uwp-windows-msvc --uwp=x64",
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
from __future__ import absolute_import, print_function, unicode_literals
|
from __future__ import absolute_import, print_function, unicode_literals
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
import base64
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
@ -20,6 +21,7 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import six.moves.urllib as urllib
|
import six.moves.urllib as urllib
|
||||||
|
import xml
|
||||||
|
|
||||||
from mach.decorators import (
|
from mach.decorators import (
|
||||||
CommandArgument,
|
CommandArgument,
|
||||||
|
@ -91,6 +93,15 @@ else:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
|
||||||
|
def get_taskcluster_secret(name):
|
||||||
|
url = (
|
||||||
|
os.environ.get("TASKCLUSTER_PROXY_URL", "http://taskcluster") +
|
||||||
|
"/api/secrets/v1/secret/project/servo/" +
|
||||||
|
name
|
||||||
|
)
|
||||||
|
return json.load(urllib.request.urlopen(url))["secret"]
|
||||||
|
|
||||||
|
|
||||||
def otool(s):
|
def otool(s):
|
||||||
o = subprocess.Popen(['/usr/bin/otool', '-L', s], stdout=subprocess.PIPE)
|
o = subprocess.Popen(['/usr/bin/otool', '-L', s], stdout=subprocess.PIPE)
|
||||||
for l in o.stdout:
|
for l in o.stdout:
|
||||||
|
@ -209,8 +220,9 @@ class PackageCommands(CommandBase):
|
||||||
default=None,
|
default=None,
|
||||||
action='append',
|
action='append',
|
||||||
help='Create an APPX package')
|
help='Create an APPX package')
|
||||||
|
@CommandArgument('--ms-app-store', default=None, action='store_true')
|
||||||
def package(self, release=False, dev=False, android=None, magicleap=None, debug=False,
|
def package(self, release=False, dev=False, android=None, magicleap=None, debug=False,
|
||||||
debugger=None, target=None, flavor=None, maven=False, uwp=None):
|
debugger=None, target=None, flavor=None, maven=False, uwp=None, ms_app_store=False):
|
||||||
if android is None:
|
if android is None:
|
||||||
android = self.config["build"]["android"]
|
android = self.config["build"]["android"]
|
||||||
if target and android:
|
if target and android:
|
||||||
|
@ -234,7 +246,7 @@ class PackageCommands(CommandBase):
|
||||||
target_dir = path.dirname(binary_path)
|
target_dir = path.dirname(binary_path)
|
||||||
if uwp:
|
if uwp:
|
||||||
vs_info = self.vs_dirs()
|
vs_info = self.vs_dirs()
|
||||||
build_uwp(uwp, dev, vs_info['msbuild'])
|
build_uwp(uwp, dev, vs_info['msbuild'], ms_app_store)
|
||||||
elif magicleap:
|
elif magicleap:
|
||||||
if platform.system() not in ["Darwin"]:
|
if platform.system() not in ["Darwin"]:
|
||||||
raise Exception("Magic Leap builds are only supported on macOS.")
|
raise Exception("Magic Leap builds are only supported on macOS.")
|
||||||
|
@ -588,14 +600,6 @@ class PackageCommands(CommandBase):
|
||||||
def upload_nightly(self, platform, secret_from_taskcluster):
|
def upload_nightly(self, platform, secret_from_taskcluster):
|
||||||
import boto3
|
import boto3
|
||||||
|
|
||||||
def get_taskcluster_secret(name):
|
|
||||||
url = (
|
|
||||||
os.environ.get("TASKCLUSTER_PROXY_URL", "http://taskcluster") +
|
|
||||||
"/api/secrets/v1/secret/project/servo/" +
|
|
||||||
name
|
|
||||||
)
|
|
||||||
return json.load(urllib.request.urlopen(url))["secret"]
|
|
||||||
|
|
||||||
def get_s3_secret():
|
def get_s3_secret():
|
||||||
aws_access_key = None
|
aws_access_key = None
|
||||||
aws_secret_access_key = None
|
aws_secret_access_key = None
|
||||||
|
@ -739,7 +743,59 @@ class PackageCommands(CommandBase):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def build_uwp(platforms, dev, msbuild_dir):
|
def setup_uwp_signing(ms_app_store):
|
||||||
|
# App package needs to be signed. If we find a certificate that has been installed
|
||||||
|
# already, we use it. Otherwise we create and install a temporary certificate.
|
||||||
|
|
||||||
|
if ms_app_store:
|
||||||
|
return ["/p:AppxPackageSigningEnabled=false"]
|
||||||
|
|
||||||
|
is_tc = "TASKCLUSTER_PROXY_URL" in os.environ
|
||||||
|
|
||||||
|
def run_powershell_cmd(cmd):
|
||||||
|
try:
|
||||||
|
return subprocess.check_output(['powershell.exe', '-NoProfile', '-Command', cmd])
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
print("ERROR: PowerShell command failed: ", cmd)
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
if is_tc:
|
||||||
|
print("Packaging on TC. Using secret certificate")
|
||||||
|
pfx = get_taskcluster_secret("windows-codesign-cert/latest")["pfx"]
|
||||||
|
open("servo.pfx", "wb").write(base64.b64decode(pfx["base64"]))
|
||||||
|
run_powershell_cmd('Import-PfxCertificate -FilePath .\servo.pfx -CertStoreLocation Cert:\CurrentUser\My')
|
||||||
|
os.remove("servo.pfx")
|
||||||
|
|
||||||
|
# Parse appxmanifest to find the publisher name
|
||||||
|
manifest_file = path.join(os.getcwd(), 'support', 'hololens', 'ServoApp', 'Package.appxmanifest')
|
||||||
|
manifest = xml.etree.ElementTree.parse(manifest_file)
|
||||||
|
namespace = "{http://schemas.microsoft.com/appx/manifest/foundation/windows10}"
|
||||||
|
publisher = manifest.getroot().find(namespace + "Identity").attrib["Publisher"]
|
||||||
|
# Powershell command that lists all certificates for publisher
|
||||||
|
cmd = '(dir cert: -Recurse | Where-Object {$_.Issuer -eq "' + publisher + '"}).Thumbprint'
|
||||||
|
certs = list(set(run_powershell_cmd(cmd).splitlines()))
|
||||||
|
if not certs and is_tc:
|
||||||
|
print("Error: No certificate installed for publisher " + publisher)
|
||||||
|
exit(1)
|
||||||
|
if not certs and not is_tc:
|
||||||
|
print("No certificate installed for publisher " + publisher)
|
||||||
|
print("Creating and installing a temporary certificate")
|
||||||
|
# PowerShell command that creates and install signing certificate for publisher
|
||||||
|
cmd = '(New-SelfSignedCertificate -Type Custom -Subject ' + publisher + \
|
||||||
|
' -FriendlyName "Allizom Signing Certificate (temporary)"' + \
|
||||||
|
' -KeyUsage DigitalSignature -CertStoreLocation "Cert:\CurrentUser\My"' + \
|
||||||
|
' -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}")).Thumbprint'
|
||||||
|
thumbprint = run_powershell_cmd(cmd)
|
||||||
|
elif len(certs) > 1:
|
||||||
|
print("Warning: multiple signing certificate are installed for " + publisher)
|
||||||
|
print("Warning: Using first one")
|
||||||
|
thumbprint = certs[0]
|
||||||
|
else:
|
||||||
|
thumbprint = certs[0]
|
||||||
|
return ["/p:AppxPackageSigningEnabled=true", "/p:PackageCertificateThumbprint=" + thumbprint]
|
||||||
|
|
||||||
|
|
||||||
|
def build_uwp(platforms, dev, msbuild_dir, ms_app_store):
|
||||||
if any(map(lambda p: p not in ['x64', 'x86', 'arm64'], platforms)):
|
if any(map(lambda p: p not in ['x64', 'x86', 'arm64'], platforms)):
|
||||||
raise Exception("Unsupported appx platforms: " + str(platforms))
|
raise Exception("Unsupported appx platforms: " + str(platforms))
|
||||||
if dev and len(platforms) > 1:
|
if dev and len(platforms) > 1:
|
||||||
|
@ -764,7 +820,8 @@ def build_uwp(platforms, dev, msbuild_dir):
|
||||||
)
|
)
|
||||||
build_file.close()
|
build_file.close()
|
||||||
# Generate an appxbundle.
|
# Generate an appxbundle.
|
||||||
subprocess.check_call([msbuild, "/m", build_file.name])
|
msbuild_args = setup_uwp_signing(ms_app_store)
|
||||||
|
subprocess.check_call([msbuild, "/m", build_file.name] + msbuild_args)
|
||||||
os.unlink(build_file.name)
|
os.unlink(build_file.name)
|
||||||
|
|
||||||
print("Creating ZIP")
|
print("Creating ZIP")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5" IgnorableNamespaces="uap mp uap5">
|
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5" IgnorableNamespaces="uap mp uap5">
|
||||||
<Identity Name="MozillaFoundation.FirefoxReality" Publisher="CN=193FE5E7-EFE6-4FC4-9D96-D742E0265B78" Version="1.0.0.0" />
|
<Identity Name="MozillaFoundation.FirefoxReality" Publisher="CN=Allizom" Version="1.0.0.0" />
|
||||||
<mp:PhoneIdentity PhoneProductId="1d265729-8836-4bd3-9992-4cb111d1068b" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
<mp:PhoneIdentity PhoneProductId="1d265729-8836-4bd3-9992-4cb111d1068b" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||||
<Properties>
|
<Properties>
|
||||||
<DisplayName>Firefox Reality</DisplayName>
|
<DisplayName>Firefox Reality</DisplayName>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<Import Project="..\packages\OpenXR.Loader.1.0.3\build\native\OpenXR.Loader.props" Condition="Exists('..\packages\OpenXR.Loader.1.0.3\build\native\OpenXR.Loader.props')" />
|
<Import Project="..\packages\OpenXR.Loader.1.0.3\build\native\OpenXR.Loader.props" Condition="Exists('..\packages\OpenXR.Loader.1.0.3\build\native\OpenXR.Loader.props')" />
|
||||||
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.190620.2\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.190620.2\build\native\Microsoft.Windows.CppWinRT.props')" />
|
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.190620.2\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.190620.2\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||||
|
@ -870,7 +870,6 @@
|
||||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\z-1.dll">
|
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\z-1.dll">
|
||||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
|
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
|
||||||
</None>
|
</None>
|
||||||
<None Include="ServoApp_TemporaryKey.pfx" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="Assets\LargeTile.scale-100.png" />
|
<Image Include="Assets\LargeTile.scale-100.png" />
|
||||||
|
|
|
@ -159,7 +159,6 @@
|
||||||
<AppxManifest Include="Package.appxmanifest" />
|
<AppxManifest Include="Package.appxmanifest" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="ServoApp_TemporaryKey.pfx" />
|
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\simpleservo.dll">
|
<None Include="..\..\..\target\x86_64-uwp-windows-msvc\release\simpleservo.dll">
|
||||||
<Filter>ReleaseServoDLLs</Filter>
|
<Filter>ReleaseServoDLLs</Filter>
|
||||||
|
|
Binary file not shown.
|
@ -9,6 +9,6 @@
|
||||||
</ConfigAndPlatform>
|
</ConfigAndPlatform>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<MSBuild Projects="%%SOLUTION%%" Targets="Build"
|
<MSBuild Projects="%%SOLUTION%%" Targets="Build"
|
||||||
Properties="Configuration=%(ConfigAndPlatform.Identity);Platform=%(ConfigAndPlatform.Platform);AppxBundle=Always;AppxBundlePlatforms=%%PACKAGE_PLATFORMS%%;UseSubFolderForOutputDirDuringMultiPlatformBuild=false;AppxPackageSigningEnabled=false"/>
|
Properties="Configuration=%(ConfigAndPlatform.Identity);Platform=%(ConfigAndPlatform.Platform);AppxBundle=Always;AppxBundlePlatforms=%%PACKAGE_PLATFORMS%%;UseSubFolderForOutputDirDuringMultiPlatformBuild=false"/>
|
||||||
</Target>
|
</Target>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue