From 0e0be144155123b9a43c6331ef328e9a7bc8ef90 Mon Sep 17 00:00:00 2001 From: andreas Date: Tue, 5 Sep 2023 21:15:07 +0200 Subject: [PATCH] first trigger of builds via GUI --- webinstall/cibuild.css | 3 ++ webinstall/cibuild.html | 38 +++++++++++++++ webinstall/cibuild.js | 98 +++++++++++++++++++++++++++++++++++++++ webinstall/helper.js | 96 ++++++++++++++++++++++++++++++++++++++ webinstall/install.html | 2 +- webinstall/install.js | 6 +-- webinstall/installUtil.js | 33 ------------- 7 files changed, 239 insertions(+), 37 deletions(-) create mode 100644 webinstall/cibuild.css create mode 100644 webinstall/cibuild.html create mode 100644 webinstall/cibuild.js create mode 100644 webinstall/helper.js diff --git a/webinstall/cibuild.css b/webinstall/cibuild.css new file mode 100644 index 0000000..b5164fc --- /dev/null +++ b/webinstall/cibuild.css @@ -0,0 +1,3 @@ +.hidden{ + display: none; +} \ No newline at end of file diff --git a/webinstall/cibuild.html b/webinstall/cibuild.html new file mode 100644 index 0000000..d1de53a --- /dev/null +++ b/webinstall/cibuild.html @@ -0,0 +1,38 @@ + + + + + + + + + +

Build your own ESP32-NMEA2000

+
+ + +
+
+ + +
+
+ +
+
+ +
---
+
+
+ +
---
+
+ + + + + \ No newline at end of file diff --git a/webinstall/cibuild.js b/webinstall/cibuild.js new file mode 100644 index 0000000..5627f32 --- /dev/null +++ b/webinstall/cibuild.js @@ -0,0 +1,98 @@ +import { setButtons,fillValues, setValue, buildUrl, fetchJson, setVisible, enableEl } from "./helper"; +(function(){ + const STATUS_INTERVAL=2000; + const CURRENT_PIPELINE='pipeline'; + let API="cibuild.php"; + let currentPipeline=undefined; + let downloadUrl=undefined; + let timer=undefined; + const fetchStatus=()=>{ + if (currentPipeline === undefined) return; + fetchJson(API,{api:'status',pipeline:currentPipeline}) + .then((st)=>{ + setValue('status',st.status); + let l=document.getElementById('link'); + if (l){ + if (st.status_url){ + l.setAttribute('href',st.status_url); + setVisible(l.parentElement,true); + } + else{ + setVisible(l.parentElement,false); + } + } + if (st.status === 'success'){ + enableEl('start',true); + fetchJson(API,{api:'artifacts',pipeline:currentPipeline}) + .then((ar)=>{ + if (! ar.items || ar.items.length < 1){ + throw new Error("no download link"); + } + downloadUrl=ar.items[0].url; + setVisible(document.getElementById('download'),true,true); + + }) + .catch((err)=>alert("Unable to get build result: "+err)); + return; + } + else{ + setVisible(document.getElementById('download'),false,true); + } + timer=window.setTimeout(fetchStatus,STATUS_INTERVAL) + }) + .catch((e)=>{ + timer=window.setTimeout(fetchStatus,STATUS_INTERVAL); + }) + } + const setCurrentPipeline=(pipeline)=>{ + currentPipeline=pipeline; + window.localStorage.setItem(CURRENT_PIPELINE,pipeline); + }; + const startBuild=()=>{ + let param={}; + currentPipeline=undefined; + if (timer) window.clearTimeout(timer); + timer=undefined; + fillValues(param,['environment','buildflags']); + setValue('status','requested'); + fetchJson(API,Object.assign({ + api:'start'},param)) + .then((json)=>{ + if (json.status === 'error'){ + throw new Error("unable to create job "+(json.error||'')); + } + if (!json.id) throw new Error("unable to create job, no id"); + setCurrentPipeline(json.id); + setValue('pipeline',currentPipeline); + setValue('status',json.status); + enableEl('start',false); + timer=window.setTimeout(fetchStatus,STATUS_INTERVAL); + }) + .catch((err)=>{ + setValue('status','error'); + enableEl('start',true); + alert(err); + }); + } + const runDownload=()=>{ + if (! downloadUrl) return; + let df=document.getElementById('dlframe'); + if (df){ + df.setAttribute('src',null); + df.setAttribute('src',downloadUrl); + } + } + const btConfig={ + start:startBuild, + download:runDownload + }; + window.onload=()=>{ + setButtons(btConfig); + currentPipeline=window.localStorage.getItem(CURRENT_PIPELINE); + if (currentPipeline){ + setValue('pipeline',currentPipeline); + enableEl('start',false); + fetchStatus(); + } + } +})(); \ No newline at end of file diff --git a/webinstall/helper.js b/webinstall/helper.js new file mode 100644 index 0000000..82c3085 --- /dev/null +++ b/webinstall/helper.js @@ -0,0 +1,96 @@ +const getParam = (key) => { + let value = RegExp("" + key + "[^&]+").exec(window.location.search); + // Return the unescaped value minus everything starting from the equals sign or an empty string + return decodeURIComponent(!!value ? value.toString().replace(/^[^=]+./, "") : ""); +}; +/** + * add an HTML element + * @param {*} type + * @param {*} clazz + * @param {*} parent + * @param {*} text + * @returns + */ +const addEl = (type, clazz, parent, text) => { + let el = document.createElement(type); + if (clazz) { + if (!(clazz instanceof Array)) { + clazz = clazz.split(/ */); + } + clazz.forEach(function (ce) { + el.classList.add(ce); + }); + } + if (text) el.textContent = text; + if (parent) parent.appendChild(el); + return el; +} +/** + * call a function for each matching element + * @param {*} selector + * @param {*} cb + */ +const forEachEl = (selector, cb) => { + let arr = document.querySelectorAll(selector); + for (let i = 0; i < arr.length; i++) { + cb(arr[i]); + } +} + +const setButtons=(config)=>{ + for (let k in config){ + let bt=document.getElementById(k); + if (bt){ + bt.addEventListener('click',config[k]); + } + } +} +const fillValues=(values,items)=>{ + items.forEach((it)=>{ + let e=document.getElementById(it); + if (e){ + values[it]=e.value; //TODO: type of el + } + }) +}; +const setValue=(id,value)=>{ + let el=document.getElementById(id); + if (! el) return; + if (el.tagName == 'DIV'){ + el.textContent=value; + return; + } + if (el.tagName == 'INPUT'){ + el.value=value; + } +} +const buildUrl=(url,pars)=>{ + let delim=(url.match("[?]"))?"&":"?"; + for (let k in pars){ + url+=delim; + delim="&"; + url+=encodeURIComponent(k); + url+="="; + url+=encodeURIComponent(pars[k]); + } + return url; +} +const fetchJson=(url,pars)=>{ + let furl=buildUrl(url,pars); + return fetch(furl).then((rs)=>rs.json()); +} +const setVisible=(el,vis,useParent)=>{ + if (! el) return; + if (useParent) el=el.parentElement; + if (! el) return; + if (vis) el.classList.remove('hidden'); + else el.classList.add('hidden'); +} +const enableEl=(id,en)=>{ + let el=document.getElementById(id); + if (!el) return; + if (en) el.disabled=false; + else el.disabled=true; +} + +export { getParam, addEl, forEachEl,setButtons,fillValues, setValue,buildUrl,fetchJson,setVisible, enableEl } \ No newline at end of file diff --git a/webinstall/install.html b/webinstall/install.html index e578a82..414d431 100644 --- a/webinstall/install.html +++ b/webinstall/install.html @@ -9,9 +9,9 @@ -
+ \ No newline at end of file diff --git a/webinstall/install.js b/webinstall/install.js index 0281ff4..ff7d958 100644 --- a/webinstall/install.js +++ b/webinstall/install.js @@ -1,10 +1,10 @@ import {XtermOutputHandler} from "./installUtil.js"; import ESPInstaller from "./installUtil.js"; +import { addEl, getParam } from "./helper.js"; (function(){ let espLoaderTerminal; let espInstaller; let releaseData={}; - const addEl=ESPInstaller.addEl; //shorter typing let showConsole; let hideConsole; const enableConsole=(enable,disableBoth)=>{ @@ -134,8 +134,8 @@ import ESPInstaller from "./installUtil.js"; showError("your browser does not support the ESP flashing (no serial)"); return; } - let user = window.gitHubUser||ESPInstaller.getParam('user'); - let repo = window.gitHubRepo || ESPInstaller.getParam('repo'); + let user = window.gitHubUser||getParam('user'); + let repo = window.gitHubRepo || getParam('repo'); if (!user || !repo) { alert("missing parameter user or repo"); } diff --git a/webinstall/installUtil.js b/webinstall/installUtil.js index 87f91c3..a40a691 100644 --- a/webinstall/installUtil.js +++ b/webinstall/installUtil.js @@ -72,39 +72,6 @@ class ESPInstaller{ // Return the unescaped value minus everything starting from the equals sign or an empty string return decodeURIComponent(!!value ? value.toString().replace(/^[^=]+./,"") : ""); }; - /** - * add an HTML element - * @param {*} type - * @param {*} clazz - * @param {*} parent - * @param {*} text - * @returns - */ - static addEl(type, clazz, parent, text) { - let el = document.createElement(type); - if (clazz) { - if (!(clazz instanceof Array)) { - clazz = clazz.split(/ */); - } - clazz.forEach(function (ce) { - el.classList.add(ce); - }); - } - if (text) el.textContent = text; - if (parent) parent.appendChild(el); - return el; - } - /** - * call a function for each matching element - * @param {*} selector - * @param {*} cb - */ - static forEachEl(selector,cb){ - let arr=document.querySelectorAll(selector); - for (let i=0;i