From f21a87fa42176f4bf03bf4744300400e86994dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kriszti=C3=A1n=20G=C3=B6drei?= Date: Thu, 19 Sep 2019 15:54:26 +0200 Subject: [PATCH] send android artifact's module, product flavour and build type (#100) * send android artifct's module, product flavour and build type * new tests * parse multiple falvours * PR fix * better example for parseAppPath * handle -unsigned suffix in artifact path * parse android artifacts, include split meta * artifact info models * mark bundle of the split * aab support in artifact meta * refactors + dep update * introduce Artifact * always return split meta * pr fix, bundle's universal apk name fix, bundle's universal apk name test, loging updates * wire in renameUniversalAPK func * generating apk from aab mooved to the main package; generate or find universal apk pairs for aabs; android artifact path parsing logic moved to the androidartifact package * improved FindSameArtifact and tests * new tests * pr fixes * pr fixes * BundleTool fixes * PR fixes --- Gopkg.lock | 22 +- aabutil.go | 100 ++++ androidartifact/apk_info.go | 111 ++++ .../apk_info_test.go | 12 +- androidartifact/file_name.go | 289 +++++++++ androidartifact/file_name_test.go | 562 ++++++++++++++++++ bitrise.yml | 9 + bundletool/bundletool.go | 24 +- main.go | 97 ++- main_test.go | 38 ++ uploaders/aabuploader.go | 121 +--- uploaders/apkuploader.go | 119 +--- .../bitrise-io/bitrise/models/models.go | 3 +- .../bitrise/models/models_methods.go | 6 + .../go-steputils/stepconf/stepconf.go | 311 +++++++++- .../go-utils/sliceutil/sliceutil.go | 32 + 16 files changed, 1599 insertions(+), 257 deletions(-) create mode 100644 aabutil.go create mode 100644 androidartifact/apk_info.go rename uploaders/apkuploader_test.go => androidartifact/apk_info_test.go (85%) create mode 100644 androidartifact/file_name.go create mode 100644 androidartifact/file_name_test.go create mode 100644 main_test.go create mode 100644 vendor/github.com/bitrise-io/go-utils/sliceutil/sliceutil.go diff --git a/Gopkg.lock b/Gopkg.lock index 4795297b..4b3bfebd 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -3,11 +3,11 @@ [[projects]] branch = "master" - digest = "1:f006631e21e1ebecc5bd025f272197c6d1ee0102bc46006cf2e527b57be5e884" + digest = "1:5e3bbc74fb2d9b11f52377c6cf4310c084aa8f3dc1995a16f46da52862651ccd" name = "github.com/bitrise-io/bitrise" packages = ["models"] pruneopts = "UT" - revision = "85fcf1f508cb6d92ddd2ddf788988fde6cf5178f" + revision = "099ec60f02cc67ebd8b086e71abe0c2bd6a58c03" [[projects]] branch = "master" @@ -15,7 +15,7 @@ name = "github.com/bitrise-io/envman" packages = ["models"] pruneopts = "UT" - revision = "b62ffe18bb760bf14002dd1a80b059180ef910f1" + revision = "7698fc58b190e022c2a8ca667b539ce48c3ed1c9" [[projects]] branch = "master" @@ -23,22 +23,22 @@ name = "github.com/bitrise-io/go-android" packages = ["sdk"] pruneopts = "UT" - revision = "8082fe069ed29f394c2fd0724dd6bdc64e5cf6b4" + revision = "34d6f20488bf0e2256c034c03a2a589a4a608e3f" [[projects]] branch = "master" - digest = "1:e875a94349b121ca6fa86bd72f7593f7f0e6f0d07a7d664f31fc000d80eaeec3" + digest = "1:8f5fdb79a7a38f6b7dafbc47f620322f384a0cb06858cb28df0e5635e5bb4df4" name = "github.com/bitrise-io/go-steputils" packages = [ "stepconf", "tools", ] pruneopts = "UT" - revision = "cecc766da84859e37e780d9d1c416f0f3993e6b1" + revision = "f540824d77dfd382ce84fd0ee0a9da2fba1cce0a" [[projects]] branch = "master" - digest = "1:c752648f9ec1c0f43af891ef888a43831d99573e4cabec34b89a74f0e1497e9f" + digest = "1:16fce352370acaddbf2e658b37ed0870b9490310bed5b55bbd6b47a546f5ca93" name = "github.com/bitrise-io/go-utils" packages = [ "colorstring", @@ -52,11 +52,12 @@ "pkcs12/internal/rc2", "pointers", "retry", + "sliceutil", "urlutil", "ziputil", ] pruneopts = "UT" - revision = "cb35044c1bab53fdbfa1e6ea3b56478c25275c9c" + revision = "ad86bf775472ce1934affb9d3cb7d5ea3dffd16f" [[projects]] branch = "master" @@ -81,7 +82,7 @@ name = "github.com/bitrise-io/stepman" packages = ["models"] pruneopts = "UT" - revision = "605a625dade4553d2e2c5dcc9e3459844cd2f5b4" + revision = "8138843b694ce731d58a1754b57ac250a9dec9e6" [[projects]] branch = "master" @@ -89,7 +90,7 @@ name = "github.com/bitrise-io/xcode-project" packages = ["serialized"] pruneopts = "UT" - revision = "5929ad85d89233b3296d2d795e068a656db7fb25" + revision = "e74e748ca5af39e2bd2b24ed4e9476bc4abd1a50" [[projects]] digest = "1:26e714e21bef4fc07640fb796ccce6d4f9423e15b2d660e131a8e61a0ee576d5" @@ -162,6 +163,7 @@ "github.com/bitrise-io/go-utils/log", "github.com/bitrise-io/go-utils/pathutil", "github.com/bitrise-io/go-utils/retry", + "github.com/bitrise-io/go-utils/sliceutil", "github.com/bitrise-io/go-utils/urlutil", "github.com/bitrise-io/go-utils/ziputil", "github.com/bitrise-io/go-xcode/exportoptions", diff --git a/aabutil.go b/aabutil.go new file mode 100644 index 00000000..0e7fe99c --- /dev/null +++ b/aabutil.go @@ -0,0 +1,100 @@ +package main + +import ( + "errors" + "fmt" + "os" + "path/filepath" + + "github.com/bitrise-io/go-utils/command" + "github.com/bitrise-io/go-utils/errorutil" + "github.com/bitrise-io/go-utils/pathutil" + "github.com/bitrise-steplib/steps-deploy-to-bitrise-io/androidartifact" + "github.com/bitrise-steplib/steps-deploy-to-bitrise-io/bundletool" +) + +// handleError creates error with layout: ` failed (status: ): `. +func handleError(cmd, out string, err error) error { + if err == nil { + return nil + } + + msg := fmt.Sprintf("%s failed", cmd) + if status, exitCodeErr := errorutil.CmdExitCodeFromError(err); exitCodeErr == nil { + msg += fmt.Sprintf(" (status: %d)", status) + } + if len(out) > 0 { + msg += fmt.Sprintf(": %s", out) + } + return errors.New(msg) +} + +// run executes a given command. +func run(cmd *command.Model) error { + out, err := cmd.RunAndReturnTrimmedCombinedOutput() + return handleError(cmd.PrintableCommandArgs(), out, err) +} + +// generateKeystore creates a debug keystore. +func generateKeystore(tmpPth string) (string, error) { + pth := filepath.Join(tmpPth, "debug.keystore") + return pth, run(command.New("keytool", "-genkey", "-v", + "-keystore", pth, + "-storepass", "android", + "-alias", "androiddebugkey", + "-keypass", "android", + "-keyalg", "RSA", + "-keysize", "2048", + "-validity", "10000", + "-dname", "C=US, O=Android, CN=Android Debug", + )) +} + +// buildApksArchive generates universal apks from an aab file. +func buildApksArchive(bundleTool bundletool.Path, tmpPth, aabPth, keystorePath string) (string, error) { + pth := filepath.Join(tmpPth, "universal.apks") + return pth, run(bundleTool.Command("build-apks", "--mode=universal", + "--bundle", aabPth, + "--output", pth, + "--ks", keystorePath, + "--ks-pass", "pass:android", + "--ks-key-alias", "androiddebugkey", + "--key-pass", "pass:android", + )) +} + +// unzipUniversalAPKsArchive unzips an universal apks archive. +func unzipUniversalAPKsArchive(archive, destDir string) (string, error) { + return filepath.Join(destDir, "universal.apk"), run(command.New("unzip", archive, "-d", destDir)) +} + +// GenerateUniversalAPK generates universal apks from an aab file. +func GenerateUniversalAPK(aabPth string) (string, error) { + r, err := bundletool.New() + if err != nil { + return "", err + } + + tmpPth, err := pathutil.NormalizedOSTempDirPath("aab-bundle") + if err != nil { + return "", err + } + + keystorePath, err := generateKeystore(tmpPth) + if err != nil { + return "", err + } + + apksPth, err := buildApksArchive(r, tmpPth, aabPth, keystorePath) + if err != nil { + return "", err + } + + universalAPKPath, err := unzipUniversalAPKsArchive(apksPth, tmpPth) + if err != nil { + return "", err + } + + renamedUniversalAPKPath := filepath.Join(tmpPth, androidartifact.UniversalAPKBase(aabPth)) + return renamedUniversalAPKPath, os.Rename(universalAPKPath, renamedUniversalAPKPath) +} diff --git a/androidartifact/apk_info.go b/androidartifact/apk_info.go new file mode 100644 index 00000000..3c6eda7c --- /dev/null +++ b/androidartifact/apk_info.go @@ -0,0 +1,111 @@ +package androidartifact + +import ( + "errors" + "fmt" + "os" + "regexp" + "strings" + + "github.com/bitrise-io/go-android/sdk" + "github.com/bitrise-io/go-utils/command" +) + +// ApkInfo ... +type ApkInfo struct { + AppName string + PackageName string + VersionCode string + VersionName string + MinSDKVersion string + RawPackageContent string +} + +// parseAppName parses the application name from `aapt dump badging` command output. +func parseAppName(aaptOut string) string { + pattern := `application: label=\'(?P