From 82205785d343d0b24c7eaf65793931cb03572c35 Mon Sep 17 00:00:00 2001 From: peri4 Date: Wed, 25 Dec 2024 12:30:12 +0300 Subject: [PATCH] version 2 --- README.md | 43 +++++++++++++++--- src/org/SHS/Platforms.groovy | 84 ++++++++++++++++++++++++++++++++---- 2 files changed, 112 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 854b26a..a884f70 100644 --- a/README.md +++ b/README.md @@ -4,18 +4,38 @@ This repo add functionality for automate building with `platforms.json` configur ## Setup -You should add `PLATFORMS_GIT` environment to your Jenkins with url to git repo, which -contains single `platforms.json` file. +You should add `PLATFORMS_GIT` and `PLATFORMS_FILTER_GIT` environment to your Jenkins with url to git repo, which +contains single `platforms.json` and `filter.json` file. + +`PLATFORMS_GIT` -> `platforms.json` + +`PLATFORMS_FILTER_GIT` -> `filter.json` Next you should register this library in Jenkins -> System settings -> Global Pipeline Libraries: * Library name: `SHS.Platforms` * Default version: `master` * Project Repository: `https://git.shstk.ru/SHS/jenkins_lib.git` +Then create pipeline job with fixed name `shstk-platforms` and set script to: +``` +@Library('SHS.Platforms') _ +node { + properties([copyArtifactPermission('*')]) + def pl = new org.SHS.Platforms(this) + pl.createLocal() +} +``` +If you want to copy final json to host, add +``` +pl.copyToHost('/your/path/platforms.json') +``` + ## API `org.SHS.Platforms` Class: - * `get()` - download and parse `platforms.json` file from `PLATFORMS_GIT` + * `createLocal()` - download and parse `platforms.json` from `PLATFORMS_GIT` and `filter.json` from `PLATFORMS_FILTER_GIT`, filter/prepare final JSON and save it to artifact + * `copyToHost(path)` - call after createLocal() to copy final JSON to `path` on your host + * `get()` - read and parse `platforms_local.json` file from "shstk-platforms" artifact * `root()` - returns root JSON object of `platforms.json` * `forEach(func, ...)` - iterate over platforms, `func` is only mandatory parameter: * `func` - method to execute for each enabled platform, pass JSON element of current platform and optional CMake toolchain argument @@ -29,6 +49,15 @@ Next you should register this library in Jenkins -> System settings -> Global Pi ## Usage +Prepare your local configuration (when platforms or filter changed): +``` +@Library('SHS.Platforms') _ +node { + def pl = new org.SHS.Platforms(this) + pl.createLocal() +} +``` + Simple: ``` @Library('SHS.Platforms') _ @@ -36,7 +65,7 @@ node { def pl = new org.SHS.Platforms(this) pl.get() pl.forEach ({ dist -> - print("works in ${dist.docker_image}") + print("works in ${dist.docker.image_basename}") }) } ``` @@ -48,19 +77,19 @@ node { def pl = new org.SHS.Platforms(this) pl.get() pl.forEach ({ dist, cmake_toolchain -> - print("compile in ${dist.docker_image} with arg ${cmake_toolchain}") + print("compile in ${dist.docker.image_basename} with arg ${cmake_toolchain}") }) } ``` -With filter: +With white/black lists: ``` @Library('SHS.Platforms') _ node { def pl = new org.SHS.Platforms(this) pl.get() pl.forEach ({ dist -> - print("works in ${dist.docker_image}") + print("works in ${dist.docker.image_basename}") }, stagePrefix: "Build ", stageSuffix: " soft", diff --git a/src/org/SHS/Platforms.groovy b/src/org/SHS/Platforms.groovy index e448876..41f24eb 100644 --- a/src/org/SHS/Platforms.groovy +++ b/src/org/SHS/Platforms.groovy @@ -3,16 +3,18 @@ package org.SHS class Platforms { def steps def _root + def _filter public Platforms(steps) {this.steps = steps} public void get() { - steps.stage("Download platforms.json") { - steps.dir("platforms_git") { - steps.deleteDir() - steps.git url: "${steps.env.PLATFORMS_GIT}" - this._root = steps.readJSON(file: 'platforms.json') - } + steps.stage("Read platforms_local.json") { + steps.CopyArtifact(projectName: 'shstk-platforms', target: 'platforms'); + this._root = steps.readJSON(file: "platforms/platforms_local.json") + /*if (steps.env.PLATFORMS_LOCAL_DIR == null) { + steps.error "Add \"PLATFORMS_LOCAL_DIR\" node environment to local directory with write permission" + } + this._root = steps.readJSON(file: "${steps.env.PLATFORMS_LOCAL_DIR}/platforms_local.json")*/ } } @@ -32,6 +34,72 @@ class Platforms { } public void forEach(functor) { forEach(functor, stagePrefix: "") } + public void createLocal() { + if (steps.env.PLATFORMS_GIT == null) { + steps.error "Add \"PLATFORMS_GIT\" node environment to git repo with \"platforms.json\" file (e.g. https://git.shstk.ru/SHS/platforms)" + } + if (steps.env.PLATFORMS_FILTER_GIT == null) { + steps.error "Add \"PLATFORMS_FILTER_GIT\" node environment to git repo with \"filter.json\" file (e.g. https://git.shstk.ru/SHS/platforms-SHS)" + } + /*if (steps.env.PLATFORMS_LOCAL_DIR == null) { + steps.error "Add \"PLATFORMS_LOCAL_DIR\" node environment to local directory with write permission" + }*/ + steps.dir("platforms_git") { + steps.stage("Create platforms_local.json") { + + steps.deleteDir() + steps.git url: "${steps.env.PLATFORMS_GIT}" + this._root = steps.readJSON(file: 'platforms_new.json') + + steps.deleteDir() + steps.git url: "${steps.env.PLATFORMS_FILTER_GIT}" + this._filter = steps.readJSON(file: 'filter.json') + + } + } + def ret = [:] + def iinst = [:] + def wlist = [] + def blist = [] + ret.platforms = [:] + if (this._root.containsKey('install_instructions')) { + iinst = this._root.install_instructions + } + if (this._filter.containsKey('whiteList')) { + wlist = this._filter.whiteList + } + if (this._filter.containsKey('blackList')) { + blist = this._filter.blackList + } + this._root.platforms.each({name, dist -> + if (filterDist(name, dist, wlist, blist, true)) { + // steps.print "${name} filter ok" + if (dist.containsKey('ppa')) { + if (dist.ppa.containsKey('install_instructions')) { + if (dist.ppa.install_instructions instanceof String) { + dist.ppa.install_instructions = iinst[dist.ppa.install_instructions] + if (dist.ppa.install_instructions == null) { + steps.error "Invalid \"ppa.install_instructions\" reference for \"${name}\"" + } + } + // steps.print dist.ppa.install_instructions + } + } + ret.platforms[name] = dist + } else { + // steps.print "${name} filter fail" + } + }) + steps.writeJSON(file: "platforms_local.json", json: ret, pretty: 2) + steps.archiveArtifacts("platforms_local.json") + // steps.writeJSON(file: "${steps.env.PLATFORMS_LOCAL_DIR}/platforms_local.json", json: ret, pretty: 2) + } + + public void copyToHost(path) { + steps.writeJSON(file: path, json: steps.readJSON(file: "platforms_local.json"), pretty: 2) + } + + //@NonCPS private Boolean filterDist(name, dist, whiteList, blackList, ondemand) { if (!dist.enabled) { @@ -52,11 +120,11 @@ class Platforms { private def filterJSON(whiteList, blackList, ondemand) { def ret = [:] - _root.Platforms.each({name, dist -> + _root.platforms.each({name, dist -> if (filterDist(name, dist, whiteList, blackList, ondemand)) ret[name] = dist }) return ret } - + }