From 80fbdba0acc7d8d245f6036a51f6eeb6c5b7b277 Mon Sep 17 00:00:00 2001 From: Vedran Mendelski Date: Mon, 16 Sep 2024 17:32:22 +0200 Subject: [PATCH] chore_: enable windows and macos CI build - Added support for Windows and macOS in CI pipelines - Added missing dependencies for Windows and x86-64-darwin - Resolved macOS SDK version compatibility for darwin-x86_64 The `mkShell` override was necessary to ensure compatibility with the newer macOS SDK (version 11.0) for x86_64. The default SDK (10.12) was causing build failures because of the missing libs and frameworks. OverrideSDK creates a mapping from the default SDK in all package categories to the requested SDK (11.0). --- Makefile | 5 + _assets/ci/Jenkinsfile | 8 +- _assets/ci/Jenkinsfile.desktop | 166 +++++++++++++++++++++++++++++++ _assets/ci/Jenkinsfile.linux | 101 +------------------ _assets/ci/Jenkinsfile.macos | 1 + _assets/ci/Jenkinsfile.windows | 1 + nix/pkgs/codecov-cli/default.nix | 1 + nix/shell.nix | 7 +- 8 files changed, 188 insertions(+), 102 deletions(-) create mode 100644 _assets/ci/Jenkinsfile.desktop mode change 100644 => 120000 _assets/ci/Jenkinsfile.linux create mode 120000 _assets/ci/Jenkinsfile.macos create mode 120000 _assets/ci/Jenkinsfile.windows diff --git a/Makefile b/Makefile index 0d0916ee48e..4149ccba87c 100644 --- a/Makefile +++ b/Makefile @@ -193,6 +193,11 @@ statusgo-cross: statusgo-android statusgo-ios @echo "Full cross compilation done." @ls -ld build/bin/statusgo-* +status-go-deps: + go install go.uber.org/mock/mockgen@v0.4.0 + go install github.com/kevinburke/go-bindata/v4/...@v4.0.2 + go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.34.1 + statusgo-android: generate statusgo-android: ##@cross-compile Build status-go for Android @echo "Building status-go for Android..." diff --git a/_assets/ci/Jenkinsfile b/_assets/ci/Jenkinsfile index ed66572c3e0..ab3fa726d18 100644 --- a/_assets/ci/Jenkinsfile +++ b/_assets/ci/Jenkinsfile @@ -1,5 +1,5 @@ #!/usr/bin/env groovy -library 'status-jenkins-lib@v1.9.6' +library 'status-jenkins-lib@v1.9.12' pipeline { agent { label 'linux' } @@ -52,6 +52,12 @@ pipeline { stage('Linux') { steps { script { linux = jenkins.Build('status-go/platforms/linux') } } } + stage('MacOS') { steps { script { + linux = jenkins.Build('status-go/platforms/macos') + } } } + stage('Windows') { steps { script { + linux = jenkins.Build('status-go/platforms/windows') + } } } stage('Docker') { steps { script { dock = jenkins.Build('status-go/platforms/docker') } } } diff --git a/_assets/ci/Jenkinsfile.desktop b/_assets/ci/Jenkinsfile.desktop new file mode 100644 index 00000000000..c7e460c8468 --- /dev/null +++ b/_assets/ci/Jenkinsfile.desktop @@ -0,0 +1,166 @@ +#!/usr/bin/env groovy +library 'status-jenkins-lib@v1.9.12' + +pipeline { + /* This way we run the same Jenkinsfile on different platforms. */ + agent { label "${params.AGENT_LABEL}" } + + parameters { + string( + name: 'BRANCH', + defaultValue: 'develop', + description: 'Name of branch to build.' + ) + string( + name: 'AGENT_LABEL', + description: 'Label for targetted CI slave host.', + defaultValue: params.AGENT_LABEL ?: getAgentLabel(), + ) + booleanParam( + name: 'RELEASE', + defaultValue: false, + description: 'Enable to create build for release.', + ) + } + + options { + timestamps() + ansiColor('xterm') + /* Prevent Jenkins jobs from running forever */ + timeout(time: 15, unit: 'MINUTES') + disableConcurrentBuilds() + /* manage how many builds we keep */ + buildDiscarder(logRotator( + numToKeepStr: '5', + daysToKeepStr: '30', + artifactNumToKeepStr: '1', + )) + } + + environment { + PLATFORM = getPlatformFromLabel(params.AGENT_LABEL) + TMPDIR = "${WORKSPACE_TMP}" + GOPATH = "${WORKSPACE_TMP}/go" + GOCACHE = "${WORKSPACE_TMP}/gocache" + PATH = "${PATH}:${GOPATH}/bin:/c/Users/jenkins/go/bin" + REPO_SRC = "${GOPATH}/src/github.com/status-im/status-go" + VERSION = sh(script: "./_assets/scripts/version.sh", returnStdout: true) + ARTIFACT = utils.pkgFilename( + name: 'status-go', + type: env.PLATFORM, + version: env.VERSION, + ext: 'zip', + ) + /* prevent sharing cache dir across different jobs */ + GO_GENERATE_FAST_DIR = "${env.WORKSPACE_TMP}/go-generate-fast" + } + + stages { + stage('Setup') { + steps { + script { + if (env.PLATFORM != 'windows') { + sh "mkdir -p \$(dirname ${REPO_SRC})" + sh "ln -s ${WORKSPACE} ${REPO_SRC}" + } + } + } + } + + stage('Deps') { + steps { script { + shell('make status-go-deps') + } + } + } + + stage('Generate') { + steps { script { + shell('make generate') + } + } + } + + stage('Build Static Lib') { + steps { + script { + shell('make statusgo-library') + } + } + } + + stage('Build Shared Lib') { + steps { + script { + shell('make statusgo-shared-library') + } + } + } + + stage('Archive') { + steps { + zip zipFile: "${ARTIFACT}", archive: true, dir: 'build/bin' + } + } + + stage('Upload') { + steps { + script { + env.PKG_URL = s5cmd.upload(ARTIFACT) + } + } + } + stage('Cleanup') { + steps { + script { + cleanTmp() + } + } + } +} // stages + post { + success { script { github.notifyPR(true) } } + failure { script { github.notifyPR(false) } } + cleanup { cleanWs() } + } // post +} // pipeline + +/* This allows us to use one Jenkinsfile and run + * jobs on different platforms based on job name. */ +def getAgentLabel() { + if (params.AGENT_LABEL) { return params.AGENT_LABEL } + /* We extract the name of the job from currentThread because + * before an agent is picket env is not available. */ + def tokens = Thread.currentThread().getName().split('/') + def labels = [] + /* Check if the job path contains any of the valid labels. */ + ['linux', 'macos', 'windows', 'x86_64', 'aarch64', 'arm64'].each { + if (tokens.contains(it)) { labels.add(it) } + } + return labels.join(' && ') +} + +/* This function extracts the platform from the AGENT_LABEL */ +def getPlatformFromLabel(label) { + for (platform in ['linux', 'macos', 'windows']) { + if (label.contains(platform)) { + return platform + } + } +} + +def shell(cmd) { + if (env.PLATFORM == 'windows') { + sh "${cmd} SHELL=/bin/sh" + } else { + nix.shell(cmd, pure: false) // Use nix.shell for Linux/macOS + } +} + +def cleanTmp() { + if (env.PLATFORM == 'windows') { + sh "rm -rf ${env.WORKSPACE}@tmp" + } else { + dir("${env.WORKSPACE}@tmp") { deleteDir() } + } +} \ No newline at end of file diff --git a/_assets/ci/Jenkinsfile.linux b/_assets/ci/Jenkinsfile.linux deleted file mode 100644 index 869b26b28f4..00000000000 --- a/_assets/ci/Jenkinsfile.linux +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env groovy -library 'status-jenkins-lib@v1.9.6' - -pipeline { - agent { label 'linux && x86_64 && nix-2.19' } - - parameters { - string( - name: 'BRANCH', - defaultValue: 'develop', - description: 'Name of branch to build.' - ) - booleanParam( - name: 'RELEASE', - defaultValue: false, - description: 'Enable to create build for release.', - ) - } - - options { - timestamps() - ansiColor('xterm') - /* Prevent Jenkins jobs from running forever */ - timeout(time: 10, unit: 'MINUTES') - disableConcurrentBuilds() - /* manage how many builds we keep */ - buildDiscarder(logRotator( - numToKeepStr: '5', - daysToKeepStr: '30', - artifactNumToKeepStr: '1', - )) - } - - environment { - PLATFORM = 'linux' - TMPDIR = "${WORKSPACE_TMP}" - GOPATH = "${WORKSPACE_TMP}/go" - GOCACHE = "${WORKSPACE_TMP}/gocache" - PATH = "${PATH}:${GOPATH}/bin" - REPO_SRC = "${GOPATH}/src/github.com/status-im/status-go" - VERSION = sh(script: "./_assets/scripts/version.sh", returnStdout: true) - ARTIFACT = utils.pkgFilename( - name: 'status-go', - type: env.PLATFORM, - version: env.VERSION, - ext: 'zip', - ) - /* prevent sharing cache dir across different jobs */ - GO_GENERATE_FAST_DIR = "${env.WORKSPACE_TMP}/go-generate-fast" - } - - stages { - stage('Setup') { - steps { /* Go needs to find status-go in GOPATH. */ - sh "mkdir -p \$(dirname ${REPO_SRC})" - sh "ln -s ${WORKSPACE} ${REPO_SRC}" - } - } - - stage('Generate') { - steps { script { - nix.shell('make generate', pure: false) - } } - } - - /* Sanity-check C bindings */ - stage('Build Static Lib') { - steps { script { - nix.shell('make statusgo-library', pure: false) - } } - } - - stage('Build Shared Lib') { - steps { script { - nix.shell('make statusgo-shared-library', pure: false) - } } - } - - stage('Archive') { - steps { - sh "zip -q -r ${ARTIFACT} build/bin" - archiveArtifacts(ARTIFACT) - } - } - - stage('Upload') { - steps { script { - env.PKG_URL = s5cmd.upload(ARTIFACT) - } } - } - } // stages - post { - success { script { github.notifyPR(true) } } - failure { script { github.notifyPR(false) } } - cleanup { - cleanWs() - dir("${env.WORKSPACE}@tmp") { deleteDir() } - } - } // post -} // pipeline diff --git a/_assets/ci/Jenkinsfile.linux b/_assets/ci/Jenkinsfile.linux new file mode 120000 index 00000000000..6047babb30e --- /dev/null +++ b/_assets/ci/Jenkinsfile.linux @@ -0,0 +1 @@ +Jenkinsfile.desktop \ No newline at end of file diff --git a/_assets/ci/Jenkinsfile.macos b/_assets/ci/Jenkinsfile.macos new file mode 120000 index 00000000000..6047babb30e --- /dev/null +++ b/_assets/ci/Jenkinsfile.macos @@ -0,0 +1 @@ +Jenkinsfile.desktop \ No newline at end of file diff --git a/_assets/ci/Jenkinsfile.windows b/_assets/ci/Jenkinsfile.windows new file mode 120000 index 00000000000..6047babb30e --- /dev/null +++ b/_assets/ci/Jenkinsfile.windows @@ -0,0 +1 @@ +Jenkinsfile.desktop \ No newline at end of file diff --git a/nix/pkgs/codecov-cli/default.nix b/nix/pkgs/codecov-cli/default.nix index 12fbf83e01b..b342a1561e2 100644 --- a/nix/pkgs/codecov-cli/default.nix +++ b/nix/pkgs/codecov-cli/default.nix @@ -16,6 +16,7 @@ in stdenv.mkDerivation rec { url = "https://cli.codecov.io/v${version}/${platform}/codecov"; hash = lib.getAttr builtins.currentSystem { aarch64-darwin = "sha256-CB1D8/zYF23Jes9sd6rJiadDg7nwwee9xWSYqSByAlU="; + x86_64-darwin = "sha256-CB1D8/zYF23Jes9sd6rJiadDg7nwwee9xWSYqSByAlU="; x86_64-linux = "sha256-65AgCcuAD977zikcE1eVP4Dik4L0PHqYzOO1fStNjOw="; aarch64-linux = "sha256-hALtVSXY40uTIaAtwWr7EXh7zclhK63r7a341Tn+q/g="; }; diff --git a/nix/shell.nix b/nix/shell.nix index 10f2647c77e..5a29bac6aa3 100644 --- a/nix/shell.nix +++ b/nix/shell.nix @@ -16,7 +16,12 @@ let inherit xcodeWrapper; withAndroidPkgs = !isMacM1; }; -in pkgs.mkShell { + /* Override the default SDK to enable darwin-x86_64 builds */ + appleSdk11Stdenv = pkgs.overrideSDK pkgs.stdenv "11.0"; + sdk11mkShell = pkgs.mkShell.override { stdenv = appleSdk11Stdenv; }; + mkShell = if stdenv.isDarwin then sdk11mkShell else pkgs.mkShell; + +in mkShell { name = "status-go-shell"; buildInputs = with pkgs; [