import groovy.json.JsonBuilder /* I'm using utils from ghcmgr to avoid another load */ ghcmgr = load 'ci/ghcmgr.groovy' /** * Methods for interacting with GitHub API and related tools. **/ /* Comments -------------------------------------------------------*/ def notify(message) { def githubIssuesUrl = 'https://api.github.com/repos/status-im/status-react/issues' def changeId = ghcmgr.utils.changeId() if (changeId == null) { return } def msgObj = [body: message] def msgJson = new JsonBuilder(msgObj).toPrettyString() withCredentials([usernamePassword( credentialsId: 'status-im-auto', usernameVariable: 'GH_USER', passwordVariable: 'GH_PASS' )]) { sh """ curl --silent \ -u '${GH_USER}:${GH_PASS}' \ --data '${msgJson}' \ -H "Content-Type: application/json" \ "${githubIssuesUrl}/${changeId}/comments" """.trim() } } def notifyFull(urls) { def msg = "#### :white_check_mark: " msg += "[${env.JOB_NAME}${currentBuild.displayName}](${currentBuild.absoluteUrl}) " msg += "CI BUILD SUCCESSFUL in ${ghcmgr.utils.buildDuration()} (${GIT_COMMIT.take(8)})\n" msg += '| | | | | |\n' msg += '|-|-|-|-|-|\n' msg += "| [Android](${urls.Apk}) ([e2e](${urls.Apke2e})) " msg += "| [iOS](${urls.iOS}) ([e2e](${urls.iOSe2e})) |" if (urls.Mac != null) { msg += " [MacOS](${urls.Mac}) | [AppImage](${urls.App}) | [Windows](${urls.Win}) |" } else { msg += " ~~MacOS~~ | ~~AppImage~~ | ~~Windows~~~ |" } notify(msg) } def notifyPRFailure() { def d = ":small_orange_diamond:" def msg = "#### :x: " msg += "[${env.JOB_NAME}${currentBuild.displayName}](${currentBuild.absoluteUrl}) ${d} " msg += "${ghcmgr.utils.buildDuration()} ${d} ${GIT_COMMIT.take(8)} ${d} " msg += "[:page_facing_up: build log](${currentBuild.absoluteUrl}/consoleText)" //msg += "Failed in stage: ${env.STAGE_NAME}\n" //msg += "```${currentBuild.rawBuild.getLog(5)}```" notify(msg) } def notifyPRSuccess() { def d = ":small_blue_diamond:" def msg = "#### :heavy_check_mark: " def type = ghcmgr.utils.getBuildType() == 'e2e' ? ' e2e' : '' msg += "[${env.JOB_NAME}${currentBuild.displayName}](${currentBuild.absoluteUrl}) ${d} " msg += "${ghcmgr.utils.buildDuration()} ${d} ${GIT_COMMIT.take(8)} ${d} " msg += "[:package: ${env.TARGET_OS}${type} package](${env.PKG_URL})" notify(msg) } /* Releases -------------------------------------------------------*/ def getPrevRelease() { return sh(returnStdout: true, script: "git for-each-ref --format '%(refname)' --sort=committerdate refs/remotes/origin/release" ).trim().split('\\r?\\n').last() } def getDiffUrl(prev, current) { prev = prev.replaceAll(/.*origin\//, '') return "https://github.com/status-im/status-react/compare/${prev}...${current}" } def getReleaseChanges() { def prevRelease = getPrevRelease() def curRelease = ghcmgr.utils.branchName() def changes = '' try { changes = sh(returnStdout: true, script: """ git log \ --cherry-pick \ --right-only \ --no-merges \ --format='%h %s' \ ${prevRelease}..HEAD """ ).trim() } catch (Exception ex) { println 'ERROR: Failed to retrieve changes.' println ex.message return ':warning: __Please fill me in!__' } /* remove single quotes to not confuse formatting */ changes = changes.replace('\'', '') return changes + '\nDiff:' + getDiffUrl(prevRelease, curRelease) } def releaseExists(Map args) { def output = sh( returnStdout: true, script: """ github-release info --json \ -u '${args.user}' \ -r '${args.repo}' \ | jq '.Releases[].tag_name' """ ) return output.contains(args.version) } def releaseDelete(Map args) { if (!releaseExists(args)) { return } sh """ github-release delete \ -u '${args.user}' \ -r '${args.repo}' \ -t '${args.version}' \ """ } def releaseUpload(Map args) { dir(args.pkgDir) { args.files.each { sh """ github-release upload \ -u '${args.user}' \ -r '${args.repo}' \ -t '${args.version}' \ -n ${it} \ -f ${it} """ } } } def releasePublish(Map args) { sh """ github-release release \ -u '${args.user}' \ -r '${args.repo}' \ -n '${args.version}' \ -t '${args.version}' \ -c '${args.branch}' \ -d '${args.desc}' \ ${args.draft ? '--draft' : ''} """ } def publishRelease(Map args) { def config = [ draft: true, user: 'status-im', repo: 'status-react', pkgDir: args.pkgDir, files: args.files, version: args.version, branch: ghcmgr.utils.branchName(), desc: getReleaseChanges(), ] /* we release only for mobile right now */ withCredentials([usernamePassword( credentialsId: 'status-im-auto', usernameVariable: 'GITHUB_USER', passwordVariable: 'GITHUB_TOKEN' )]) { releaseDelete(config) /* so we can re-release it */ releasePublish(config) releaseUpload(config) } } def publishReleaseMobile() { publishRelease( version: ghcmgr.utils.getVersion()+'-mobile', pkgDir: 'pkg', files: [ /* upload only mobile release files */ ghcmgr.utils.pkgFilename(btype, 'ipa'), ghcmgr.utils.pkgFilename(btype, 'apk'), ghcmgr.utils.pkgFilename(btype, 'sha256'), ] ) } def notifyPR(success) { if (ghcmgr.utils.changeId() == null) { return } try { ghcmgr.postBuild(success) } catch (ex) { /* fallback to posting directly to GitHub */ println "Failed to use GHCMGR: ${ex}" switch (success) { case true: notifyPRSuccess(); break } } } return this