diff --git a/.gitignore b/.gitignore index a3688191..b407c63b 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,8 @@ nodekey *.aar *.jar +pkg/* + # output binaries go-waku @@ -77,7 +79,6 @@ xcuserdata/ *.xccheckout ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) -build/ DerivedData/ *.moved-aside *.pbxuser diff --git a/Makefile b/Makefile index cf1179c0..0ba7acbf 100644 --- a/Makefile +++ b/Makefile @@ -124,7 +124,7 @@ endif mobile-android: gomobile init && \ - gomobile bind -target=android -ldflags="-s -w" $(BUILD_FLAGS) -o ./build/lib/gowaku.aar ./mobile + gomobile bind -v -target=android -ldflags="-s -w" $(BUILD_FLAGS) -o ./build/lib/gowaku.aar ./mobile @echo "Android library built:" @ls -la ./build/lib/*.aar ./build/lib/*.jar @@ -133,3 +133,14 @@ mobile-ios: gomobile bind -target=ios -ldflags="-s -w" -o ./build/lib/Gowaku.xcframework ./mobile @echo "IOS library built:" @ls -la ./build/lib/*.xcframework + +install-xtools: + go install golang.org/x/tools/...@v0.1.10 + +install-gomobile: install-xtools + go install golang.org/x/mobile/cmd/gomobile@v0.0.0-20220518205345-8578da9835fd + go install golang.org/x/mobile/cmd/gobind@v0.0.0-20220518205345-8578da9835fd + +build-linux-pkg: + ./scripts/linux/docker-run.sh + ls -la ./build/*.rpm ./build/*.deb diff --git a/build/.gitignore b/build/.gitignore index 2db665d9..542c5c2e 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -1,3 +1,4 @@ * !.gitignore -!lib \ No newline at end of file +!lib +!lib/* \ No newline at end of file diff --git a/build/lib/.gitignore b/build/lib/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/build/lib/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/ci/Jenkinsfile b/ci/Jenkinsfile index f5383444..88a98ac9 100644 --- a/ci/Jenkinsfile +++ b/ci/Jenkinsfile @@ -1,39 +1,94 @@ +library 'status-jenkins-lib@v1.4.3' + pipeline { - agent { - label 'linux' - } + agent { label 'linux' } options { timestamps() + disableConcurrentBuilds() + /* Prevent Jenkins jobs from running forever */ + timeout(time: 40, unit: 'MINUTES') + /* Limit builds retained */ buildDiscarder(logRotator( numToKeepStr: '10', daysToKeepStr: '30', + artifactNumToKeepStr: '10', )) } - environment { - GOPATH = "${env.HOME}/go" - PATH = "${env.PATH}:${env.GOPATH}/bin" + /* WARNING: Defining parameters here with the ?: trick causes them to remember last value. */ + parameters { + booleanParam( + name: 'PUBLISH', + description: 'Trigger publishing of build results for nightly or release.', + defaultValue: getPublishDefault(params.PUBLISH), + ) } stages { - stage('Deps') { - steps { sh 'make deps' } + stage('Build') { + parallel { + stage('iOS') { steps { script { + ios = jenkins.Build('go-waku/platforms/ios') + } } } + stage('Android') { steps { script { + android = jenkins.Build('go-waku/platforms/android') + } } } + } } - - stage('Lint') { - steps { sh 'make lint' } + stage('Archive') { + steps { script { + sh('rm -f pkg/*') + jenkins.copyArts(ios) + jenkins.copyArts(android) + sha = "pkg/${utils.pkgFilename(ext: 'sha256')}" + dir('pkg') { + /* generate sha256 checksums for upload */ + sh "sha256sum * | tee ../${sha}" + archiveArtifacts('*') + } + } } } - - stage('Test') { - steps { sh 'make test-ci' } + stage('Upload') { + steps { script { + /* object for easier URLs handling */ + urls = [ + /* mobile */ + Android: utils.pkgUrl(android), + // iOS: utils.pkgUrl(ios), + /* upload the sha256 checksums file too */ + SHA: s3.uploadArtifact(sha), + ] + /* add URLs to the build description */ + jenkins.setBuildDesc(urls) + } } } - - stage('Build example') { - steps { sh 'make build-example' } + stage('Publish') { + when { expression { params.PUBLISH } } + steps { script { + github.publishReleaseFiles(repo: 'status-desktop'); + } } } } - post { - always { cleanWs() } - } } + +/* Helper that generates list of available choices for a parameter + * but re-orders them based on the currently set value. First is default. */ +def List genChoices(String previousChoice, List defaultChoices) { + if (previousChoice == null) { + return defaultChoices + } + choices = defaultChoices.minus(previousChoice) + choices.add(0, previousChoice) + return choices +} + +/* Helper that makes PUBLISH default to 'false' unless: + * - The build is for a release branch + * - A user explicitly specified a value + * Since release builds create and re-create GitHub drafts every time. */ +def Boolean getPublishDefault(Boolean previousValue) { + if (env.JOB_NAME.startsWith('go-waku/release')) { return true } + if (previousValue != null) { return previousValue } + return false +} \ No newline at end of file diff --git a/ci/Jenkinsfile.android b/ci/Jenkinsfile.android new file mode 100644 index 00000000..e3a0844a --- /dev/null +++ b/ci/Jenkinsfile.android @@ -0,0 +1,83 @@ +library 'status-jenkins-lib@v1.3.3' + +pipeline { + agent { label 'linux && x86_64 && go-1.18' } + + options { + timestamps() + disableConcurrentBuilds() + /* Prevent Jenkins jobs from running forever */ + timeout(time: 30, unit: 'MINUTES') + /* Go requires a certain directory structure */ + checkoutToSubdirectory('src/github.com/status-im/go-waku') + /* Limit builds retained */ + buildDiscarder(logRotator( + numToKeepStr: '10', + daysToKeepStr: '20', + artifactNumToKeepStr: '10', + )) + /* Allows combined build to copy */ + copyArtifactPermission('/go-waku/*') + } + + environment { + BUILD_PLATFORM = 'android' + CC="gcc-10" + /* Other stuff */ + TARGET = 'android' + REPO = "${env.WORKSPACE}/src/github.com/status-im/go-waku" + GOPATH = "${env.WORKSPACE}" + PATH = "/usr/local/go/bin:${env.PATH}:${env.GOPATH}/bin" + /* Android SDK */ + ANDROID_HOME = '/usr/lib/android-sdk' + ANDROID_SDK_ROOT = '/usr/lib/android-sdk' + /* gomobile requires a specific NDK version */ + ANDROID_NDK = "/opt/android-ndk-r23c" + ANDROID_NDK_HOME = "/opt/android-ndk-r23c" + } + + stages { + + stage('Prep') { steps { dir(env.REPO) { script { + env.ARTIFACT = "${env.REPO}/pkg/" + utils.pkgFilename( + name: "go-waku", + type: "android", + ext: "tar.gz" + ) + + sh 'make install-gomobile' + + println("Output: ${env.ARTIFACT}") + } } } } + + stage('Build') { steps { dir(env.REPO) { + sh 'make mobile-android || true' + sh 'make mobile-android' + dir('build/lib') { + sh 'tar -czvf gowaku-android.tar.gz gowaku.aar gowaku-sources.jar' + sh "cp gowaku-android.tar.gz ${env.ARTIFACT}" + } + } } } + + stage('Parallel Upload') { + parallel { + stage('Archive') { + steps { script { + archiveArtifacts(env.ARTIFACT.minus("${env.WORKSPACE}/")) + } } + } + stage('Upload') { + steps { script { + env.PKG_URL = s3.uploadArtifact(env.ARTIFACT) + jenkins.setBuildDesc(android: env.PKG_URL) + } } + } + } + } + } + post { + success { script { github.notifyPR(true) } } + failure { script { github.notifyPR(false) } } + always { cleanWs() } + } +} \ No newline at end of file diff --git a/ci/Jenkinsfile.ios b/ci/Jenkinsfile.ios new file mode 100644 index 00000000..4a97c9f8 --- /dev/null +++ b/ci/Jenkinsfile.ios @@ -0,0 +1,75 @@ +library 'status-jenkins-lib@v1.3.3' + +pipeline { + agent { label 'macos && x86_64' } + + options { + timestamps() + /* Prevent Jenkins jobs from running forever */ + timeout(time: 30, unit: 'MINUTES') + /* Go requires a certain directory structure */ + checkoutToSubdirectory('src/github.com/status-im/go-waku') + /* Limit builds retained */ + buildDiscarder(logRotator( + numToKeepStr: '10', + daysToKeepStr: '20', + artifactNumToKeepStr: '10', + )) + /* Allows combined build to copy */ + copyArtifactPermission('/go-waku/*') + } + + environment { + BUILD_PLATFORM = 'android' + + /* Other stuff */ + TARGET = 'ios' + REPO = "${env.WORKSPACE}/src/github.com/status-im/go-waku" + GOPATH = "${env.WORKSPACE}" + PATH = "/usr/local/go/bin:${env.PATH}:${env.GOPATH}/bin" + } + + stages { + + stage('Prep') { steps { dir(env.REPO) { script { + env.ARTIFACT = "${env.REPO}/pkg/" + utils.pkgFilename( + name: "go-waku", + type: "ios", + ext: "tar.gz" + ) + + sh 'make install-gomobile' + + println("Output: ${env.ARTIFACT}") + } } } } + + stage('Build') { steps { dir(env.REPO) { + sh 'make mobile-ios' + dir('build/lib') { + sh 'tar -czvf gowaku-ios.tar.gz Gowaku.xcframework' + sh "cp gowaku-ios.tar.gz ${env.ARTIFACT}" + } + } } } + + stage('Parallel Upload') { + parallel { + stage('Archive') { + steps { script { + archiveArtifacts(env.ARTIFACT.minus("${env.WORKSPACE}/")) + } } + } + stage('Upload') { + steps { script { + env.PKG_URL = s3.uploadArtifact(env.ARTIFACT) + jenkins.setBuildDesc(ios: env.PKG_URL) + } } + } + } + } + } + post { + success { script { github.notifyPR(true) } } + failure { script { github.notifyPR(false) } } + always { cleanWs() } + } +} \ No newline at end of file diff --git a/ci/Jenkinsfile.old b/ci/Jenkinsfile.old new file mode 100644 index 00000000..4c0704a2 --- /dev/null +++ b/ci/Jenkinsfile.old @@ -0,0 +1,51 @@ +pipeline { + agent { + label 'linux' + } + + options { + timestamps() + disableConcurrentBuilds() + buildDiscarder(logRotator( + numToKeepStr: '10', + daysToKeepStr: '30', + )) + } + + environment { + GOPATH = "${env.HOME}/go" + PATH = "${env.PATH}:${env.GOPATH}/bin" + } + + stages { + stage('Deps') { + steps { sh 'make deps' } + } + + stage('Lint') { + steps { sh 'make lint' } + } + + stage('Test') { + steps { sh 'make test-ci' } + } + + stage('Build example') { + steps { sh 'make build-example' } + } + + stage('Build go-mobile') { + parallel { + stage('Linux') { steps { script { + linux = jenkins.Build('go-waku/platforms/linux') + } } } + stage('MacOS') { steps { script { + macos = jenkins.Build('go-waku/platforms/macos') + } } } + } + } + } + post { + always { cleanWs() } + } +} diff --git a/go.mod b/go.mod index cd04b6e3..cb497518 100644 --- a/go.mod +++ b/go.mod @@ -145,11 +145,12 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.7.0 // indirect golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect + golang.org/x/mobile v0.0.0-20220518205345-8578da9835fd // indirect golang.org/x/mod v0.5.0 // indirect golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 // indirect golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect - golang.org/x/tools v0.1.5 // indirect + golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect diff --git a/go.sum b/go.sum index 44607237..97309439 100644 --- a/go.sum +++ b/go.sum @@ -1758,6 +1758,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= @@ -1890,6 +1891,7 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= @@ -1921,7 +1923,10 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mobile v0.0.0-20220518205345-8578da9835fd h1:x1GptNaTtxPAlTVIAJk61fuXg0y17h09DTxyb+VNC/k= +golang.org/x/mobile v0.0.0-20220518205345-8578da9835fd/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= @@ -2302,6 +2307,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098 h1:YuekqPskqwCCPM79F1X5Dhv4ezTCj+Ki1oNwiafxkA0= +golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/.gitkeep b/pkg/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/scripts/linux/Dockerfile b/scripts/linux/Dockerfile new file mode 100644 index 00000000..29b36c98 --- /dev/null +++ b/scripts/linux/Dockerfile @@ -0,0 +1,27 @@ +# BUILD IMAGE -------------------------------------------------------- +FROM ubuntu:18.04 + +LABEL maintainer="richard@status.im" +LABEL source="https://github.com/status-im/go-waku" +LABEL description="go-waku: deb/rpm builder" + +RUN export DEBIAN_FRONTEND=noninteractive \ + && apt update -yq \ + && apt install -yq ruby wget git rpm build-essential + +# Installing Golang +RUN GOLANG_SHA256="d69a4fe2694f795d8e525c72b497ededc209cb7185f4c3b62d7a98dd6227b3fe" \ + && GOLANG_TARBALL="go1.17.11.linux-amd64.tar.gz" \ + && wget -q "https://dl.google.com/go/${GOLANG_TARBALL}" \ + && echo "${GOLANG_SHA256} ${GOLANG_TARBALL}" | sha256sum -c \ + && tar -C /usr/local -xzf "${GOLANG_TARBALL}" \ + && rm "${GOLANG_TARBALL}" \ + && ln -s /usr/local/go/bin/go /usr/local/bin + +RUN gem install fpm + +# Jenkins user needs a specific UID/GID to work +RUN groupadd -g 1001 jenkins \ + && useradd --create-home -u 1001 -g 1001 jenkins +USER jenkins +ENV HOME="/home/jenkins" \ No newline at end of file diff --git a/scripts/linux/README.md b/scripts/linux/README.md new file mode 100644 index 00000000..7d282f84 --- /dev/null +++ b/scripts/linux/README.md @@ -0,0 +1,11 @@ +# Description + +This script is used to build .deb and .rpm packages + +# Builds + +## Linux + +``` +docker build -t statusteam/gowaku-linux-pkgs:latest . +``` diff --git a/scripts/linux/build-pkgs.sh b/scripts/linux/build-pkgs.sh new file mode 100755 index 00000000..efb3e0f6 --- /dev/null +++ b/scripts/linux/build-pkgs.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +git config --global --add safe.directory /go-waku + +make + +cd /go-waku/scripts/linux + +parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )/../../ + +VERSION=`cat ${parent_path}/VERSION` + +if [ ! -f ${parent_path}/build/waku ] +then + echo "waku binary does not exist. Execute make first" + exit +fi + +tmpdir=`mktemp -d` + +cp ${parent_path}/build/waku ${tmpdir} + +strip --strip-unneeded ${tmpdir}/waku + +pushd ${tmpdir} + +ls . + +fpm_build () { + fpm \ + -s dir -t $1 \ + -p gowaku-${VERSION}-x86_64.$1 \ + --name go-waku \ + --license "MIT, Apache 2.0" \ + --version ${VERSION} \ + --architecture x86_64 \ + --depends libc6 \ + --description "Go implementation of Waku v2 protocol" \ + --url "https://github.com/status-im/go-waku" \ + --maintainer "Richard Ramos " \ + waku=/usr/bin/waku +} + +fpm_build "deb" +fpm_build "rpm" + +mv *.deb *.rpm ${parent_path}/build/. + +popd diff --git a/scripts/linux/docker-run.sh b/scripts/linux/docker-run.sh new file mode 100755 index 00000000..8385f284 --- /dev/null +++ b/scripts/linux/docker-run.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +docker run -it --rm \ + --cap-add SYS_ADMIN \ + --security-opt apparmor:unconfined \ + --device /dev/fuse \ + -u jenkins:$(getent group $(whoami) | cut -d: -f3) \ + -v "${PWD}:/go-waku" \ + -w /go-waku \ + statusteam/gowaku-linux-pkgs:latest \ + /go-waku/scripts/linux/build-pkgs.sh