Remake packages (#485)

* Remove isxdl

* Fix targets bools

* Fix builder base dir

* Update builder innosetup build

* Fix builder build

* Run ps script function

* Fix ps script function

* Print build results

* Fix dict

* Function add_task

* Fix results log

* Add deploy

* Fix deploy

* Add core deploy

* Fix core deploy

* Debug scripts

* Fix workspace_dir

* Refactoring core

* Refactoring core

* Fix platforms

* Refactoring builder

* Small fix

* Fix core

* Fix cmd

* Refactoring builder

* Fix builder

* Fix

* Fix

* Fix server

* Fix builder

* Fix desktop linux

* Fix desktop windows

* Add appcast-prod creation

* Fix appcast

* Fix vcredist verbose

* Fix appcast

* Small fix builder

* Small fix desktop

* Small fix desktop linux

* Fix desktop macos

* Check vc redist md5 sums

* Fix kwargs

* Fix log_h1

* Fix macos fastlane params
This commit is contained in:
Semyon Bezrukov
2022-07-05 15:34:00 +03:00
committed by GitHub
parent d3d53b983a
commit 14522ee010
9 changed files with 751 additions and 488 deletions

View File

@ -2,17 +2,84 @@
# -*- coding: utf-8 -*-
import sys
sys.path.append('scripts')
sys.path.append("scripts")
import argparse
import package_common as common
import package_utils as utils
import package_core
import package_desktop
import package_server
import package_builder
# config
utils.parse()
# parse
parser = argparse.ArgumentParser(description="Build packages.")
parser.add_argument("-P", "--platform", dest="platform", type=str,
action="store", help="Defines platform", required=True)
parser.add_argument("-T", "--targets", dest="targets", type=str, nargs="+",
action="store", help="Defines targets", required=True)
parser.add_argument("-R", "--branding", dest="branding", type=str,
action="store", help="Provides branding path")
parser.add_argument("-V", "--version", dest="version", type=str,
action="store", help="Defines version")
parser.add_argument("-B", "--build", dest="build", type=str,
action="store", help="Defines build")
args = parser.parse_args()
# vars
common.workspace_dir = utils.get_abspath(utils.get_script_dir(__file__) + "/..")
common.os_family = utils.host_platform()
common.platform = args.platform
common.targets = args.targets
common.clean = "clean" in args.targets
common.sign = "sign" in args.targets
common.deploy = "deploy" in args.targets
common.version = args.version if (args.version is not None) else utils.get_env("PRODUCT_VERSION", "1.0.0")
common.build = args.build if (args.build is not None) else utils.get_env("BUILD_NUMBER", "1")
common.branding = args.branding
common.timestamp = utils.get_timestamp()
common.summary = {}
common.deploy_list = []
utils.log("workspace_dir: " + common.workspace_dir)
utils.log("os_family: " + common.os_family)
utils.log("platform: " + str(common.platform))
utils.log("targets: " + str(common.targets))
utils.log("clean: " + str(common.clean))
utils.log("sign: " + str(common.sign))
utils.log("deploy: " + str(common.deploy))
utils.log("version: " + common.version)
utils.log("build: " + common.build)
utils.log("branding: " + str(common.branding))
utils.log("timestamp: " + common.timestamp)
utils.set_cwd(common.workspace_dir, verbose=True)
# branding
if utils.branding is not None:
branding_path = utils.get_path('..', utils.branding)
sys.path.insert(-1, utils.get_path(branding_path, 'build_tools/scripts'))
if common.branding is not None:
sys.path.insert(-1, utils.get_path(common.branding + "/build_tools/scripts"))
# build
import package
package.make(utils.product)
if "core" in common.targets:
package_core.make()
if "desktop" in common.targets:
package_desktop.make()
if "builder" in common.targets:
package_builder.make()
if "server-ce" in common.targets:
package_server.make("community")
if "server-ee" in common.targets:
package_server.make("enterprise")
if "server-de" in common.targets:
package_server.make("developer")
# if "mobile" in common.targets:
# package_mobile.make()
# summary
utils.log_h1("Build summary")
exitcode = 0
for task, rc in common.summary.items():
if rc == 0:
utils.log("[ OK ] " + task)
else:
utils.log("[FAILED] " + task)
exitcode = 1
exit(exitcode)

View File

@ -1,12 +0,0 @@
#!/usr/bin/env python
import package_desktop
import package_server
import package_builder
def make(product):
if product == 'desktop': package_desktop.make()
elif product == 'server': package_server.make()
elif product == 'builder': package_builder.make()
else: exit(1)
return

View File

@ -1,44 +1,34 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from package_utils import *
import package_utils as utils
onlyoffice = True
company_name = 'ONLYOFFICE'
company_name = "ONLYOFFICE"
company_name_l = company_name.lower()
publisher_name = 'Ascensio System SIA'
cert_name = 'Ascensio System SIA'
publisher_name = "Ascensio System SIA"
cert_name = "Ascensio System SIA"
if product == 'desktop':
if utils.is_windows():
desktop_product_name = "Desktop Editors"
desktop_product_name_s = desktop_product_name.replace(" ","")
desktop_package_name = company_name + "_" + desktop_product_name_s
desktop_vcredist_list = ["2022"]
desktop_update_changes_list = {
"en": "changes",
"ru": "changes_ru"
}
if system == 'windows':
build_dir = get_path("desktop-apps/win-linux/package/windows")
# branding_dir = get_path(branding, build_dir)
product_name = 'Desktop Editors'
product_name_s = product_name.replace(' ','')
package_name = company_name + '_' + product_name_s
vcredist_list = ['2022']
update_changes_list = {
'en': "changes",
'ru': "changes_ru"
}
if utils.is_macos():
desktop_package_name = "ONLYOFFICE"
desktop_build_dir = "desktop-apps/macos"
desktop_branding_dir = "desktop-apps/macos"
desktop_updates_dir = "build/update"
desktop_changes_dir = "ONLYOFFICE/update/updates/ONLYOFFICE/changes"
desktop_update_changes_list = {
"en": "ReleaseNotes",
"ru": "ReleaseNotesRU"
}
sparkle_base_url = "https://download.onlyoffice.com/install/desktop/editors/mac"
elif system == 'darwin':
build_dir = "desktop-apps/macos"
branding_build_dir = "desktop-apps/macos"
package_name = company_name
updates_dir = "build/update"
changes_dir = "ONLYOFFICE/update/updates/ONLYOFFICE/changes"
update_changes_list = {
'en': "ReleaseNotes",
'ru': "ReleaseNotesRU"
}
sparkle_base_url = "https://download.onlyoffice.com/install/desktop/editors/mac"
if product == 'builder':
if system == 'windows':
build_dir = "document-builder-package"
product_name = 'Document Builder'
product_name_s = product_name.replace(' ','')
package_name = company_name + '_' + product_name_s
builder_product_name = "Document Builder"

View File

@ -1,101 +1,118 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from package_utils import *
from package_branding import *
import package_utils as utils
import package_common as common
import package_branding as branding
def make():
if system == 'windows':
utils.log_h1("BUILDER")
if utils.is_windows():
make_windows()
elif system == 'linux':
if 'packages' in targets:
set_cwd(build_dir)
log("Clean")
cmd("make", ["clean"])
log("Build packages")
cmd("make", ["packages"])
elif utils.is_linux():
make_linux()
else:
exit(1)
utils.log("Unsupported host OS")
return
#
# Windows
#
def make_windows():
global package_version, sign, machine, arch, source_dir, base_dir, \
innosetup_file, portable_zip_file, isxdl_file
base_dir = "base"
isxdl_file = "exe/scripts/isxdl/isxdl.dll"
global inno_file, zip_file
utils.set_cwd("document-builder-package")
set_cwd(get_abspath(git_dir, build_dir))
prefix = common.platforms[common.platform]["prefix"]
company = branding.company_name.lower()
product = branding.builder_product_name.replace(" ","").lower()
source_dir = "..\\build_tools\\out\\%s\\%s\\%s" % (prefix, company, product)
package_name = company + "_" + product
package_version = common.version + "." + common.build
suffixes = {
"windows_x64": "x64",
"windows_x86": "x86",
"windows_x64_xp": "x64_xp",
"windows_x86_xp": "x86_xp"
}
suffix = suffixes[common.platform]
zip_file = "%s_%s_%s.zip" % (package_name, package_version, suffix)
inno_file = "%s_%s_%s.exe" % (package_name, package_version, suffix)
if 'clean' in targets:
log("\n=== Clean\n")
delete_dir(base_dir)
delete_files(isxdl_file)
delete_files("exe/*.exe")
delete_files("zip/*.zip")
if common.clean:
utils.log_h1("clean")
utils.delete_dir("build")
package_version = version + '.' + build
sign = 'sign' in targets
utils.log_h1("copy arifacts")
utils.create_dir("build\\app")
utils.copy_dir_content(source_dir, "build\\app\\")
for target in targets:
if not (target.startswith('innosetup') or target.startswith('portable')):
continue
# if "builder-zip" in common.targets:
make_zip()
# if "builder-inno" in common.targets:
make_inno()
machine = get_platform(target)['machine']
arch = get_platform(target)['arch']
suffix = arch
source_prefix = "win_" + machine
source_dir = get_path("%s/%s/%s/%s" % (out_dir, source_prefix, company_name_l, product_name_s))
log("\n=== Copy arifacts\n")
create_dir(base_dir)
copy_dir_content(source_dir, base_dir + '\\')
if target.startswith('innosetup'):
download_isxdl()
innosetup_file = "exe/%s_%s_%s.exe" % (package_name, package_version, suffix)
make_innosetup()
if target.startswith('portable'):
portable_zip_file = "zip/%s_%s_%s.zip" % (package_name, package_version, suffix)
make_win_portable()
utils.set_cwd(common.workspace_dir)
return
def download_isxdl():
log("\n=== Download isxdl\n")
log("--- " + isxdl_file)
if is_file(isxdl_file):
log("! file exist, skip")
return
create_dir(get_dirname(isxdl_file))
download_file(isxdl_link, isxdl_file)
def make_zip():
common.summary["builder zip build"] = 1
utils.log_h1("zip build " + zip_file)
rc = utils.cmd("7z", "a", "-y", zip_file, ".\\app\\*",
chdir="build", creates="build\\" + zip_file, verbose=True)
common.summary["builder zip build"] = rc
# common.summary["zip deploy"] = 1
# if rc == 0:
# utils.log_h1("zip deploy " + zip_file)
# dest = "s3://" + common.s3_bucket + "/onlyoffice/experimental/windows/builder/" \
# + common.version + "/" + common.build + "/"
# rc = utils.cmd(
# "aws", "s3", "cp", "--acl", "public-read", "--no-progress",
# "build\\" + zip_file, dest,
# verbose=True
# )
# common.summary["zip deploy"] = rc
return
def make_innosetup():
log("\n=== Build innosetup project\n")
iscc_args = ["/DVERSION=" + package_version]
if not onlyoffice:
iscc_args.append("/DBRANDING_DIR=" + get_abspath(git_dir, branding, build_dir, "exe"))
if sign:
iscc_args.append("/DSIGN")
iscc_args.append("/Sbyparam=signtool.exe sign /v /n $q" + cert_name + "$q /t " + tsa_server + " $f")
log("--- " + innosetup_file)
if is_file(innosetup_file):
log("! file exist, skip")
return
set_cwd("exe")
cmd("iscc", iscc_args + ["builder.iss"])
set_cwd("..")
def make_inno():
common.summary["builder inno build"] = 1
utils.log_h1("inno build " + inno_file)
# if utils.is_file(inno_file):
# utils.log("! file exist, skip")
# return
args = ["-Version " + common.version, "-Build " + common.build]
if not branding.onlyoffice:
args.append("-Branding '..\\..\\%s\\document-builder-package\\exe'" % common.branding)
if common.sign:
args.append("-Sign")
args.append("-CertName '%s'" % branding.cert_name)
rc = utils.ps1(".\\make_inno.ps1", args,
creates="build\\" + inno_file, verbose=True)
common.summary["builder inno build"] = rc
# common.summary["inno deploy"] = 1
# if rc == 0:
# utils.log_h1("inno deploy " + inno_file)
# dest = "s3://" + common.s3_bucket + "/onlyoffice/experimental/windows/builder/" \
# + common.version + "/" + common.build + "/"
# rc = utils.cmd(
# "aws", "s3", "cp", "--acl", "public-read", "--no-progress",
# "build\\" + inno_file, dest,
# verbose=True
# )
# common.summary["inno deploy"] = rc
return
def make_win_portable():
log("\n=== Build portable\n")
log("--- " + portable_zip_file)
if is_file(portable_zip_file):
log("! file exist, skip")
return
cmd("7z", ["a", "-y", portable_zip_file, get_path(base_dir, "*")])
def make_linux():
utils.set_cwd("document-builder-package")
rc = utils.sh("make clean", verbose=True)
common.summary["builder clean"] = rc
args = []
if common.platform == "linux_aarch64":
args += ["-e", "UNAME_M=aarch64"]
if not branding.onlyoffice:
args += ["-e", "BRANDING_DIR=../" + common.branding + "/document-builder-package"]
rc = utils.sh("make packages " + " ".join(args), verbose=True)
common.summary["builder build"] = rc
utils.set_cwd(common.workspace_dir)
return

52
scripts/package_common.py Normal file
View File

@ -0,0 +1,52 @@
#!/usr/bin/env python
platforms = {
"windows_x64": { "title": "Windows x64", "prefix": "win_64", "arch": "x64" },
"windows_x64_xp": { "title": "Windows x64 XP", "prefix": "win_64_xp", "arch": None },
"windows_x86": { "title": "Windows x86", "prefix": "win_32", "arch": "x86" },
"windows_x86_xp": { "title": "Windows x86 XP", "prefix": "win_32_xp", "arch": None },
"darwin_x86_64": { "title": "macOS x86_64", "prefix": "mac_64", "arch": "x64" },
"darwin_x86_64_v8": { "title": "macOS x86_64 V8", "prefix": "mac_64", "arch": None },
"darwin_arm64": { "title": "macOS arm64", "prefix": "mac_arm64", "arch": None },
"linux_x86_64": { "title": "Linux x86_64", "prefix": "linux_64", "arch": "x64" },
"linux_aarch64": { "title": "Linux aarch64", "prefix": "linux_arm64", "arch": None },
"android": { "title": "Android" }
}
out_dir = "build_tools/out"
# s3_bucket = "repo-doc-onlyoffice-com"
s3_bucket = "deploytest-static.teamlab.com"
s3_region = "eu-west-1"
tsa_server = "http://timestamp.digicert.com"
vcredist_links = {
"2022": {
"x64": {
"url": "https://aka.ms/vs/17/release/vc_redist.x64.exe",
"md5": "cdce5d5ee259d8071fa82f522c5c7d6e"
},
"x86": {
"url": "https://aka.ms/vs/17/release/vc_redist.x86.exe",
"md5": "dd89ae7bc09cad5648524905d0f53214"
}
},
"2015": {
"x64": {
"url": "https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x64.exe",
"md5": "27b141aacc2777a82bb3fa9f6e5e5c1c"
},
"x86": {
"url": "https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x86.exe",
"md5": "1a15e6606bac9647e7ad3caa543377cf"
}
},
"2013": {
"x64": {
"url": "https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe",
"md5": "96b61b8e069832e6b809f24ea74567ba"
},
"x86": {
"url": "https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x86.exe",
"md5": "0fc525b6b7b96a87523daa7a0013c69d"
}
}
}

60
scripts/package_core.py Normal file
View File

@ -0,0 +1,60 @@
#!/usr/bin/env python
import package_utils as utils
import package_common as common
import package_branding as branding
def make():
utils.log_h1("CORE")
if not (utils.is_windows() or utils.is_macos() or utils.is_linux()):
utils.log("Unsupported host OS")
return
if common.deploy:
make_core()
return
def make_core():
prefix = common.platforms[common.platform]["prefix"]
company = branding.company_name.lower()
repos = {
"windows": "windows",
"darwin": "mac",
"linux": "linux"
}
branch = utils.get_env("BRANCH_NAME")
if branch is None:
utils.log("BRANCH_NAME variable is undefined")
return
arch = common.platforms[common.platform]["arch"]
if utils.is_windows():
version = common.version + "." + common.build
else:
version = common.version + "-" + common.build
src = "build_tools/out/%s/%s/core/core.7z" % (prefix, company)
dest = common.s3_bucket + "/" + repos[common.os_family] + "/core/" \
+ branch + "/%s/" + arch + "/"
utils.log_h1("core deploy")
common.summary["core deploy"] = 1
ret = utils.cmd(
"aws", "s3", "cp",
"--acl", "public-read", "--no-progress",
utils.get_path(src), "s3://" + dest % version,
verbose=True
)
if ret == 0:
common.deploy_list.append({
"product": "core",
"platform": common.platform,
"section": "Archive",
"path": dest % version + "core.7z",
"size": utils.get_file_size(utils.get_path(src))
})
ret = utils.cmd(
"aws", "s3", "sync",
"--delete", "--acl", "public-read", "--no-progress",
"s3://" + dest % version, "s3://" + dest % "latest",
verbose=True
)
common.summary["core deploy"] = ret
return

View File

@ -2,23 +2,20 @@
# -*- coding: utf-8 -*-
import os
from package_utils import *
from package_branding import *
import package_utils as utils
import package_common as common
import package_branding as branding
def make():
if system == 'windows':
utils.log_h1("DESKTOP")
if utils.is_windows():
make_windows()
elif system == 'darwin':
elif utils.is_macos():
make_macos()
elif system == 'linux':
if 'packages' in targets:
set_cwd(build_dir)
log("Clean")
cmd("make", ["clean"])
log("Build packages")
cmd("make", ["packages"])
elif utils.is_linux():
make_linux()
else:
exit(1)
utils.log("Unsupported host OS")
return
#
@ -26,174 +23,202 @@ def make():
#
def make_windows():
global package_version, sign, machine, arch, xp, iscc_args, source_dir, \
innosetup_file, innosetup_update_file, advinst_file, portable_zip_file
global package_version, iscc_args, source_dir, arch_list, inno_arch_list, \
inno_file, inno_update_file, msi_file, zip_file
utils.set_cwd("desktop-apps\\win-linux\\package\\windows")
set_cwd(get_abspath(git_dir, build_dir))
prefix = common.platforms[common.platform]["prefix"]
company = branding.company_name.lower()
product = branding.desktop_product_name.replace(" ","").lower()
package_name = branding.desktop_package_name
package_version = common.version + "." + common.build
source_dir = "..\\..\\..\\..\\build_tools\\out\\%s\\%s\\%s" % (prefix, company, product)
arch_list = {
"windows_x64": "x64",
"windows_x64_xp": "x64",
"windows_x86": "x86",
"windows_x86_xp": "x86"
}
inno_arch_list = {
"windows_x64": "64",
"windows_x86": "32",
"windows_x64_xp": "64",
"windows_x86_xp": "32"
}
suffix = arch_list[common.platform]
if common.platform.endswith("_xp"): suffix += "_xp"
zip_file = "%s_%s_%s.zip" % (package_name, package_version, suffix)
inno_file = "%s_%s_%s.exe" % (package_name, package_version, suffix)
inno_update_file = "update\\editors_update_%s.exe" % suffix
msi_file = "%s_%s_%s.msi" % (package_name, package_version, suffix)
if 'clean' in targets:
log("\n=== Clean\n")
delete_dir(get_path("data/vcredist"))
delete_dir("DesktopEditors-cache")
delete_files("*.exe")
delete_files("*.msi")
delete_files("*.aic")
delete_files("*.tmp")
delete_files("*.zip")
delete_files(get_path("update/*.exe"))
delete_files(get_path("update/*.xml"))
delete_files(get_path("update/*.html"))
if common.clean:
utils.log_h2("desktop clean")
# utils.delete_dir("data\\vcredist")
utils.delete_dir("DesktopEditors-cache")
utils.delete_files("*.exe")
utils.delete_files("*.msi")
utils.delete_files("*.aic")
utils.delete_files("*.tmp")
utils.delete_files("*.zip")
utils.delete_files("update\\*.exe")
utils.delete_files("update\\*.xml")
utils.delete_files("update\\*.html")
package_version = version + '.' + build
sign = 'sign' in targets
make_zip()
for target in targets:
if not (target.startswith('innosetup') or target.startswith('advinst') or
target.startswith('portable')):
continue
vc_total = True
for year in branding.desktop_vcredist_list:
if download_vcredist(year) != 0:
vc_total = False
machine = get_platform(target)['machine']
arch = get_platform(target)['arch']
xp = get_platform(target)['xp']
suffix = arch + ("_xp" if xp else "")
source_prefix = "win_" + machine + ("_xp" if xp else "")
source_dir = get_path("%s/%s/%s/%s" % (out_dir, source_prefix, company_name_l, product_name_s))
if vc_total:
common.summary["desktop inno build"] = 1
common.summary["desktop inno update build"] = 1
common.summary["desktop advinst build"] = 1
return
if target.startswith('innosetup'):
for year in vcredist_list:
download_vcredist(year)
make_inno()
make_inno_update()
innosetup_file = "%s_%s_%s.exe" % (package_name, package_version, suffix)
make_innosetup()
if common.platform == "windows_x64":
make_winsparkle_files()
if 'winsparkle-update' in targets:
innosetup_update_file = get_path("update/editors_update_%s.exe" % suffix)
make_innosetup_update()
if common.platform in ["windows_x64", "windows_x86"]:
make_msi()
if 'winsparkle-files' in targets:
make_winsparkle_files()
if target.startswith('advinst'):
advinst_file = "%s_%s_%s.msi" % (package_name, package_version, suffix)
make_advinst()
if target.startswith('portable'):
portable_zip_file = "%s_%s_%s.zip" % (package_name, package_version, suffix)
make_win_portable()
utils.set_cwd(common.workspace_dir)
return
def make_zip():
utils.log_h1("desktop zip build")
utils.log_h2(zip_file)
rc = utils.cmd("7z", "a", "-y", zip_file, source_dir + "\\*",
creates=zip_file, verbose=True)
common.summary["desktop zip build"] = rc
return
def download_vcredist(year):
log("\n=== Download vcredist " + year + "\n")
vcredist = get_path("data/vcredist/vcredist_%s_%s.exe" % (year, arch))
log("--- " + vcredist)
if is_file(vcredist):
log("! file exist, skip")
return
create_dir(get_dirname(vcredist))
download_file(vcredist_links[year][machine], vcredist)
return
utils.log_h1("download vcredist " + year)
def make_innosetup():
log("\n=== Build innosetup project\n")
arch = arch_list[common.platform]
link = common.vcredist_links[year][arch]["url"]
md5 = common.vcredist_links[year][arch]["md5"]
vcredist_file = "data\\vcredist\\vcredist_%s_%s.exe" % (year, arch)
utils.log_h2(vcredist_file)
utils.create_dir(utils.get_dirname(vcredist_file))
rc = utils.download_file(link, vcredist_file, md5, verbose=True)
common.summary["desktop vcredist download"] = rc
return rc
def make_inno():
global iscc_args
utils.log_h1("innosetup project build")
utils.log_h2(inno_file)
iscc_args = [
"/Qp",
# "/Qp",
"/DsAppVersion=" + package_version,
"/DDEPLOY_PATH=" + source_dir,
"/D_ARCH=" + machine
"/D_ARCH=" + inno_arch_list[common.platform]
]
if onlyoffice:
if branding.onlyoffice:
iscc_args.append("/D_ONLYOFFICE=1")
else:
iscc_args.append("/DsBrandingFolder=" + get_abspath(git_dir, branding_dir))
if xp:
iscc_args.append("/DsBrandingFolder=..\\..\\..\\..\\" + common.branding + \
"\\desktop-apps\\win-linux\\package\\windows")
if common.platform in ["windows_x64_xp", "windows_x86_xp"]:
iscc_args.append("/D_WIN_XP=1")
if sign:
if common.sign:
iscc_args.append("/DENABLE_SIGNING=1")
iscc_args.append("/Sbyparam=signtool.exe sign /v /n $q" + cert_name + "$q /t " + tsa_server + " $f")
log("--- " + innosetup_file)
if is_file(innosetup_file):
log("! file exist, skip")
return
cmd("iscc", iscc_args + ["common.iss"])
iscc_args.append("/Sbyparam=signtool.exe sign /v /n $q" + \
branding.cert_name + "$q /t " + common.tsa_server + " $f")
args = ["iscc"] + iscc_args + ["common.iss"]
rc = utils.cmd(*args, creates=inno_file, verbose=True)
common.summary["desktop inno build"] = rc
return
def make_innosetup_update():
log("\n=== Build innosetup update project\n")
log("--- " + innosetup_update_file)
if is_file(innosetup_update_file):
log("! file exist, skip")
return
cmd("iscc", iscc_args + ["/DTARGET_NAME=" + innosetup_file, "update_common.iss"])
def make_inno_update():
utils.log_h1("build innosetup update project")
utils.log_h2(inno_update_file)
args = ["iscc"] + iscc_args + ["/DTARGET_NAME=" + inno_file, "update_common.iss"]
rc = utils.cmd(*args, creates=inno_update_file, verbose=True)
common.summary["desktop inno update build"] = rc
return
def make_winsparkle_files():
log("\n=== Build winsparkle files\n")
utils.log_h1("winsparkle files build")
awk_branding = "update/branding.awk"
if not onlyoffice:
build_branding_dir = get_abspath(git_dir, branding_dir, "win-linux/package/windows")
if branding.onlyoffice:
awk_branding = "update/branding.awk"
else:
build_branding_dir = get_path(".")
awk_branding = "../../../../" + common.branding + \
"/desktop-apps/win-linux/package/windows/update/branding.awk"
awk_args = [
"-v", "Version=" + version,
"-v", "Build=" + build,
"-v", "Timestamp=" + timestamp,
"-i", get_path(build_branding_dir, awk_branding)
"-v", "Version=" + common.version,
"-v", "Build=" + common.build,
"-v", "Timestamp=" + common.timestamp,
"-i", awk_branding
]
appcast = get_path("update/appcast.xml")
log("--- " + appcast)
if is_file(appcast):
log("! file exist, skip")
else:
command = "env LANG=en_US.UTF-8 awk " + ' '.join(awk_args) + \
" -f " + appcast + ".awk"
appcast_result = proc_open(command)
if appcast_result['stderr'] != "":
log("! error: " + appcast_result['stderr'])
write_file(appcast, appcast_result['stdout'])
appcast = "update/appcast.xml"
utils.log_h2(appcast)
args = ["env", "LANG=en_US.UTF-8", "awk"] + \
awk_args + ["-f", "update/appcast.xml.awk"]
appcast_result = utils.cmd_output(*args, verbose=True)
utils.write_file(appcast, appcast_result)
changes_dir = get_path(build_branding_dir, "update/changes", version)
for lang, base in update_changes_list.items():
changes = get_path("update/" + base + ".html")
if lang == 'en': encoding = 'en_US.UTF-8'
elif lang == 'ru': encoding = 'ru_RU.UTF-8'
log("--- " + changes)
if is_file(changes):
log("! file exist, skip")
appcast_prod = "update/appcast-prod.xml"
utils.log_h2(appcast_prod)
args = ["env", "LANG=en_US.UTF-8", "awk", "-v", "Prod=1"] + \
awk_args + ["-f", "update/appcast.xml.awk"]
appcast_result = utils.cmd_output(*args, verbose=True)
utils.write_file(appcast, appcast_result)
if branding.onlyoffice:
changes_dir = "update/changes/" + common.version
else:
changes_dir = "../../../../" + common.branding + \
"/desktop-apps/win-linux/package/windows/update/changes/" + common.version
for lang, base in branding.desktop_update_changes_list.items():
changes = "update/%s.html" % base
if lang == "en": encoding = "en_US.UTF-8"
elif lang == "ru": encoding = "ru_RU.UTF-8"
utils.log_h2(changes)
changes_file = "%s/%s.html" % (changes_dir, lang)
args = ["env", "LANG=" + encoding, "awk"] + awk_args + \
["-f", "update/changes.html.awk", changes_file]
if utils.is_exist(changes_file):
changes_result = utils.cmd_output(*args, verbose=True)
print(changes_result)
utils.write_file(changes, changes_result)
else:
command = "env LANG=" + encoding + " awk " + ' '.join(awk_args) + \
" -f update\\changes.html.awk " + changes_dir + "\\" + lang + ".html"
changes_result = proc_open(command)
if changes_result['stderr'] != "":
log("! error: " + changes_result['stderr'])
write_file(changes, changes_result['stdout'])
utils.log("! file not exist: " + changes_file)
return
def make_advinst():
log("\n=== Build advanced installer project\n")
log("--- " + advinst_file)
if is_file(advinst_file):
log("! file exist, skip")
return
def make_msi():
utils.log_h1("advanced installer project build")
utils.log_h2(msi_file)
arch = arch_list[common.platform]
aic_content = [";aic"]
if not onlyoffice:
copy_dir_content(
get_abspath(git_dir, branding_dir, "win-linux/package/windows/data"),
"data", ".bmp")
copy_dir_content(
get_abspath(git_dir, branding_dir, "win-linux/package/windows/data"),
"data", ".png")
if not branding.onlyoffice:
utils.copy_dir_content("..\\..\\..\\..\\" + common.branding + \
"\\desktop-apps\\win-linux\\package\\windows\\data", "data", ".bmp")
utils.copy_dir_content("..\\..\\..\\..\\" + common.branding + \
"\\desktop-apps\\win-linux\\package\\windows\\data", "data", ".png")
aic_content += [
"SetProperty ProductName=\"%s\"" % product_name_full,
"SetProperty Manufacturer=\"%s\"" % publisher_name.replace('"', '""'),
"SetProperty ARPURLINFOABOUT=\"%s\"" % info_about_url,
"SetProperty ARPURLUPDATEINFO=\"%s\"" % update_info_url,
"SetProperty ARPHELPLINK=\"%s\"" % help_url,
"SetProperty ARPHELPTELEPHONE=\"%s\"" % help_phone,
"SetProperty ARPCONTACT=\"%s\"" % publisher_address,
"SetProperty ProductName=\"%s\"" % branding.desktop_product_name_full,
"SetProperty Manufacturer=\"%s\"" % branding.desktop_publisher_name.replace('"', '""'),
"SetProperty ARPURLINFOABOUT=\"%s\"" % branding.desktop_info_about_url,
"SetProperty ARPURLUPDATEINFO=\"%s\"" % branding.desktop_update_info_url,
"SetProperty ARPHELPLINK=\"%s\"" % branding.desktop_help_url,
"SetProperty ARPHELPTELEPHONE=\"%s\"" % branding.desktop_help_phone,
"SetProperty ARPCONTACT=\"%s\"" % branding.desktop_publisher_address,
"DelLanguage 1029 -buildname DefaultBuild",
"DelLanguage 1031 -buildname DefaultBuild",
"DelLanguage 1041 -buildname DefaultBuild",
@ -204,28 +229,20 @@ def make_advinst():
"DelLanguage 3082 -buildname DefaultBuild",
"DelLanguage 1033 -buildname DefaultBuild"
]
if not sign: aic_content.append("ResetSig")
if machine == '32': aic_content.append("SetPackageType x86")
if not common.sign: aic_content.append("ResetSig")
if arch == "x86": aic_content.append("SetPackageType x86")
aic_content += [
"AddOsLc -buildname DefaultBuild -arch " + arch,
"NewSync APPDIR " + source_dir + " -existingfiles delete",
"UpdateFile APPDIR\\DesktopEditors.exe " + get_path(source_dir, "DesktopEditors.exe"),
"UpdateFile APPDIR\\DesktopEditors.exe " + source_dir + "\\DesktopEditors.exe",
"SetVersion " + package_version,
"SetPackageName " + advinst_file + " -buildname DefaultBuild",
"SetPackageName " + msi_file + " -buildname DefaultBuild",
"Rebuild -buildslist DefaultBuild"
]
write_file("DesktopEditors.aic", "\r\n".join(aic_content), 'utf-8-sig')
cmd("AdvancedInstaller.com",
["/execute", "DesktopEditors.aip", "DesktopEditors.aic", "-nofail"])
return
def make_win_portable():
log("\n=== Build portable\n")
log("--- " + portable_zip_file)
if is_file(portable_zip_file):
log("! file exist, skip")
return
cmd("7z", ["a", "-y", portable_zip_file, get_path(source_dir, "*")])
utils.write_file("DesktopEditors.aic", "\r\n".join(aic_content), "utf-8-sig")
rc = utils.cmd("AdvancedInstaller.com", "/execute", \
"DesktopEditors.aip", "DesktopEditors.aic", "-nofail", verbose=True)
common.summary["desktop advinst build"] = rc
return
#
@ -233,88 +250,130 @@ def make_win_portable():
#
def make_macos():
global suffix, lane, scheme
global package_name, build_dir, branding_dir, updates_dir, changes_dir, \
update_changes_list, suffix, lane, scheme
package_name = branding.desktop_package_name
build_dir = branding.desktop_build_dir
branding_dir = branding.desktop_branding_dir
updates_dir = branding.desktop_updates_dir
changes_dir = branding.desktop_changes_dir
update_changes_list = branding.desktop_update_changes_list
suffixes = {
"macos_x86_64": "x86_64",
"macos_x86_64_v8": "v8",
"macos_aarch64": "aarch64"
}
suffix = suffixes[common.platform]
lane = "release_" + suffix
scheme = package_name + "-" + suffix
set_cwd(git_dir + "/" + branding_build_dir)
utils.set_cwd(build_dir)
for target in targets:
if not target.startswith('diskimage'):
continue
# utils.sh_output(" \
# url=" + branding.sparkle_base_url + "/" + suffix + "/onlyoffice.xml; \
# appcast=$(curl -s $url 2> /dev/null); \
# path=desktop-apps/macos/ONLYOFFICE/Resources/ONLYOFFICE-" + suffix + "/Info.plist; \
# echo -n \"RELEASE_MACOS_VERSION=\"; \
# echo $appcast | xmllint --xpath \"/rss/channel/item[1]/enclosure/@*[name()='sparkle:shortVersionString']\" - | cut -f 2 -d \\\\\"; \
# echo -n \"RELEASE_MACOS_BUILD=\"; \
# echo $appcast | xmllint --xpath \"/rss/channel/item[1]/enclosure/@*[name()='sparkle:version']\" - | cut -f 2 -d \\\\\"; \
# echo -n \"CURRENT_MACOS_VERSION=\"; \
# /usr/libexec/PlistBuddy -c 'print :CFBundleShortVersionString' $path; \
# echo -n \"CURRENT_MACOS_BUILD=\"; \
# /usr/libexec/PlistBuddy -c 'print :CFBundleVersion' $path",
# verbose=True
# )
make_dmg()
# if :
make_sparkle_updates()
if target.startswith('diskimage'):
if (target == 'diskimage-x86_64'): suffix = 'x86_64'
elif (target == 'diskimage-x86_64-v8'): suffix = 'v8'
elif (target == 'diskimage-arm64'): suffix = 'arm'
else: exit(1)
lane = "release_" + suffix
scheme = package_name + '-' + suffix
make_diskimage(target)
if ('sparkle-updates' in targets):
make_sparkle_updates()
utils.set_cwd(common.workspace_dir)
return
def make_diskimage(target):
log("\n=== Build package " + scheme + "\n")
log("--- build/" + package_name + ".app")
cmd("bundler", ["exec", "fastlane", lane, "skip_git_bump:true"])
def make_dmg():
utils.log_h1(scheme + " build")
utils.log_h2("build/" + package_name + ".app")
rc = utils.sh("bundler exec fastlane " + lane + \
" git_bump:false notarization:false", verbose=True)
common.summary["desktop build"] = rc
return
def make_sparkle_updates():
log("\n=== Build sparkle updates\n")
utils.log_h1("sparkle updates build")
app_version = proc_open("/usr/libexec/PlistBuddy \
app_version = utils.sh_output("/usr/libexec/PlistBuddy \
-c 'print :CFBundleShortVersionString' \
build/" + package_name + ".app/Contents/Info.plist")['stdout']
build/" + package_name + ".app/Contents/Info.plist", verbose=True)
zip_filename = scheme + '-' + app_version
macos_zip = "build/" + zip_filename + ".zip"
updates_storage_dir = "%s/%s/_updates" % (get_env('ARCHIVES_DIR'), scheme)
create_dir(updates_dir)
copy_dir_content(updates_storage_dir, updates_dir, ".zip")
copy_dir_content(updates_storage_dir, updates_dir, ".html")
copy_file(macos_zip, updates_dir)
utils.create_dir(updates_dir)
utils.copy_dir_content(updates_storage_dir, updates_dir, ".zip")
utils.copy_dir_content(updates_storage_dir, updates_dir, ".html")
utils.copy_file(macos_zip, updates_dir)
for lang, base in update_changes_list.items():
notes_src = "%s/%s/%s.html" % (changes_dir, app_version, base)
notes_dst = "%s/%s.html" % (updates_dir, zip_filename)
if lang == 'en':
encoding = 'en_US.UTF-8'
cur_date = proc_open("env LC_ALL=" + encoding + " date -u \"+%B %e, %Y\"")['stdout']
cur_date = utils.sh_output("env LC_ALL=" + encoding + " date -u \"+%B %e, %Y\"")
elif lang == 'ru':
encoding = 'ru_RU.UTF-8'
cur_date = proc_open("env LC_ALL=" + encoding + " date -u \"+%e %B %Y\"")['stdout']
if is_file(notes_src):
copy_file(notes_src, notes_dst)
replace_in_file(notes_dst,
r"(<span class=\"releasedate\">).+(</span>)",
"\\1 - " + cur_date + "\\2")
cur_date = utils.sh_output("env LC_ALL=" + encoding + " date -u \"+%e %B %Y\"")
if utils.is_file(notes_src):
utils.copy_file(notes_src, notes_dst)
utils.replace_in_file(notes_dst,
r"(<span class=\"releasedate\">).+(</span>)",
"\\1 - " + cur_date + "\\2")
# else:
# write_file(notes_dst, "placeholder\n")
cmd(git_dir + "/" + build_dir + "/Vendor/Sparkle/bin/generate_appcast", [updates_dir])
utils.sh(common.workspace_dir + \
"/desktop-apps/macos/Vendor/Sparkle/bin/generate_appcast " + updates_dir)
log("\n=== Edit Sparkle appcast links\n")
utils.log_h1("edit sparkle appcast links")
appcast_url = sparkle_base_url + "/" + suffix
appcast = "%s/%s.xml" % (updates_dir, package_name.lower())
for lang, base in update_changes_list.items():
if base == "ReleaseNotes":
replace_in_file(appcast,
r"(<sparkle:releaseNotesLink>)(?:.+" + package_name + \
"-(?:x86|x86_64|v8|arm)-([0-9.]+)\..+)(</sparkle:releaseNotesLink>)",
"\\1" + appcast_url + "/updates/changes/\\2/" + base + ".html\\3")
utils.replace_in_file(appcast,
r"(<sparkle:releaseNotesLink>)(?:.+" + package_name + \
"-(?:x86|x86_64|v8|arm)-([0-9.]+)\..+)(</sparkle:releaseNotesLink>)",
"\\1" + appcast_url + "/updates/changes/\\2/" + base + ".html\\3")
else:
replace_in_file(appcast,
r"(<sparkle:releaseNotesLink xml:lang=\"" + lang + "\">)(?:" + package_name + \
"-(?:x86|x86_64|v8|arm)-([0-9.]+)\..+)(</sparkle:releaseNotesLink>)",
"\\1" + appcast_url + "/updates/changes/\\2/" + base + ".html\\3")
replace_in_file(appcast,
r"(url=\")(?:.+/)(" + package_name + ".+\")",
"\\1" + appcast_url + "/updates/\\2")
utils.replace_in_file(appcast,
r"(<sparkle:releaseNotesLink xml:lang=\"" + lang + "\">)(?:" + package_name + \
"-(?:x86|x86_64|v8|arm)-([0-9.]+)\..+)(</sparkle:releaseNotesLink>)",
"\\1" + appcast_url + "/updates/changes/\\2/" + base + ".html\\3")
utils.replace_in_file(appcast,
r"(url=\")(?:.+/)(" + package_name + ".+\")",
"\\1" + appcast_url + "/updates/\\2")
log("\n=== Delete unnecessary files\n")
utils.log_h1("delete unnecessary files")
for file in os.listdir(updates_dir):
if (-1 == file.find(app_version)) and (file.endswith(".zip") or
file.endswith(".html")):
delete_file(updates_dir + '/' + file)
utils.delete_file(updates_dir + '/' + file)
return
#
# Linux
#
def make_linux():
utils.set_cwd("desktop-apps/win-linux/package/linux")
rc = utils.sh("make clean", verbose=True)
common.summary["desktop clean"] = rc
args = []
if common.platform == "linux_aarch64":
args += ["-e", "UNAME_M=aarch64"]
if not branding.onlyoffice:
args += ["-e", "BRANDING_DIR=../../../../" + common.branding + "/desktop-apps/win-linux/package/linux"]
rc = utils.sh("make packages " + " ".join(args), verbose=True)
common.summary["desktop build"] = rc
utils.set_cwd(common.workspace_dir)
return

View File

@ -1,25 +1,59 @@
#!/usr/bin/env python3
#!/usr/bin/env python
import base
import os
def make(platform, targets):
base_dir = base.get_script_dir() + "/../out"
git_dir = base.get_script_dir() + "/../.."
package_dir = os.path.abspath(git_dir + "/document-server-package")
if ("windows" == platform) or ("linux" == platform):
if ("packages" in targets):
print("Make clean")
base.cmd_in_dir(package_dir, "make", ["clean"])
print("Make packages")
base.cmd_in_dir(package_dir, "make", ["packages"])
import package_utils as utils
import package_common as common
import package_branding as branding
def make(edition):
utils.log_h1("SERVER (" + edition.upper() + ")")
if utils.is_windows():
make_windows(edition)
elif utils.is_linux():
make_linux(edition)
else:
exit(1)
utils.log("Unsupported host OS")
return
def make_windows(edition):
if edition == "enterprise":
product_name = "DocumentServer-EE"
elif edition == "developer":
product_name = "DocumentServer-DE"
else:
product_name = "DocumentServer"
utils.set_cwd("document-server-package")
rc = utils.cmd("make", "clean", verbose=True)
common.summary["server " + edition + " clean"] = rc
args = ["-e", "PRODUCT_NAME=" + product_name]
if not branding.onlyoffice:
args += ["-e", "BRANDING_DIR=../" + common.branding + "/document-server-package"]
rc = utils.cmd("make", "packages", *args, verbose=True)
common.summary["server " + edition + " build"] = rc
utils.set_cwd(common.workspace_dir)
return
def make_linux(edition):
if edition == "enterprise":
product_name = "documentserver-ee"
elif edition == "developer":
product_name = "documentserver-de"
else:
product_name = "documentserver"
utils.set_cwd("document-server-package")
rc = utils.sh("make clean", verbose=True)
common.summary["server " + edition + " clean"] = rc
args = ["-e", "PRODUCT_NAME=" + product_name]
if common.platform == "linux_aarch64":
args += ["-e", "UNAME_M=aarch64"]
if not branding.onlyoffice:
args += ["-e", "BRANDING_DIR=../" + common.branding + "/document-server-package"]
rc = utils.sh("make packages " + " ".join(args), verbose=True)
common.summary["server " + edition + " build"] = rc
utils.set_cwd(common.workspace_dir)
return

View File

@ -1,9 +1,9 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import argparse
import codecs
import glob
import hashlib
import os
import platform
import re
@ -11,71 +11,68 @@ import shutil
import subprocess
import sys
import time
import base
def parse():
parser = argparse.ArgumentParser(description="Build packages.")
parser.add_argument('-P', '--product', dest='product', type=str,
action='store', help="Defines product")
parser.add_argument('-S', '--system', dest='system', type=str,
action='store', help="Defines system")
parser.add_argument('-R', '--branding', dest='branding', type=str,
action='store', help="Provides branding path")
parser.add_argument('-V', '--version', dest='version', type=str,
action='store', help="Defines version")
parser.add_argument('-B', '--build', dest='build', type=str,
action='store', help="Defines build")
parser.add_argument('-T', '--targets', dest='targets', type=str, nargs='+',
action='store', help="Defines targets")
args = parser.parse_args()
global product, system, targets, version, build, branding, sign, clean
product = args.product
system = args.system if (args.system is not None) else host_platform()
targets = args.targets
version = args.version if (args.version is not None) else get_env('PRODUCT_VERSION', '0.0.0')
build = args.build if (args.build is not None) else get_env('BUILD_NUMBER', '0')
branding = args.branding
return
def host_platform():
return platform.system().lower()
def log(string, end='\n', bold=False):
if bold:
out = '\033[1m' + string + '\033[0m' + end
else:
out = string + end
sys.stdout.write(out)
def is_windows():
return host_platform() == "windows"
def is_macos():
return host_platform() == "darwin"
def is_linux():
return host_platform() == "linux"
def log(string, end='\n'):
sys.stdout.write(string + end)
sys.stdout.flush()
return
def get_env(name, default=''):
return os.getenv(name, default)
def set_env(name, value):
os.environ[name] = value
def log_h1(string):
line = "-" * (len(string) + 8)
log("\n" + line + "\n--- " + string + " ---\n" + line + "\n")
return
def set_cwd(dir):
log("- change working dir: " + dir)
os.chdir(dir)
def log_h2(string):
log("--- " + string)
return
def get_path(*paths):
arr = []
for path in paths:
if host_platform() == 'windows':
arr += path.split('/')
else:
arr += [path]
return os.path.join(*arr)
def get_timestamp():
return "%.f" % time.time()
def get_abspath(*paths):
arr = []
for path in paths:
arr += path.split('/')
return os.path.abspath(os.path.join(*arr))
def get_env(key, default=None):
return os.getenv(key, default)
def set_env(key, value):
os.environ[key] = value
return
def get_cwd():
return os.getcwd()
def set_cwd(path, verbose=True):
if verbose:
log_h2("change working dir: " + path)
os.chdir(path)
return
def get_path(path):
if is_windows():
return path.replace("/", "\\")
return path
def get_abspath(path):
return os.path.abspath(get_path(path))
def get_dirname(path):
return os.path.dirname(path)
def get_file_size(path):
return os.path.getsize(path)
def get_script_dir(path):
return get_dirname(os.path.realpath(path))
def is_file(path):
return os.path.isfile(path)
@ -88,8 +85,12 @@ def is_exist(path):
return True
return False
def get_dirname(path):
return os.path.dirname(path)
def get_md5(path):
if os.path.exists(path):
md5_hash = hashlib.md5()
md5_hash.update(open(path, "rb").read())
return md5_hash.hexdigest()
return
def create_dir(path):
log("- create dir: " + path)
@ -203,77 +204,72 @@ def delete_files(src):
delete_dir(path)
return
def download_file(url, path):
log("- download file: " + path + " < " + url)
def cmd(*args, **kwargs):
if kwargs.get("verbose"):
log_h2("cmd: " + " ".join(args))
if kwargs.get("creates") and is_exist(kwargs["creates"]):
return 0
if kwargs.get("chdir") and is_dir(kwargs["chdir"]):
oldcwd = get_cwd()
set_cwd(kwargs["chdir"])
ret = subprocess.call(
[i for i in args], stderr=subprocess.STDOUT, shell=True
)
if kwargs.get("chdir") and oldcwd:
set_cwd(oldcwd)
return ret
def cmd_output(*args, **kwargs):
if kwargs.get("verbose"):
log_h2("cmd output: " + " ".join(args))
return subprocess.check_output(
[i for i in args], stderr=subprocess.STDOUT, shell=True
).decode("utf-8")
def powershell(*args, **kwargs):
if kwargs.get("verbose"):
log_h2("powershell: " + " ".join(args))
if kwargs.get("creates") and is_exist(kwargs["creates"]):
return 0
args = ["powershell", "-Command"] + [i for i in args]
ret = subprocess.call(
args, stderr=subprocess.STDOUT, shell=True
)
return ret
def ps1(file, args=[], **kwargs):
if kwargs.get("verbose"):
log_h2("powershell cmdlet: " + file + " " + " ".join(args))
if kwargs.get("creates") and is_exist(kwargs["creates"]):
return 0
ret = subprocess.call(
["powershell", file] + args, stderr=subprocess.STDOUT, shell=True
)
return ret
def download_file(url, path, md5, verbose=False):
if verbose:
log("download file: %s < %s (%s)" % (path, url, md5))
if is_file(path):
os.remove(path)
powershell(["Invoke-WebRequest", url, "-OutFile", path])
return
def proc_open(command):
log("- open process: " + command)
popen = subprocess.Popen(command, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=True)
ret = {'stdout' : '', 'stderr' : ''}
try:
stdout, stderr = popen.communicate()
popen.wait()
ret['stdout'] = stdout.strip().decode('utf-8', errors='ignore')
ret['stderr'] = stderr.strip().decode('utf-8', errors='ignore')
finally:
popen.stdout.close()
popen.stderr.close()
if get_md5(path) == md5:
log("! file already exist (match checksum)")
return 0
else:
log("! wrong checksum (%s), delete" % md5)
os.remove(path)
ret = powershell("(New-Object System.Net.WebClient).DownloadFile('%s','%s')" % (url, path), verbose=True)
if get_md5(path) != md5:
return 1
return ret
def cmd(prog, args=[], is_no_errors=False):
log("- cmd: " + prog + " " + ' '.join(args))
ret = 0
if host_platform() == 'windows':
sub_args = args[:]
sub_args.insert(0, get_path(prog))
ret = subprocess.call(sub_args, stderr=subprocess.STDOUT, shell=True)
else:
command = prog
for arg in args:
command += (" \"%s\"" % arg)
ret = subprocess.call(command, stderr=subprocess.STDOUT, shell=True)
if ret != 0 and True != is_no_errors:
sys.exit("! error (" + prog + "): " + str(ret))
return ret
def sh(command, **kwargs):
if kwargs.get("verbose"):
log_h2("sh: " + command)
return subprocess.call(command, stderr=subprocess.STDOUT, shell=True)
def powershell(cmd):
log("- pwsh: " + ' '.join(cmd))
ret = subprocess.call(['powershell', '-Command'] + cmd,
stderr=subprocess.STDOUT, shell=True)
if ret != 0:
sys.exit("! error: " + str(ret))
return ret
def get_platform(target):
xp = (-1 != target.find('-xp'))
if (-1 != target.find('-x64')):
return {'machine': "64", 'arch': "x64", 'xp': xp}
elif (-1 != target.find('-x86')):
return {'machine': "32", 'arch': "x86", 'xp': xp}
return
global git_dir, out_dir, tsa_server, vcredist_links
git_dir = get_abspath(get_dirname(__file__), '../..')
out_dir = get_abspath(get_dirname(__file__), '../out')
timestamp = "%.f" % time.time()
tsa_server = "http://timestamp.digicert.com"
vcredist_links = {
'2022': {
'64': "https://aka.ms/vs/17/release/vc_redist.x64.exe",
'32': "https://aka.ms/vs/17/release/vc_redist.x86.exe"
},
'2015': {
'64': "https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x64.exe",
'32': "https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x86.exe"
},
'2013': {
'64': "https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe",
'32': "https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x86.exe"
}
}
isxdl_link = "https://raw.githubusercontent.com/jrsoftware/ispack/is-5_6_1/isxdlfiles/isxdl.dll"
def sh_output(command, **kwargs):
if kwargs.get("verbose"):
log_h2("sh output: " + command)
return subprocess.check_output(
command, stderr=subprocess.STDOUT, shell=True
).decode("utf-8")