diff --git a/util/README.md b/util/README.md index bb08602d9..87cf50040 100644 --- a/util/README.md +++ b/util/README.md @@ -28,9 +28,12 @@ and can be set to anything but ideally we should follow established practices (i Then run the provided `release.dart` script from the project root: - dart run utils/release.dart -t path/to/github/token/file + dart run utils/release.dart -t path/to/github/token/file -i -b -(Omitting the github token still creates the release packages but doesn't upload them to github). +Notes: + +- Omitting the github token still creates the release packages but doesn't upload them to github. +- If --identity-name, -i; *or* --publisher, -b; are not present, the Windows MSIX installer will not be created. ## Publishing the release diff --git a/util/release.dart b/util/release.dart index c1495a783..abaa4da2d 100644 --- a/util/release.dart +++ b/util/release.dart @@ -29,14 +29,38 @@ Future main(List args) async { final aab = await buildAab(buildName, version.build[0] as int); final winInstaller = await buildWindowsInstaller(buildName); + final identityName = options.identityName; + final publisher = options.publisher; + final winMSIX = await buildWindowsMSIX(identityName, publisher); + final suffix = createFileSuffix(version, commit); final outputDir = await createOutputDir(suffix); - final collatedAab = await collateAsset(outputDir, "ouisync-android", suffix, aab); + final collatedAab = + await collateAsset(outputDir, "ouisync-android", suffix, aab); final collatedApk = await extractApk(collatedAab); - final collatedWinInstaller = await collateAsset(outputDir, "ouisync-windows-installer", suffix, winInstaller); + final collatedWinInstaller = await collateAsset( + outputDir, "ouisync-windows-installer", suffix, winInstaller); + + File? collateWinMSIX; + if (winMSIX != null) { + collateWinMSIX = + await collateAsset(outputDir, 'ouisync-windows-msix', suffix, winMSIX); + } - final assets = [collatedAab, collatedApk, collatedWinInstaller]; + /// Right now the MSIX is not signed, therefore, it can only be used for the + /// Microsoft Store, not for standalone installations. + /// + /// Until we get the certificates and sign the MSIX, we don't upload it to + /// GitHub releases. + /// + /// + final assets = [ + collatedAab, + collatedApk, + collatedWinInstaller, + if (collateWinMSIX != null) collateWinMSIX + ]; final token = options.token; if (token != null) { @@ -58,8 +82,15 @@ class Options { final String? token; final String? firstCommit; final bool detailedLog; + final String? identityName; + final String? publisher; - Options._({this.token, this.firstCommit, this.detailedLog = true}); + Options._( + {this.token, + this.firstCommit, + this.detailedLog = true, + this.identityName, + this.publisher}); static Future parse(List args) async { final parser = ArgParser(); @@ -79,6 +110,18 @@ class Options { defaultsTo: true, help: 'Whether to generate detailed changelog in the release notes', ); + parser.addOption( + 'identity-name', + abbr: 'i', + help: + 'The unique identifier for the app in the Microsoft Store (For the MSIX)', + ); + parser.addOption( + 'publisher', + abbr: 'b', + help: + 'The Publisher (CN) value for the app in the Microsoft Store (For the MSIX)', + ); parser.addFlag( 'help', abbr: 'h', @@ -102,6 +145,8 @@ class Options { token: token?.trim(), firstCommit: results['first-commit']?.trim(), detailedLog: results['detailed-log'], + identityName: results['identity-name'], + publisher: results['publisher'], ); } } @@ -120,8 +165,10 @@ Future buildWindowsInstaller(String buildName) async { buildName, ]); - final inno_script = await File("windows/inno-setup.iss.template").readAsString(); - await File("build/inno-setup.iss").writeAsString(inno_script.replaceAll("", buildName)); + final innoScript = + await File("windows/inno-setup.iss.template").readAsString(); + await File("build/inno-setup.iss") + .writeAsString(innoScript.replaceAll("", buildName)); await run("C:/Program Files (x86)/Inno Setup 6/Compil32.exe", ['/cc', 'build/inno-setup.iss']); @@ -129,13 +176,40 @@ Future buildWindowsInstaller(String buildName) async { return File('build/windows/runner/Release/ouisync-installer.exe'); } -Future buildAab( - String buildName, - int buildNumber, { - String flavor = "vanilla", -}) async { - final inputPath = - 'build/app/outputs/bundle/${flavor}Release/app-$flavor-release.aab'; +Future buildWindowsMSIX(String? identityName, String? publisher) async { + if (identityName == null || publisher == null) { + final missingOptions = + StringBuffer('The Windows MSIX creation will be skipped:\n\n'); + + if (identityName == null) { + missingOptions.writeln(' --identity-name, -i: parameter not provided.'); + } + if (publisher == null) { + missingOptions.writeln(' --publisher, -b: parameter not provided.\n'); + } + + print(missingOptions.toString()); + + return null; + } + + await run('dart', [ + 'run', + 'msix:create', + '-u', + '"eQualitie Inc"', + '-i', + identityName, + '-b', + publisher, + '--store' + ]); + + return File('build/windows/runner/Release/ouisync_app.msix'); +} + +Future buildAab(String buildName, int buildNumber) async { + final inputPath = 'build/app/outputs/bundle/Release/app-release.aab'; print('Creating Android App Bundle ...');