From 7a5da47e17f32d3c222ac3bd7cac4bbb2d321b32 Mon Sep 17 00:00:00 2001 From: andreas Date: Sun, 1 Oct 2023 20:48:45 +0200 Subject: [PATCH] intermediate: find pipelines in DB and use existing --- webinstall/cibuild.html | 2 +- webinstall/cibuild.js | 77 ++++++++++++++++++++++++---- webinstall/cibuild.php | 110 +++++++++++++++++++++++++++++++++++++++- webinstall/helper.js | 4 ++ 4 files changed, 180 insertions(+), 13 deletions(-) diff --git a/webinstall/cibuild.html b/webinstall/cibuild.html index 7ec4565..deea2fb 100644 --- a/webinstall/cibuild.html +++ b/webinstall/cibuild.html @@ -28,7 +28,7 @@
-

Last Build

+

Last Build

Job Id
---
diff --git a/webinstall/cibuild.js b/webinstall/cibuild.js index 067e294..0a034e9 100644 --- a/webinstall/cibuild.js +++ b/webinstall/cibuild.js @@ -12,7 +12,25 @@ import fileDownload from "https://cdn.skypack.dev/js-file-download@0.4.12" let config={}; //values as read and stored let configStruct={}; //complete struct merged of config and struct let branch=getParam('branch'); + let displayMode='last'; + let delayedSearch=undefined; + let running=false; if (! branch) branch='master'; + const modeStrings={ + last: 'Last Build', + existing: 'Existing Build', + current: 'Current Build' + }; + const setDisplayMode=(mode)=>{ + let old=displayMode; + let ms=modeStrings[mode]; + if (ms === undefined){ + return false; + } + displayMode=mode; + setValue('resultTitle',ms); + return mode !== old; + } const showError=(text)=>{ if (text === undefined){ setVisible('buildError',false,true); @@ -30,19 +48,31 @@ import fileDownload from "https://cdn.skypack.dev/js-file-download@0.4.12" setVisible('download', false, true); setVisible('status_url', false, true); } - const setRunning=(active)=>{ + const setRunning=(active,opt_noActivate)=>{ + running=active; if (active){ showError(); downloadUrl=undefined; setVisible('download', false, true); setVisible('status_url', false, true); } - enableEl('start',!active); + if (active || ! opt_noActivate) enableEl('start',!active); + } + const isRunning=()=>{ + return running; } const fetchStatus=(initial)=>{ - if (currentPipeline === undefined) return; + if (currentPipeline === undefined) { + setVisible('status_url',false,true); + setVisible('error',false); + setVisible('download',false,true); + setValue('status','---'); + return; + }; + let queryPipeline=currentPipeline; fetchJson(API,{api:'status',pipeline:currentPipeline}) .then((st)=>{ + if (queryPipeline !== currentPipeline) return; setValues(st); setVisible('status_url',st.status_url !== undefined,true); setVisible('error',st.error !== undefined,true); @@ -52,7 +82,7 @@ import fileDownload from "https://cdn.skypack.dev/js-file-download@0.4.12" return; } if (st.status === 'success'){ - setRunning(false); + setRunning(false, displayMode == 'existing'); fetchJson(API,{api:'artifacts',pipeline:currentPipeline}) .then((ar)=>{ if (! ar.items || ar.items.length < 1){ @@ -79,9 +109,10 @@ import fileDownload from "https://cdn.skypack.dev/js-file-download@0.4.12" timer=window.setTimeout(fetchStatus,STATUS_INTERVAL); }) } - const setCurrentPipeline=(pipeline)=>{ + const setCurrentPipeline=(pipeline,doStore)=>{ currentPipeline=pipeline; - window.localStorage.setItem(CURRENT_PIPELINE,pipeline); + setValue('pipeline',currentPipeline); + if (doStore) window.localStorage.setItem(CURRENT_PIPELINE,pipeline); }; const startBuild=()=>{ let param={'branch':branch}; @@ -92,6 +123,7 @@ import fileDownload from "https://cdn.skypack.dev/js-file-download@0.4.12" setValue('status','requested'); setValue('pipeline',''); setRunning(true); + param.config=JSON.stringify(config); fetchJson(API,Object.assign({ api:'start'},param)) .then((json)=>{ @@ -99,9 +131,9 @@ import fileDownload from "https://cdn.skypack.dev/js-file-download@0.4.12" 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); + setCurrentPipeline(json.id,true); setValue('status',json.status); + setDisplayMode('current'); timer=window.setTimeout(fetchStatus,STATUS_INTERVAL); }) .catch((err)=>{ @@ -279,14 +311,37 @@ import fileDownload from "https://cdn.skypack.dev/js-file-download@0.4.12" } document.getElementById('environment').value=environment; document.getElementById('buildflags').value=flags; + findPipeline(); + } + const findPipeline=()=>{ + if (delayedSearch !== undefined){ + window.clearTimeout(delayedSearch); + delayedSearch=undefined; + } + if (isRunning()) { + delayedSearch=window.setTimeout(findPipeline,500); + return; + } + let param={find:1}; + fillValues(param,['environment','buildflags']); + fetchJson(API,param) + .then((res)=>{ + setCurrentPipeline(res.pipeline); + fetchStatus(true); + setDisplayMode('existing'); + enableEl('start',res.pipeline === undefined); + }) + .catch((e)=>console.log("findPipeline error ",e)); + } window.onload=async ()=>{ setButtons(btConfig); forEachEl('#environment',(el)=>el.addEventListener('change',hideResults)); forEachEl('#buildflags',(el)=>el.addEventListener('change',hideResults)); - currentPipeline=window.localStorage.getItem(CURRENT_PIPELINE); - if (currentPipeline){ - setValue('pipeline',currentPipeline); + let pipeline=window.localStorage.getItem(CURRENT_PIPELINE); + setDisplayMode('last'); + if (pipeline){ + setCurrentPipeline(pipeline); fetchStatus(true); setRunning(true); } diff --git a/webinstall/cibuild.php b/webinstall/cibuild.php index 20be940..414a400 100644 --- a/webinstall/cibuild.php +++ b/webinstall/cibuild.php @@ -2,15 +2,18 @@ include("token.php"); include("functions.php"); include("config.php"); +mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); +include("cibuild_connection.php"); if (! isset($CI_TOKEN)) die("no token"); const apiBase="https://circleci.com/api/v2/"; const webApp="https://app.circleci.com/"; const apiRepo="project/gh/#user#/#repo#"; const workflowName="build-workflow"; const jobName="pio-build"; -const defaultBranch='circleci-project-setup'; +const defaultBranch='master'; const defaultUser='wellenvogel'; const defaultRepo='esp32-nmea2000'; +const TABLENAME="CIBUILDS"; function getTokenHeaders(){ global $CI_TOKEN; @@ -68,6 +71,7 @@ function getJobStatus($pipeline,$wf=workflowName,$job=jobName){ } $pipeline_id=$pstat['id']; $pipeline_number=$pstat['number']; + $vcs=$pstat['vcs']; $pstat=getWorkflow($pipeline,$wf); $workflow_id=$pstat['id']; $workflow_number=$pstat['workflow_number']; @@ -81,6 +85,7 @@ function getJobStatus($pipeline,$wf=workflowName,$job=jobName){ preg_replace('/^gh/','github',$pstat['project_slug'])."/". $pipeline_number."/workflows/".$workflow_id."/jobs/".$pstat['job_number']; } + $pstat['vcs']=$vcs; return $pstat; } @@ -89,6 +94,79 @@ function getArtifacts($job,$slug){ return getJson($url,getTokenHeaders(),true); } +function insertPipeline($id,$param){ + global $database; + if (! isset($database)) return false; + try { + $status='created'; + $stmt = $database->prepare("INSERT into " . TABLENAME . + "(id,status,config,environment,buildflags) VALUES (?,?,?,?,?)"); + $stmt->bind_param("sssss", + $id, + $status, + $param['config'], + $param['environment'], + $param['build_flags']); + $stmt->execute(); + return true; + } catch (Exception $e) { + error_log("insert pipeline $id failed: $e"); + return false; + } +} +function updatePipeline($id,$status,$tag=null){ + global $database; + if (! isset($database)) return false; + try{ + $stmt=null; + if ($tag != null){ + $stmt=$database->prepare("UPDATE ".TABLENAME." SET status=?,tag=? where id=? and ( status <> ? or tag <> ?)"); + $stmt->bind_param("sssss",$status,$tag,$id,$status,$tag); + $stmt->execute(); + } + else{ + $stmt=$database->prepare("UPDATE ".TABLENAME." SET status=? where id=? AND status <> ?"); + $stmt->bind_param("sss",$status,$id,$status); + $stmt->execute(); + } + + }catch (Exception $e){ + error_log("update pipeline $id failed: $e"); + return false; + } + return true; +} + +function findPipeline($param) +{ + global $database; + if (!isset($database)) + return false; + try { + $stmt = null; + if (isset($param['tag'])) { + $stmt = $database->prepare("SELECT * from " . TABLENAME . + " where status='success' and environment=? and buildflags=? and tag=? order by timestamp desc"); + $stmt->bind_param("sss", $param['environment'], $param['buildflags'], $param['tag']); + } else { + $stmt = $database->prepare("SELECT id from " . TABLENAME . + " where status='success' and environment=? and buildflags=? order by timestamp desc"); + $stmt->bind_param("ss", $param['environment'], $param['buildflags']); + } + $stmt->execute(); + $id=null; + $stmt->bind_result($id); + if ($stmt->fetch()){ + return $id; + } + return false; + } catch (Exception $e) { + error_log("find pipeline failed: $e"); + return false; + } + +} + function getArtifactsForPipeline($pipeline,$wf=workflowName,$job=jobName){ $jstat=getJobStatus($pipeline,$wf,$job); if (! isset($jstat['job_number'])){ @@ -116,6 +194,12 @@ try { ); try { $pstat = getJobStatus($par['pipeline'], $par['workflow'], $par['job']); + if (isset($pstat['vcs'])){ + updatePipeline($par['pipeline'],$pstat['status'],$pstat['vcs']['revision']); + } + else{ + updatePipeline($par['pipeline'],$pstat['status']); + } echo (json_encode($pstat)); } catch (Exception $e) { $rt = array('status' => 'error', 'error' => $e->getMessage()); @@ -148,6 +232,16 @@ try { echo(json_encode($rt)); exit(0); } + if ($action == 'pipelineuuid'){ + addVars( + $par, + ['pipeline'] + ); + $url=apiBase."/pipeline/".$par['pipeline']; + $rt=getJson($url,getTokenHeaders(),true); + echo(json_encode($rt)); + exit(0); + } if ($action == 'start'){ addVars( $par, @@ -173,6 +267,7 @@ try { $userRepo=fillUserAndRepo(null,$par); $url=apiBase."/".replaceVars(apiRepo,$userRepo)."/pipeline"; $rt=getJson($url,getTokenHeaders(),true,$requestParam); + insertPipeline($rt['id'],$requestParam['parameters']); echo (json_encode($rt)); exit(0); } @@ -196,6 +291,19 @@ try { proxy($dlurl); exit(0); } + if (isset($_REQUEST['find'])){ + $par=array(); + addVars($par,['environment','buildflags']); + if (isset($_REQUEST['tag'])) $par['tag']=$_REQUEST['tag']; + $id=findPipeline($par); + header("Content-Type: application/json"); + $rt=array('status'=>'OK'); + if ($id){ + $rt['pipeline']=$id; + } + echo(json_encode($rt)); + exit(0); + } die("no action"); } catch (HTTPErrorException $h) { header($_SERVER['SERVER_PROTOCOL'] . " " . $h->code . " " . $h->getMessage()); diff --git a/webinstall/helper.js b/webinstall/helper.js index fb37aca..857427c 100644 --- a/webinstall/helper.js +++ b/webinstall/helper.js @@ -65,6 +65,10 @@ const setValue=(id,value)=>{ el.value=value; return; } + if (el.tagName.match(/^H[0-9]/)){ + el.textContent=value; + return; + } if (el.tagName == 'A'){ el.setAttribute('href',value); return;