status-react/ci/github.groovy

210 lines
5.5 KiB
Groovy
Raw Normal View History

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.isE2EBuild() ? ' e2e' : ''
msg += "[${env.JOB_NAME}${currentBuild.displayName}](${currentBuild.absoluteUrl}) ${d} "
msg += "${ghcmgr.utils.buildDuration()} ${d} ${GIT_COMMIT.take(8)} ${d} "
major nix refactor Changes: - Adds a new `nix-gc` Makefile target for removing old packages - Moves all `nix/*.sh` files to `nix/scripts/*.sh` to make things more tidy - Renames `TARGET_OS` into `TARGET` and makes it effective only with `nix/scripts/shell.sh` - Renames `target-os` Nix argument to just `target` and makes it effective only with `shell.nix` - Drops `IN_CI_ENVIRONMENT` env variable which was useless - Drops use of `target-os` argument outside of `shell.nix` (with few exceptions, but just in naming) - `nix/platform.nix` has been made obsolete and removed - Moves the definition of all major targets to `nix/targets.nix` - Moves the definition of all major shells to `nix/shells.nix` - Makes `default.nix` and `shell.nix` just thin wrappers around `nix/default.nix` - `nix/nixpkgs-bootstrap.nix` has been moved to `nix/pkgs.nix` - All package and tool overrides have been moved to `nix/pkgs.nix` - Explicit passing of contents of `pkgs` has been removed in favor of `callPackage` doing it for us - `nix/bootstrapped-shell.nix` has been moved to `nix/tools/mkShell.nix` - A new `mergeSh` tool has been added to `pkgs` from `nix/tools/mergeSh.nix` - This tool is used to merge shells created using `mkShell` - `mobile/targets/jsbundle.nix` has been moved to `mobile/android/jsbundle/default.nix` - Moves `status-go` version sanitization to `nix/status-go/utils.nix` - Renames version to rawVersion and versionName to cleanVersion in status-go derivation - Ports nix/mobile/ios/install-pods-and-status-go.sh to Nix sub-shells - Moves adjustment of `inotify/max_user_watches` out into `scripts/inotify_fix.sh` - Makes iOS builds use the Nix version of Fastlane Signed-off-by: Jakub Sokołowski <jakub@status.im>
2019-11-29 10:20:08 +00:00
msg += "[:package: ${env.TARGET}${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(path='pkg') {
def found = findFiles(glob: "${path}/*")
if (found.size() == 0) {
sh "ls ${path}"
error("No file to release in ${path}")
}
publishRelease(
version: ghcmgr.utils.getVersion(),
pkgDir: 'pkg',
files: found.collect { it.path },
)
}
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