remove
This commit is contained in:
@@ -1 +1,3 @@
|
||||
<?php
|
||||
$config->job->create->requiredFields = 'name,repo,buildType,jenkins,jenkinsTask,triggerType';
|
||||
$config->job->edit->requiredFields = 'name,repo,buildType,jenkins,jenkinsTask,triggerType';
|
||||
|
||||
@@ -35,4 +35,194 @@ class ci extends control
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Browse ci task.
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function browseJob($orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$this->view->taskList = $this->citask->listAll($orderBy, $pager);
|
||||
|
||||
$this->view->title = $this->lang->ci->task . $this->lang->colon . $this->lang->citask->browse;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = $this->lang->ci->task;
|
||||
$this->view->position[] = $this->lang->ci->browse;
|
||||
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->module = 'citask';
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ci task.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function createJob()
|
||||
{
|
||||
if($_POST)
|
||||
{
|
||||
$this->citask->create();
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
|
||||
}
|
||||
|
||||
$this->app->loadLang('action');
|
||||
|
||||
$this->view->title = $this->lang->ci->task . $this->lang->colon . $this->lang->ci->create;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = html::a(inlink('browse'), $this->lang->ci->common);
|
||||
$this->view->position[] = $this->lang->ci->create;
|
||||
|
||||
$this->view->repoList = $this->loadModel('cirepo')->listForSelection("true");
|
||||
$this->view->jenkinsList = $this->loadModel('cijenkins')->listForSelection("true");
|
||||
$this->view->module = 'citask';
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a ci task.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function editJob($id)
|
||||
{
|
||||
$citask = $this->citask->getByID($id);
|
||||
if($_POST)
|
||||
{
|
||||
$this->citask->update($id);
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
|
||||
}
|
||||
|
||||
$this->app->loadLang('action');
|
||||
|
||||
$this->view->citask = $citask;
|
||||
|
||||
$this->view->repoList = $this->loadModel('cirepo')->listForSelection("true");
|
||||
$this->view->jenkinsList = $this->loadModel('cijenkins')->listForSelection("true");
|
||||
$this->view->module = 'citask';
|
||||
|
||||
$this->view->title = $this->lang->ci->task . $this->lang->colon . $this->lang->ci->edit;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = html::a(inlink('browse'), $this->lang->ci->task);
|
||||
$this->view->position[] = $this->lang->ci->edit;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a ci task.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function deleteJob($id)
|
||||
{
|
||||
$this->citask->delete(TABLE_CI_TASK, $id);
|
||||
|
||||
$command = 'moduleName=citask&methodName=exe&parm=' . $id;
|
||||
$this->dao->delete()->from(TABLE_CRON)->where('command')->eq($command)->exec();
|
||||
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
|
||||
$this->send(array('result' => 'success'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Exec a ci task.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function exeJob($id)
|
||||
{
|
||||
error_log("===exeCitask " . $id);
|
||||
|
||||
$this->citask->exe($id);
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
|
||||
$this->send(array('result' => 'success'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Browse jenkins build.
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function browseBuild($taskID = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$this->view->buildList = $this->citask->listBuild($taskID, $orderBy, $pager);
|
||||
|
||||
$this->view->title = $this->lang->ci->task . $this->lang->colon . $this->lang->citask->browseBuild;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = html::a(inlink('browse'), $this->lang->ci->task);
|
||||
$this->view->position[] = $this->lang->citask->browseBuild;
|
||||
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->module = 'citask';
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* View jenkins build logs.
|
||||
*
|
||||
* @param int $buildID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function viewBuildLogs($buildID)
|
||||
{
|
||||
$build = $this->citask->getBuild($buildID);
|
||||
$this->view->logs = str_replace("\r\n","<br />", $build->logs);
|
||||
|
||||
$this->view->title = $this->lang->ci->task . $this->lang->colon . $this->lang->citask->viewLogs;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = html::a(inlink('browse'), $this->lang->ci->task);
|
||||
$this->view->position[] = html::a(inlink('browseBuild', "taskID=" . $build->citask), $this->lang->citask->browseBuild);
|
||||
$this->view->position[] = $this->lang->citask->viewLogs;
|
||||
|
||||
$this->view->module = 'citask';
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a request to jenkins to check build status.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function checkBuildStatus()
|
||||
{
|
||||
$this->citask->checkBuildStatus();
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
|
||||
$this->send(array('result' => 'success'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@ $lang->ci->common = '持续集成';
|
||||
$lang->ci->credentials = '凭证';
|
||||
$lang->ci->jenkins = 'Jenkins';
|
||||
$lang->ci->repo = '代码库';
|
||||
$lang->ci->task = '任务';
|
||||
$lang->ci->job = '构建';
|
||||
$lang->ci->browse = '浏览';
|
||||
$lang->ci->create = '新建';
|
||||
$lang->ci->edit = '编辑';
|
||||
@@ -18,3 +18,48 @@ $lang->ci->subModules['cicredentials'] = '凭证';
|
||||
$lang->ci->subModules['cijenkins'] = 'Jenkins';
|
||||
$lang->ci->subModules['cirepo'] = '代码库';
|
||||
$lang->ci->subModules['citask'] = '任务';
|
||||
|
||||
$lang->job->browseBuild = '构建历史';
|
||||
$lang->job->viewLogs = '构建日志';
|
||||
|
||||
$lang->job->exeNow = '立即执行';
|
||||
$lang->job->delete = '删除构建任务';
|
||||
$lang->job->confirmDelete = '确认删除该构建任务吗?';
|
||||
|
||||
$lang->job->buildStatus = '构建状态';
|
||||
$lang->job->buildTime = '构建时间';
|
||||
|
||||
$lang->job->id = 'ID';
|
||||
$lang->job->name = '名称';
|
||||
$lang->job->repo = '代码库';
|
||||
$lang->job->jenkins = 'Jenkins服务';
|
||||
$lang->job->jenkinsTask = 'Jenkins任务名';
|
||||
$lang->job->buildType = '构建类型';
|
||||
$lang->job->triggerType = '触发方式';
|
||||
$lang->job->scheduleType = '时间计划';
|
||||
$lang->job->cornExpression = 'Corn表达式';
|
||||
$lang->job->custom = '自定义';
|
||||
|
||||
$lang->job->tagKeywords = '标签关键字';
|
||||
$lang->job->commentKeywords = '注释关键字';
|
||||
$lang->job->extTask = '执行任务';
|
||||
|
||||
$lang->job->at = '在';
|
||||
$lang->job->time = '时间';
|
||||
$lang->job->exe = '执行';
|
||||
$lang->job->scheduleInterval = '每隔';
|
||||
$lang->job->scheduleDay = '天数';
|
||||
$lang->job->day = '天';
|
||||
$lang->job->lastExe = '最后执行';
|
||||
$lang->job->scheduleTime = '时间';
|
||||
|
||||
$lang->job->example = '举例';
|
||||
$lang->job->tagEx = 'build_#15,其中15为Jenkins任务编号';
|
||||
$lang->job->commitEx = 'start build #15,其中15为Jenkins任务编号';
|
||||
$lang->job->cronSample = '如 0 0 2 * * 2-6/1 表示每个工作日凌晨2点';
|
||||
|
||||
$lang->job->buildStatus = array('success' => '成功', 'fail' => '失败', 'created' => '新建', 'building' => '构建中');
|
||||
$lang->job->dayTypeList = array('workDay' => '工作日', 'everyDay' => '每天');
|
||||
$lang->job->buildTypeList = array('build' => '仅构建', 'buildAndDeploy' => '构建部署', 'buildAndTest' => '构建测试');
|
||||
$lang->job->triggerTypeList = array('tag' => '打标签', 'commit' => '代码提交注释', 'schedule' => '定时计划');
|
||||
$lang->job->scheduleTypeList = array('cron' => 'Cron表达式', 'custom' => '自定义');
|
||||
|
||||
@@ -13,4 +13,374 @@
|
||||
class ciModel extends model
|
||||
{
|
||||
|
||||
/**
|
||||
* Get ci task list.
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @param bool $decode
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function listJob($orderBy = 'id_desc', $pager = null, $decode = true)
|
||||
{
|
||||
$list = $this->dao->
|
||||
select('t1.*, t2.name repoName, t3.name as jenkinsName')->from(TABLE_CI_TASK)->alias('t1')
|
||||
->leftJoin(TABLE_REPO)->alias('t2')->on('t1.repo=t2.id')
|
||||
->leftJoin(TABLE_JENKINS)->alias('t3')->on('t1.jenkins=t3.id')
|
||||
->where('t1.deleted')->eq('0')
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a ci task by id.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getJobByID($id)
|
||||
{
|
||||
$jenkins = $this->dao->select('*')->from(TABLE_CI_TASK)->where('id')->eq($id)->fetch();
|
||||
return $jenkins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ci task.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function createJob()
|
||||
{
|
||||
$task = fixer::input('post')
|
||||
->add('createdBy', $this->app->user->account)
|
||||
->add('createdDate', helper::now())
|
||||
->get();
|
||||
|
||||
$this->dao->insert(TABLE_CI_TASK)->data($task)
|
||||
->batchCheck($this->config->citask->requiredFields, 'notempty')
|
||||
|
||||
->batchCheckIF($task->triggerType === 'schedule' && $task->scheduleType == 'cron', "cronExpression", 'notempty')
|
||||
->batchCheckIF($task->triggerType === 'schedule' && $task->scheduleType == 'custom', "scheduleDay,scheduleTime,scheduleInterval", 'notempty')
|
||||
|
||||
->autoCheck()
|
||||
->exec();
|
||||
|
||||
if ($task->triggerType === 'schedule') {
|
||||
$taskId = $this->dao->lastInsertID();
|
||||
|
||||
if ($task->scheduleType == 'custom') {
|
||||
$arr = explode(":", $task->scheduleTime);
|
||||
$hour = $arr[0];
|
||||
$min = $arr[1];
|
||||
|
||||
if ($task->scheduleDay == 'everyDay') {
|
||||
$days = '1-7';
|
||||
} else if ($task->scheduleDay == 'workDay') {
|
||||
$days = '1-5';
|
||||
}
|
||||
|
||||
$cron = (object)array('m' => $min, 'h' => $hour, 'dom' => '*', 'mon' => '*',
|
||||
'dow' => $days . '/' . $task->scheduleInterval, 'command' => 'moduleName=citask&methodName=exe&parm=' . $taskId,
|
||||
'remark' => ($this->lang->citask->extTask . $taskId), 'type' => 'zentao',
|
||||
'buildin' => '-1', 'status' => 'normal', 'lastTime' => '0000-00-00 00:00:00');
|
||||
$this->dao->insert(TABLE_CRON)->data($cron)->exec();
|
||||
} else if ($task->scheduleType == 'cron') {
|
||||
$arr = explode(' ', $task->cronExpression);
|
||||
if (count($arr) >= 6) {
|
||||
$cron = (object)array('m' => $arr[1], 'h' => $arr[2], 'dom' => $arr[3], 'mon' => $arr[4],
|
||||
'dow' => $arr[5], 'command' => 'moduleName=citask&methodName=exe&parm=' . $taskId,
|
||||
'remark' => ($this->lang->citask->extTask . $taskId), 'type' => 'zentao',
|
||||
'buildin' => '-1', 'status' => 'normal', 'lastTime' => '0000-00-00 00:00:00');
|
||||
$this->dao->insert(TABLE_CRON)->data($cron)->exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a ci task.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function updateJob($id)
|
||||
{
|
||||
$task = fixer::input('post')
|
||||
->add('editedBy', $this->app->user->account)
|
||||
->add('editedDate', helper::now())
|
||||
->get();
|
||||
|
||||
$this->dao->update(TABLE_CI_TASK)->data($task)
|
||||
->batchCheck($this->config->citask->requiredFields, 'notempty')
|
||||
|
||||
->batchCheckIF($task->triggerType === 'schedule' && $task->scheduleType == 'cron', "cronExpression", 'notempty')
|
||||
->batchCheckIF($task->triggerType === 'schedule' && $task->scheduleType == 'custom', "scheduleDay,scheduleTime,scheduleInterval", 'notempty')
|
||||
|
||||
->autoCheck()
|
||||
->where('id')->eq($id)
|
||||
->exec();
|
||||
|
||||
if ($task->triggerType === 'schedule') {
|
||||
$command = 'moduleName=citask&methodName=exe&parm=' . $id;
|
||||
|
||||
if ($task->scheduleType == 'custom') {
|
||||
$arr = explode(":", $task->scheduleTime);
|
||||
$hour = $arr[0];
|
||||
$min = $arr[1];
|
||||
|
||||
$taskId = $this->dao->lastInsertID();
|
||||
if ($task->scheduleDay == 'everyDay') {
|
||||
$days = '1-7';
|
||||
} else if ($task->scheduleDay == 'workDay') {
|
||||
$days = '2-6';
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_CRON)
|
||||
->set('m')->eq($min)
|
||||
->set('h')->eq($hour)
|
||||
->set('dom')->eq('*')
|
||||
->set('mon')->eq('*')
|
||||
->set('dow')->eq($days . '/' . $task->scheduleInterval)
|
||||
->set('lastTime')->eq('0000-00-00 00:00:00')
|
||||
->where('command')->eq($command)->exec();
|
||||
} else if ($task->scheduleType == 'cron') {
|
||||
$arr = explode(' ', $task->cronExpression);
|
||||
if (count($arr) >= 6) {
|
||||
$this->dao->update(TABLE_CRON)
|
||||
->set('m')->eq($arr[1])
|
||||
->set('h')->eq($arr[2])
|
||||
->set('dom')->eq($arr[3])
|
||||
->set('mon')->eq($arr[4])
|
||||
->set('dow')->eq($arr[5])
|
||||
->set('lastTime')->eq('0000-00-00 00:00:00')
|
||||
->where('command')->eq($command)->exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute ci task.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function exeJob($taskID)
|
||||
{
|
||||
$po = $this->dao->select('task.id taskId, task.name taskName, task.repo, task.jenkinsTask, jenkins.name jenkinsName,jenkins.serviceUrl,jenkins.credentials')
|
||||
->from(TABLE_CI_TASK)->alias('task')
|
||||
->leftJoin(TABLE_JENKINS)->alias('jenkins')->on('task.jenkins=jenkins.id')
|
||||
->where('task.id')->eq($taskID)
|
||||
->fetch();
|
||||
|
||||
$credentials = $this->loadModel('cicredentials')->getByID($po->credentials); // jenkins must use a token or account credentials
|
||||
if ($credentials->type === 'token') {
|
||||
$jenkinsTokenOrPassword = $credentials->token;
|
||||
} else if ($credentials->type === 'account') {
|
||||
$jenkinsTokenOrPassword = $credentials->password;
|
||||
}
|
||||
$jenkinsUser = $credentials->username;
|
||||
$jenkinsServer = $po->serviceUrl;
|
||||
|
||||
$r = '://' . $jenkinsUser . ':' . $jenkinsTokenOrPassword . '@';
|
||||
$jenkinsServer = str_replace('://', $r, $jenkinsServer);
|
||||
$buildUrl = sprintf('%s/job/%s/build/api/json', $jenkinsServer, $po->jenkinsTask);
|
||||
|
||||
$po->queueItem = $this->sendBuildRequest($buildUrl);
|
||||
$this->saveCibuild($po);
|
||||
|
||||
return !dao::isError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get jenkins build list.
|
||||
*
|
||||
* @param int $taskID
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @param bool $decode
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function listBuild($taskID, $orderBy = 'id_desc', $pager = null, $decode = true)
|
||||
{
|
||||
$list = $this->dao->
|
||||
select('id, name, status, createdDate')->from(TABLE_CI_BUILD)
|
||||
->where('deleted')->eq('0')
|
||||
->andWhere('citask')->eq($taskID)
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get jenkins build logs.
|
||||
*
|
||||
* @param int $buildID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getBuildByID($buildID)
|
||||
{
|
||||
$build = $this->dao->select('*')->from(TABLE_CI_BUILD)->where('id')->eq($buildID)->fetch();
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save build to db.
|
||||
*
|
||||
* @param object $task
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function saveBuild($task)
|
||||
{
|
||||
$build = new stdClass();
|
||||
$build->citask = $task->taskId;
|
||||
$build->name = $task->taskName;
|
||||
$build->queueItem = $task->queueItem;
|
||||
$build->status = 'created';
|
||||
$build->createdBy = $this->app->user->account;
|
||||
$build->createdDate = helper::now();
|
||||
|
||||
$this->dao->insert(TABLE_CI_BUILD)->data($build)->exec();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update ci build status.
|
||||
*
|
||||
* @param object $task
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function updateBuildStatus($build, $status)
|
||||
{
|
||||
$this->dao->update(TABLE_CI_BUILD)->set('status')->eq($status)->where('id')->eq($build->id)->exec();
|
||||
|
||||
$this->dao->update(TABLE_CI_TASK)
|
||||
->set('lastExec')->eq(helper::now())
|
||||
->set('lastStatus')->eq($status)
|
||||
->where('id')->eq($build->citask)->exec();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a request to jenkins to check build status.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function checkBuildStatus()
|
||||
{
|
||||
$pos = $this->dao->select('build.*, task.jenkinsTask, jenkins.name jenkinsName,jenkins.serviceUrl,jenkins.credentials')
|
||||
->from(TABLE_CI_BUILD)->alias('build')
|
||||
->leftJoin(TABLE_CI_TASK)->alias('task')->on('build.citask=task.id')
|
||||
->leftJoin(TABLE_JENKINS)->alias('jenkins')->on('task.jenkins=jenkins.id')
|
||||
->where('build.status')->ne('success')
|
||||
->andWhere('build.status')->ne('fail')
|
||||
->fetchAll();
|
||||
|
||||
foreach($pos as $po) {
|
||||
$credentials = $this->loadModel('cicredentials')->getByID($po->credentials); // jenkins must use a token or account credentials
|
||||
if ($credentials->type === 'token') {
|
||||
$jenkinsTokenOrPassword = $credentials->token;
|
||||
} else if ($credentials->type === 'account') {
|
||||
$jenkinsTokenOrPassword = $credentials->password;
|
||||
}
|
||||
$jenkinsUser = $credentials->username;
|
||||
$jenkinsServer = $po->serviceUrl;
|
||||
|
||||
$r = '://' . $jenkinsUser . ':' . $jenkinsTokenOrPassword . '@';
|
||||
$jenkinsServer = str_replace('://', $r, $jenkinsServer);
|
||||
$queueUrl = sprintf('%s/queue/item/%s/api/json', $jenkinsServer, $po->queueItem);
|
||||
|
||||
$response = common::http($queueUrl);
|
||||
if (strripos($response,"404") > -1) { // queue已过期
|
||||
$infoUrl = sprintf('%s/job/%s/%s/api/json', $jenkinsServer, $po->jenkinsTask, $po->queueItem);
|
||||
$response = common::http($infoUrl);
|
||||
$buildInfo = json_decode($response);
|
||||
$result = strtolower($buildInfo->result);
|
||||
$this->updateCibuildStatus($po, $result);
|
||||
|
||||
$logUrl = sprintf('%s/job/%s/%s/consoleText', $jenkinsServer, $po->jenkinsTask, $po->queueItem);
|
||||
$response = common::http($logUrl);
|
||||
$logs = json_decode($response);
|
||||
|
||||
$this->dao->update(TABLE_CI_BUILD)->set('logs')->eq($response)->where('id')->eq($po->id)->exec();
|
||||
} else {
|
||||
$queueInfo = json_decode($response);
|
||||
|
||||
if (!empty($queueInfo->executable)) {
|
||||
$buildUrl = $queueInfo->executable->url . 'api/json?pretty=true';
|
||||
$buildUrl = str_replace('://', $r, $buildUrl);
|
||||
|
||||
$response = common::http($buildUrl);
|
||||
$buildInfo = json_decode($response);
|
||||
|
||||
if ($buildInfo->building) {
|
||||
$this->updateCibuildStatus($po, 'building');
|
||||
} else {
|
||||
$result = strtolower($buildInfo->result);
|
||||
$this->updateCibuildStatus($po, $result);
|
||||
|
||||
$logUrl = $buildInfo->url . 'logText/progressiveText/api/json';
|
||||
$logUrl = str_replace('://', $r, $logUrl);
|
||||
|
||||
$response = common::http($logUrl);
|
||||
$logs = json_decode($response);
|
||||
|
||||
$this->dao->update(TABLE_CI_BUILD)->set('logs')->eq($response)->where('id')->eq($po->id)->exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function sendBuildRequest($url)
|
||||
{
|
||||
if(!extension_loaded('curl')) return json_encode(array('result' => 'fail', 'message' => $lang->error->noCurlExt));
|
||||
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
|
||||
curl_setopt($curl, CURLOPT_USERAGENT, 'Sae T OAuth2 v0.1');
|
||||
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
|
||||
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
|
||||
curl_setopt($curl, CURLOPT_ENCODING, "");
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
|
||||
curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||||
curl_setopt($curl, CURLOPT_HEADER, FALSE);
|
||||
|
||||
$headers[] = "API-RemoteIP: " . $_SERVER['REMOTE_ADDR'];
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
|
||||
//
|
||||
curl_setopt ($curl , CURLOPT_HEADER, 1 );
|
||||
|
||||
curl_setopt($curl, CURLOPT_POST, true);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, new stdClass());
|
||||
|
||||
$response = curl_exec($curl);
|
||||
$errors = curl_error($curl);
|
||||
curl_close($curl);
|
||||
|
||||
if ( preg_match ( "!Location: .*item/(.*)/!", $response , $matches ) ) {
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<?php
|
||||
$config->credentials->create->requiredFields = 'name,serviceUrl';
|
||||
$config->credentials->edit->requiredFields = 'name,serviceUrl';
|
||||
@@ -1,122 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The control file of cicredentials module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chenqi <chenqi@cnezsoft.com>
|
||||
* @package product
|
||||
* @version $Id: ${FILE_NAME} 5144 2020/1/8 8:10 下午 chenqi@cnezsoft.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
class cicredentials extends control
|
||||
{
|
||||
/**
|
||||
* ci constructor.
|
||||
* @param string $moduleName
|
||||
* @param string $methodName
|
||||
*/
|
||||
public function __construct($moduleName = '', $methodName = '')
|
||||
{
|
||||
parent::__construct($moduleName, $methodName);
|
||||
$this->app->loadLang('ci');
|
||||
}
|
||||
|
||||
/**
|
||||
* Browse credentials
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
*/
|
||||
public function browse($orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$this->view->credentialsList = $this->cicredentials->listAll($orderBy, $pager);
|
||||
|
||||
$this->view->title = $this->lang->credentials . $this->lang->colon . $this->lang->browse;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = $this->lang->ci->credentials;
|
||||
$this->view->position[] = $this->lang->ci->browse;
|
||||
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->module = 'cicredentials';
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a credentials.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
if($_POST)
|
||||
{
|
||||
$this->cicredentials->create();
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
|
||||
}
|
||||
|
||||
$this->app->loadLang('action');
|
||||
|
||||
$this->view->title = $this->lang->ci->credentials . $this->lang->colon . $this->lang->ci->create;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = html::a(inlink('browse'), $this->lang->ci->credentials);
|
||||
$this->view->position[] = $this->lang->ci->create;
|
||||
|
||||
$this->view->module = 'cicredentials';
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a credentials.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
$credentials = $this->cicredentials->getByID($id);
|
||||
if($_POST)
|
||||
{
|
||||
$this->cicredentials->update($id);
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
|
||||
}
|
||||
|
||||
$this->app->loadLang('action');
|
||||
|
||||
$this->view->title = $this->lang->ci->credentials . $this->lang->colon . $this->lang->ci->edit;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = html::a(inlink('browse'), $this->lang->ci->credentials);
|
||||
$this->view->position[] = $this->lang->ci->edit;
|
||||
|
||||
$this->view->credentials = $credentials;
|
||||
|
||||
$this->view->module = 'cicredentials';
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a credentials.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
$this->cicredentials->delete(TABLE_CREDENTIALS, $id);
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
|
||||
$this->send(array('result' => 'success'));
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
$(function()
|
||||
{
|
||||
$('#' + module + 'Tab').addClass('btn-active-text');
|
||||
|
||||
showByType(type);
|
||||
$('#type').on('change', function()
|
||||
{
|
||||
showByType($(this).val());
|
||||
});
|
||||
});
|
||||
|
||||
function showByType(type) {
|
||||
if(type == 'account')
|
||||
{
|
||||
$('#password-field').show();
|
||||
|
||||
$('#privateKey-field').hide();
|
||||
$('#passphrase-field').hide();
|
||||
$('#token-field').hide();
|
||||
}
|
||||
else if (type == 'token')
|
||||
{
|
||||
$('#token-field').show();
|
||||
|
||||
$('#privateKey-field').hide();
|
||||
$('#passphrase-field').hide();
|
||||
$('#password-field').hide();
|
||||
}
|
||||
else // sshKey
|
||||
{
|
||||
$('#privateKey-field').show();
|
||||
$('#passphrase-field').show();
|
||||
|
||||
$('#password-field').hide();
|
||||
$('#token-field').hide();
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
$(function()
|
||||
{
|
||||
$('#' + module + 'Tab').addClass('btn-active-text');
|
||||
|
||||
showByType(type);
|
||||
$('#type').on('change', function()
|
||||
{
|
||||
showByType($(this).val());
|
||||
});
|
||||
})
|
||||
|
||||
function showByType(type) {
|
||||
if(type == 'account')
|
||||
{
|
||||
$('#password-field').show();
|
||||
|
||||
$('#privateKey-field').hide();
|
||||
$('#passphrase-field').hide();
|
||||
$('#token-field').hide();
|
||||
}
|
||||
else if (type == 'token')
|
||||
{
|
||||
$('#token-field').show();
|
||||
|
||||
$('#privateKey-field').hide();
|
||||
$('#passphrase-field').hide();
|
||||
$('#password-field').hide();
|
||||
}
|
||||
else // sshKey
|
||||
{
|
||||
$('#privateKey-field').show();
|
||||
$('#passphrase-field').show();
|
||||
|
||||
$('#password-field').hide();
|
||||
$('#token-field').hide();
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
$lang->credentials->delete = '删除凭证';
|
||||
$lang->credentials->confirmDelete = '确认删除该凭证吗?';
|
||||
|
||||
$lang->credentials->id = 'ID';
|
||||
$lang->credentials->name = '名称';
|
||||
$lang->credentials->type = '类型';
|
||||
$lang->credentials->username = '用户名';
|
||||
$lang->credentials->password = '密码';
|
||||
$lang->credentials->privateKey = '私钥';
|
||||
$lang->credentials->passphrase = '私钥密码';
|
||||
$lang->credentials->token = 'Token';
|
||||
$lang->credentials->desc = '描述';
|
||||
|
||||
$lang->credentials->typeList['account'] = '用户名密码';
|
||||
$lang->credentials->typeList['sshKey'] = '密钥';
|
||||
$lang->credentials->typeList['token'] = 'Token';
|
||||
@@ -1,106 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The model file of ci module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chenqi <chenqi@cnezsoft.com>
|
||||
* @package product
|
||||
* @version $Id: $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
|
||||
class cicredentialsModel extends model
|
||||
{
|
||||
/**
|
||||
* Get a credentials by id.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getByID($id)
|
||||
{
|
||||
$credentials = $this->dao->select('*')->from(TABLE_CREDENTIALS)->where('id')->eq($id)->fetch();
|
||||
return $credentials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get credentials list.
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @param bool $decode
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function listAll($orderBy = 'id_desc', $pager = null, $decode = true)
|
||||
{
|
||||
$credentials = $this->dao->select('*')->from(TABLE_CREDENTIALS)
|
||||
->where('deleted')->eq('0')
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
return $credentials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a credentials.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$credentials = fixer::input('post')
|
||||
->add('createdBy', $this->app->user->account)
|
||||
->add('createdDate', helper::now())
|
||||
// ->remove('')
|
||||
->get();
|
||||
|
||||
$this->dao->insert(TABLE_CREDENTIALS)->data($credentials)
|
||||
->batchCheck($this->config->credentials->create->requiredFields, 'notempty')
|
||||
->autoCheck()
|
||||
->exec();
|
||||
return !dao::isError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a credentials.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function update($id)
|
||||
{
|
||||
$credentials = fixer::input('post')
|
||||
->add('editedBy', $this->app->user->account)
|
||||
->add('editedDate', helper::now())
|
||||
->get();
|
||||
|
||||
$this->dao->update(TABLE_CREDENTIALS)->data($credentials)
|
||||
->batchCheck($this->config->credentials->edit->requiredFields, 'notempty')
|
||||
->autoCheck()
|
||||
->where('id')->eq($id)
|
||||
->exec();
|
||||
return !dao::isError();
|
||||
}
|
||||
|
||||
/**
|
||||
* list credentials for repo and jenkins edit page
|
||||
*
|
||||
* @param $whr
|
||||
* @return mixed
|
||||
*/
|
||||
public function listForSelection($whr)
|
||||
{
|
||||
$credentials = $this->dao->select('id, name')->from(TABLE_CREDENTIALS)
|
||||
->where('deleted')->eq('0')
|
||||
->beginIF(!empty(whr))->andWhere('(' . $whr . ')')->fi()
|
||||
->orderBy(id)
|
||||
->fetchPairs();
|
||||
$credentials[''] = '';
|
||||
return $credentials;
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The browse view file of credentials module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2017 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Gang Liu <liugang@cnezsoft.com>
|
||||
* @package credentials
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../ci/lang/zh-cn.php'; ?>
|
||||
<?php include '../../ci/view/header.html.php'; ?>
|
||||
<?php js::set('confirmDelete', $lang->credentials->confirmDelete); ?>
|
||||
|
||||
<div id='mainContent' class='main-row'>
|
||||
<div class='side-col' id='sidebar'>
|
||||
<?php include '../../ci/view/menu.html.php'; ?>
|
||||
</div>
|
||||
<div class='main-col main-content'>
|
||||
<form class='main-table' id='ajaxForm' method='post'>
|
||||
<table id='credentialsList' class='table has-sort-head table-fixed'>
|
||||
<thead>
|
||||
<tr>
|
||||
<?php $vars = "orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"; ?>
|
||||
<th class='w-60px'><?php common::printOrderLink('id', $orderBy, $vars, $lang->credentials->id); ?></th>
|
||||
<th class='w-120px'><?php common::printOrderLink('type', $orderBy, $vars, $lang->credentials->type); ?></th>
|
||||
<th class='w-200px text-left'><?php common::printOrderLink('name', $orderBy, $vars, $lang->credentials->name); ?></th>
|
||||
<th class='c-actions-4'><?php echo $lang->actions; ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($credentialsList as $id => $credentials): ?>
|
||||
<tr>
|
||||
<td class='text-center'><?php echo $id; ?></td>
|
||||
<td class='text'><?php echo zget($lang->credentials->typeList, $credentials->type); ?></td>
|
||||
<td class='text' title='<?php echo $credentials->name; ?>'><?php echo $credentials->name; ?></td>
|
||||
<td class='c-actions text-right'>
|
||||
<?php
|
||||
common::printIcon('cicredentials', 'edit', "id=$id", '', 'list', 'edit');
|
||||
if (common::hasPriv('cicredentials', 'delete')) {
|
||||
$deleteURL = $this->createLink('cicredentials', 'delete', "id=$id&confirm=yes");
|
||||
echo html::a("javascript:ajaxDelete(\"$deleteURL\", \"credentialsList\", confirmDelete)", '<i class="icon-trash"></i>', '', "title='{$lang->credentials->delete}' class='btn'");
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php if ($credentialsList): ?>
|
||||
<div class='table-footer'><?php $pager->show('rignt', 'pagerjs'); ?></div>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php'; ?>
|
||||
@@ -1,86 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The create view file of credentials module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2017 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Gang Liu <liugang@cnezsoft.com>
|
||||
* @package credentials
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../ci/lang/zh-cn.php'; ?>
|
||||
<?php include '../../ci/view/header.html.php'; ?>
|
||||
<?php include '../../common/view/form.html.php'; ?>
|
||||
|
||||
<?php js::set('type', 'account')?>
|
||||
|
||||
<div id='mainContent' class='main-row'>
|
||||
<div class='side-col' id='sidebar'>
|
||||
<?php include '../../ci/view/menu.html.php'; ?>
|
||||
</div>
|
||||
<div class='main-col main-content'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
<h2><?php echo $lang->credentials->create; ?></h2>
|
||||
</div>
|
||||
<form id='credentialsForm' method='post' class='form-ajax'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th class='thWidth'><?php echo $lang->credentials->type; ?></th>
|
||||
<td style="width:550px"><?php echo html::select('type', $lang->credentials->typeList, 'account', "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->credentials->name; ?></th>
|
||||
<td class='required'><?php echo html::input('name', '', "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><?php echo $lang->credentials->username; ?></th>
|
||||
<td><?php echo html::input('username', '', "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr id="password-field">
|
||||
<th><?php echo $lang->credentials->password; ?></th>
|
||||
<td><?php echo html::input('password', '', "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr id="privateKey-field">
|
||||
<th><?php echo $lang->credentials->privateKey; ?></th>
|
||||
<td><?php echo html::textarea('privateKey', '', "rows='3' class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr id="passphrase-field">
|
||||
<th><?php echo $lang->credentials->passphrase; ?></th>
|
||||
<td><?php echo html::password('passphrase', '', "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr id="token-field">
|
||||
<th><?php echo $lang->credentials->token; ?></th>
|
||||
<td><?php echo html::input('token', '', "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><?php echo $lang->credentials->desc; ?></th>
|
||||
<td><?php echo html::textarea('desc', '', "rows='3' class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td class='text-center form-actions'>
|
||||
<?php echo html::submitButton(); ?>
|
||||
<?php echo html::backButton(); ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include '../../common/view/footer.html.php'; ?>
|
||||
@@ -1,85 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The edit view file of credentials module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2017 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Gang Liu <liugang@cnezsoft.com>
|
||||
* @package credentials
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../ci/lang/zh-cn.php'; ?>
|
||||
<?php include '../../ci/view/header.html.php'; ?>
|
||||
<?php include '../../common/view/form.html.php'; ?>
|
||||
|
||||
<?php js::set('type', $credentials->type)?>
|
||||
|
||||
<div id='mainContent' class='main-row'>
|
||||
<div class='side-col' id='sidebar'>
|
||||
<?php include '../../ci/view/menu.html.php'; ?>
|
||||
</div>
|
||||
<div class='main-col main-content'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
<h2><?php echo $lang->credentials->edit; ?></h2>
|
||||
</div>
|
||||
<form id='credentialsForm' method='post' class='form-ajax'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th class='thWidth'><?php echo $lang->credentials->type; ?></th>
|
||||
<td style="width:550px"><?php echo html::select('type', $lang->credentials->typeList, $credentials->type, "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->credentials->name; ?></th>
|
||||
<td class='required'><?php echo html::input('name', $credentials->name, "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><?php echo $lang->credentials->username; ?></th>
|
||||
<td><?php echo html::input('username', $credentials->username, "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr id="password-field">
|
||||
<th><?php echo $lang->credentials->password; ?></th>
|
||||
<td><?php echo html::input('password', $credentials->password, "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr id="privateKey-field">
|
||||
<th><?php echo $lang->credentials->privateKey; ?></th>
|
||||
<td><?php echo html::textarea('privateKey', $credentials->privateKey, "rows='3' class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr id="passphrase-field">
|
||||
<th><?php echo $lang->credentials->passphrase; ?></th>
|
||||
<td><?php echo html::password('passphrase', $credentials->passphrase, "rows='3' class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr id="token-field">
|
||||
<th><?php echo $lang->credentials->token; ?></th>
|
||||
<td><?php echo html::input('token', $credentials->token, "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><?php echo $lang->credentials->desc; ?></th>
|
||||
<td><?php echo html::textarea('desc', $credentials->desc, "rows='3' class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th></th>
|
||||
<td class='text-center form-actions'>
|
||||
<?php echo html::submitButton(); ?>
|
||||
<?php echo html::backButton() ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php'; ?>
|
||||
@@ -1 +0,0 @@
|
||||
<?php
|
||||
@@ -1,8 +0,0 @@
|
||||
<?php
|
||||
$config->repo->create->requiredFields = 'SCM,name,path,encoding,client,credentials';
|
||||
$config->repo->edit->requiredFields = 'SCM,name,path,encoding,client,credentials';
|
||||
$config->repo->cacheTime = 10;
|
||||
$config->repo->syncTime = 10;
|
||||
$config->repo->batchNum = 100;
|
||||
$config->repo->images = '|png|gif|jpg|ico|jpeg|bmp|';
|
||||
$config->repo->binary = '|pdf|';
|
||||
@@ -1,298 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The control file of cirepo module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chenqi <chenqi@cnezsoft.com>
|
||||
* @package product
|
||||
* @version $Id: ${FILE_NAME} 5144 2020/1/8 8:10 下午 chenqi@cnezsoft.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
class cirepo extends control
|
||||
{
|
||||
/**
|
||||
* ci constructor.
|
||||
* @param string $moduleName
|
||||
* @param string $methodName
|
||||
*/
|
||||
public function __construct($moduleName = '', $methodName = '')
|
||||
{
|
||||
parent::__construct($moduleName, $methodName);
|
||||
$this->scm = $this->app->loadClass('scm');
|
||||
|
||||
$this->app->loadLang('ci');
|
||||
}
|
||||
|
||||
/**
|
||||
* Browse repo.
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function browse($orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$this->view->repoList = $this->cirepo->listAll($orderBy, $pager);
|
||||
|
||||
$this->view->title = $this->lang->ci->repo . $this->lang->colon . $this->lang->ci->browse;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = $this->lang->ci->repo;
|
||||
$this->view->position[] = $this->lang->ci->browse;
|
||||
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->module = 'cirepo';
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a repo.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
if($_POST)
|
||||
{
|
||||
$repoID = $this->cirepo->create();
|
||||
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
|
||||
$link = $this->cirepo->createLink('showSyncComment', "repoID=$repoID");
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $link));
|
||||
}
|
||||
|
||||
$this->app->loadLang('action');
|
||||
|
||||
$this->view->groups = $this->loadModel('group')->getPairs();
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter|noempty|nodeleted');
|
||||
|
||||
$this->view->credentialsList = $this->loadModel('cicredentials')->listForSelection("type='sshKey' or type='account'");
|
||||
$this->view->tips = str_replace("{user}",exec('whoami'), $this->lang->repo->tips);
|
||||
|
||||
$this->view->title = $this->lang->ci->repo . $this->lang->colon . $this->lang->ci->create;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = html::a(inlink('browse'), $this->lang->ci->repo);
|
||||
$this->view->position[] = $this->lang->ci->create;
|
||||
$this->view->module = 'cirepo';
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a repo.
|
||||
*
|
||||
* @param int $repoID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function edit($repoID)
|
||||
{
|
||||
$repo = $this->cirepo->getByID($repoID);
|
||||
if($_POST)
|
||||
{
|
||||
$noNeedSync = $this->cirepo->update($repoID);
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
if(!$noNeedSync)
|
||||
{
|
||||
$link = $this->cirepo->createLink('showSyncComment', "repoID=$repoID");
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $link));
|
||||
}
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
|
||||
}
|
||||
|
||||
$this->app->loadLang('action');
|
||||
|
||||
$this->view->repo = $repo;
|
||||
$this->view->groups = $this->loadModel('group')->getPairs();
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter|noempty|nodeleted');
|
||||
|
||||
$this->view->credentialsList = $this->loadModel('cicredentials')->listForSelection("type='sshKey' or type='account'");
|
||||
$this->view->tips = str_replace("{user}", exec('whoami'), $this->lang->repo->tips);
|
||||
|
||||
$this->view->title = $this->lang->ci->repo . $this->lang->colon . $this->lang->ci->edit;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = html::a(inlink('browse'), $this->lang->ci->repo);
|
||||
$this->view->position[] = $this->lang->ci->edit;
|
||||
$this->view->module = 'cirepo';
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a repo.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
$this->cirepo->delete(TABLE_REPO, $id);
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
|
||||
$this->send(array('result' => 'success'));
|
||||
}
|
||||
|
||||
/**
|
||||
* sync repo from remote.
|
||||
*
|
||||
* @param int $repoID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function sync($repoID = 0)
|
||||
{
|
||||
$this->dao->update(TABLE_REPO)->set('synced')->eq(0)->where('id')->eq($repoID)->exec();
|
||||
|
||||
$link = $this->cirepo->createLink('showSyncComment', "repoID=$repoID&needPull=true");
|
||||
$this->send(array('result' => 'success', 'locate' => $link));
|
||||
}
|
||||
|
||||
/**
|
||||
* browse branches.
|
||||
*
|
||||
* @param int $repoID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function browseBranch($repoID = 0)
|
||||
{
|
||||
$repo = $this->cirepo->getByID($repoID);
|
||||
$branches = $this->cirepo->getBranchesFromDb($repoID);
|
||||
|
||||
$this->view->repo = $repo;
|
||||
$this->view->branches = $branches;
|
||||
|
||||
$this->view->title = $this->lang->ci->repo . $this->lang->colon . $this->lang->repo->browseBranch;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = html::a(inlink('browse'), $this->lang->ci->repo);
|
||||
$this->view->position[] = $this->lang->repo->browseBranch;
|
||||
|
||||
$this->view->module = 'cirepo';
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show sync comment.
|
||||
*
|
||||
* @param int $repoID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function showSyncComment($repoID = 0, $needPull = false)
|
||||
{
|
||||
if($repoID == 0) $repoID = $this->session->repoID;
|
||||
|
||||
$this->view->title = $this->lang->repo->common . $this->lang->colon . $this->lang->repo->showSyncComment;
|
||||
$this->view->position[] = $this->lang->repo->showSyncComment;
|
||||
|
||||
$latestInDB = $this->cirepo->getLatestComment($repoID);
|
||||
$this->view->version = $latestInDB ? (int)$latestInDB->commit : 1;
|
||||
$this->view->repoID = $repoID;
|
||||
$this->view->needPull = $needPull;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax sync comment.
|
||||
*
|
||||
* @param int $repoID
|
||||
* @param string $type
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxSyncComment($repoID = 0, $type = 'batch', $needPull = false)
|
||||
{
|
||||
set_time_limit(0);
|
||||
$repo = $this->cirepo->getByID($repoID);
|
||||
|
||||
if ($needPull) {
|
||||
$this->loadModel('git')->pull($repo);
|
||||
}
|
||||
|
||||
if(empty($repo)) die();
|
||||
if($repo->synced) die('finish');
|
||||
|
||||
$this->scm->setEngine($repo);
|
||||
|
||||
$branchID = '';
|
||||
if($repo->SCM == 'Git' and empty($branchID))
|
||||
{
|
||||
$branches = $this->scm->branch();
|
||||
if($branches)
|
||||
{
|
||||
/* Init branchID. */
|
||||
if($this->cookie->syncBranch) $branchID = $this->cookie->syncBranch;
|
||||
if(!isset($branches[$branchID])) $branchID = '';
|
||||
if(empty($branchID)) $branchID = reset($branches);
|
||||
|
||||
/* Get unsynced branches. */
|
||||
foreach($branches as $branch)
|
||||
{
|
||||
unset($branches[$branch]);
|
||||
if($branch == $branchID)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$latestInDB = $this->dao->select('DISTINCT t1.*')->from(TABLE_REPOHISTORY)->alias('t1')
|
||||
->leftJoin(TABLE_REPOBRANCH)->alias('t2')->on('t1.id=t2.revision')
|
||||
->where('t1.repo')->eq($repoID)
|
||||
// ->beginIF($repo->SCM == 'Git' and $this->cookie->repoBranch)->andWhere('t2.branch')->eq($this->cookie->repoBranch)->fi()
|
||||
->orderBy('t1.time')
|
||||
->limit(1)
|
||||
->fetch();
|
||||
|
||||
$version = empty($latestInDB) ? 1 : $latestInDB->commit + 1;
|
||||
$logs = array();
|
||||
$revision = $version == 1 ? 'HEAD' : ($repo->SCM == 'Git' ? $latestInDB->commit : $latestInDB->revision);
|
||||
if($type == 'batch')
|
||||
{
|
||||
$logs = $this->scm->getCommits($revision, $this->config->repo->batchNum, $branchID);
|
||||
}
|
||||
else
|
||||
{
|
||||
$logs = $this->scm->getCommits($revision, 0, $branchID);
|
||||
}
|
||||
|
||||
$commitCount = $this->cirepo->saveCommit($repoID, $logs, $version, $branchID);
|
||||
if(empty($commitCount))
|
||||
{
|
||||
if(!$repo->synced)
|
||||
{
|
||||
if($repo->SCM == 'Git')
|
||||
{
|
||||
if($branchID) $this->cirepo->saveExistsLogBranch($repo->id, $branchID);
|
||||
|
||||
$branchID = reset($branches);
|
||||
setcookie("syncBranch", $branchID, 0, $this->config->webRoot);
|
||||
|
||||
if($branchID) $this->cirepo->fixCommit($repoID);
|
||||
}
|
||||
|
||||
if(empty($branchID))
|
||||
{
|
||||
$this->cirepo->markSynced($repoID);
|
||||
die('finish');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_REPO)->set('commits=commits + ' . $commitCount)->where('id')->eq($repoID)->exec();
|
||||
echo $type == 'batch' ? $commitCount : 'finish';
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
$(function()
|
||||
{
|
||||
$('#' + module + 'Tab').addClass('btn-active-text');
|
||||
})
|
||||
@@ -1,4 +0,0 @@
|
||||
$(function()
|
||||
{
|
||||
$('#' + module + 'Tab').addClass('btn-active-text');
|
||||
})
|
||||
@@ -1,4 +0,0 @@
|
||||
$(function()
|
||||
{
|
||||
$('#' + module + 'Tab').addClass('btn-active-text');
|
||||
})
|
||||
@@ -1,4 +0,0 @@
|
||||
$(function()
|
||||
{
|
||||
$('#' + module + 'Tab').addClass('btn-active-text');
|
||||
});
|
||||
@@ -1 +0,0 @@
|
||||
<?php
|
||||
@@ -1,66 +0,0 @@
|
||||
<?php
|
||||
$lang->repo->browseBranch = '查看分支';
|
||||
|
||||
$lang->repo->delete = '删除代码库';
|
||||
$lang->repo->confirmDelete = '确认删除该代码库吗?';
|
||||
|
||||
$lang->repo->id = 'ID';
|
||||
$lang->repo->name = '名称';
|
||||
$lang->repo->path = '地址';
|
||||
$lang->repo->type = '类型';
|
||||
$lang->repo->client = '客户端';
|
||||
$lang->repo->credentials = '凭证';
|
||||
$lang->repo->encoding = '编码';
|
||||
$lang->repo->account = '用户名';
|
||||
$lang->repo->password = '密码';
|
||||
$lang->repo->token = 'Token';
|
||||
$lang->repo->acl = '权限';
|
||||
$lang->repo->group = '分组';
|
||||
$lang->repo->user = '用户';
|
||||
$lang->repo->desc = '描述';
|
||||
|
||||
$lang->repo->example = new stdclass();
|
||||
$lang->repo->example->client = "例如:/usr/bin/svn, C:\subversion\svn.exe, /usr/bin/git";
|
||||
$lang->repo->example->path = "例如:SVN: http://example.googlecode.com/svn/, GIT: /homt/test";
|
||||
$lang->repo->example->config = "https需要填写配置目录的位置,通过config-dir选项生成配置目录";
|
||||
$lang->repo->example->encoding = "填写版本库中文件的编码";
|
||||
$lang->repo->svnCredentialsLimt = "Subversion版本库的凭证必须为用户名密码类型";
|
||||
|
||||
$lang->repo->showSyncComment = '显示同步进度';
|
||||
$lang->repo->watch = '监听';
|
||||
|
||||
$lang->repo->notice = new stdclass();
|
||||
$lang->repo->notice->syncing = '正在同步中, 请稍等...';
|
||||
$lang->repo->notice->syncComplete = '同步完成,正在跳转...';
|
||||
$lang->repo->notice->syncedCount = '已经同步记录条数';
|
||||
$lang->repo->notice->delete = '是否要删除该版本库?';
|
||||
$lang->repo->notice->successDelete = '已经成功删除版本库。';
|
||||
$lang->repo->notice->commentContent = '输入回复内容';
|
||||
$lang->repo->notice->deleteBug = '确认删除该Bug?';
|
||||
$lang->repo->notice->deleteComment = '确认删除该回复?';
|
||||
$lang->repo->notice->lastSyncTime = '最后更新于:';
|
||||
|
||||
$lang->repo->error = new stdclass();
|
||||
$lang->repo->error->useless = '你的服务器禁用了exec,shell_exec方法,无法使用该功能';
|
||||
$lang->repo->error->connect = '连接版本库失败,请填写正确的用户名、密码和版本库地址!';
|
||||
$lang->repo->error->version = "https和svn协议需要1.8及以上版本的客户端,请升级到最新版本!详情访问:http://subversion.apache.org/";
|
||||
$lang->repo->error->path = '版本库地址直接填写文件路径,如:/home/test。';
|
||||
$lang->repo->error->cmd = '客户端错误!';
|
||||
$lang->repo->error->diff = '必须选择两个版本';
|
||||
$lang->repo->error->product = "请选择{$lang->productCommon}!";
|
||||
$lang->repo->error->commentText = '请填写评审内容';
|
||||
$lang->repo->error->comment = '请填写内容';
|
||||
$lang->repo->error->title = '请填写标题';
|
||||
$lang->repo->error->accessDenied = '你没有权限访问该版本库';
|
||||
$lang->repo->error->noFound = '你访问的版本库不存在';
|
||||
$lang->repo->error->noFile = '目录 %s 不存在';
|
||||
$lang->repo->error->noPriv = '程序没有权限切换到目录 %s';
|
||||
$lang->repo->error->output = "执行命令:%s\n错误结果(%s): %s\n";
|
||||
$lang->repo->error->clientVersion = "客户端版本过低,请升级或更换SVN客户端";
|
||||
$lang->repo->error->encoding = "编码可能错误,请更换编码重试。";
|
||||
|
||||
//$lang->repo->scmList['Subversion'] = 'Subversion';
|
||||
$lang->repo->scmList['Git'] = 'Git';
|
||||
$lang->repo->tips = '请使用用户<strong class="text-blue">{user}</strong>签出代码,以便于系统获取后续的代码同步权限。如:<strong class="text-blue">sudo -u {user} git clone git_rep_address</strong>';
|
||||
|
||||
$lang->repo->watchList['1'] = '';
|
||||
@@ -1,456 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The model file of cirepo module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chenqi <chenqi@cnezsoft.com>
|
||||
* @package product
|
||||
* @version $Id: $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
|
||||
class cirepoModel extends model
|
||||
{
|
||||
/**
|
||||
* Get a repo by id.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getByID($id)
|
||||
{
|
||||
$repo = $this->dao->select('*')->from(TABLE_REPO)->where('id')->eq($id)->fetch();
|
||||
return $repo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get repo list.
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @param bool $decode
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function listAll($orderBy = 'id_desc', $pager = null, $decode = true)
|
||||
{
|
||||
$repoList = $this->dao->select('*')->from(TABLE_REPO)
|
||||
->where('deleted')->eq('0')
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
return $repoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a repo.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$data = fixer::input('post')->skipSpecial('path,client,account,password')->get();
|
||||
if ($data->SCM === 'Subversion') {
|
||||
$credentials = $this->loadModel('cicredentials')->getByID($data->credentials);
|
||||
if ($credentials->type != 'account') {
|
||||
dao::$errors['credentials'][] = $this->repo->svnCredentialsLimt;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->checkRepoConnection();
|
||||
$data = fixer::input('post')->skipSpecial('path,client,account,password')->get();
|
||||
|
||||
$data->acl = empty($data->acl) ? '' : json_encode($data->acl);
|
||||
if(empty($data->client)) $data->client = 'svn';
|
||||
|
||||
if($data->SCM == 'Subversion')
|
||||
{
|
||||
$scm = $this->app->loadClass('scm');
|
||||
$scm->setEngine($data);
|
||||
$info = $scm->info('');
|
||||
$data->prefix = empty($info->root) ? '' : trim(str_ireplace($info->root, '', str_replace('\\', '/', $data->path)), '/');
|
||||
if($data->prefix) $data->prefix = '/' . $data->prefix;
|
||||
}
|
||||
|
||||
if($data->encrypt == 'base64') $data->password = base64_encode($data->password);
|
||||
$this->dao->insert(TABLE_REPO)->data($data)
|
||||
->batchCheck($this->config->repo->create->requiredFields, 'notempty')
|
||||
->autoCheck()
|
||||
->exec();
|
||||
return $this->dao->lastInsertID();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a repo.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function update($id)
|
||||
{
|
||||
$this->checkRepoConnection();
|
||||
$data = fixer::input('post')->skipSpecial('path,client,account,password')->get();
|
||||
$data->acl = empty($data->acl) ? '' : json_encode($data->acl);
|
||||
|
||||
if(empty($data->client)) $data->client = 'svn';
|
||||
$repo = $this->getByID($id);
|
||||
$data->prefix = $repo->prefix;
|
||||
if($data->SCM == 'Subversion' and $data->path != $repo->path)
|
||||
{
|
||||
$scm = $this->app->loadClass('scm');
|
||||
$scm->setEngine($data);
|
||||
$info = $scm->info('');
|
||||
$data->prefix = empty($info->root) ? '' : trim(str_ireplace($info->root, '', str_replace('\\', '/', $data->path)), '/');
|
||||
if($data->prefix) $data->prefix = '/' . $data->prefix;
|
||||
}
|
||||
elseif($data->SCM != $repo->SCM and $data->SCM == 'Git')
|
||||
{
|
||||
$data->prefix = '';
|
||||
}
|
||||
|
||||
if($data->path != $repo->path) $data->synced = 0;
|
||||
if($data->encrypt == 'base64') $data->password = base64_encode($data->password);
|
||||
$this->dao->update(TABLE_REPO)->data($data)
|
||||
->batchCheck($this->config->repo->create->requiredFields, 'notempty')
|
||||
->autoCheck()
|
||||
->where('id')->eq($id)->exec();
|
||||
if($repo->path != $data->path)
|
||||
{
|
||||
$this->dao->delete()->from(TABLE_REPOHISTORY)->where('repo')->eq($id)->exec();
|
||||
$this->dao->delete()->from(TABLE_REPOFILES)->where('repo')->eq($id)->exec();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get git branches from scm.
|
||||
*
|
||||
* @param object $repo
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getBranches($repo)
|
||||
{
|
||||
$this->scm = $this->app->loadClass('scm');
|
||||
$this->scm->setEngine($repo);
|
||||
return $this->scm->branch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get git branches from db.
|
||||
*
|
||||
* @param object $repo
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getBranchesFromDb($repoID)
|
||||
{
|
||||
$branches = $this->dao->select('*')->from(TABLE_REPOBRANCH)
|
||||
->where('repo')->eq($repoID)
|
||||
->fetchAll('repo');
|
||||
return $branches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check repo connection
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function checkRepoConnection()
|
||||
{
|
||||
if(empty($_POST)) return false;
|
||||
$scm = $this->post->SCM;
|
||||
$client = $this->post->client;
|
||||
$encoding = strtoupper($this->post->encoding);
|
||||
$path = $this->post->path;
|
||||
if($encoding != 'UTF8' and $encoding != 'UTF-8') $path = helper::convertEncoding($path, 'utf-8', $encoding);
|
||||
|
||||
$account = "";
|
||||
$password = "";
|
||||
$privateKey = "";
|
||||
$passphrase = "";
|
||||
|
||||
$credentials = $this->loadModel('cicredentials')->getByID($this->post->credentials);
|
||||
if ($credentials->type === 'account') {
|
||||
$account = $credentials->username;
|
||||
$password = $credentials->password;
|
||||
|
||||
$_POST['account'] = $account;
|
||||
$_POST['password'] = $password;
|
||||
} else {
|
||||
$privateKey = $credentials->privateKey;
|
||||
$passphrase = $credentials->passphrase;
|
||||
|
||||
$_POST['privateKey'] = $privateKey;
|
||||
$_POST['passphrase'] = $passphrase;
|
||||
}
|
||||
|
||||
if($scm == 'Subversion')
|
||||
{
|
||||
$path = '"' . $path . '"';
|
||||
if(stripos($path, 'https://') === 1 or stripos($path, 'svn://') === 1)
|
||||
{
|
||||
$ssh = true;
|
||||
$remote = true;
|
||||
$command = "$client info --username $account --password $password --non-interactive --trust-server-cert-failures=cn-mismatch --trust-server-cert --no-auth-cache $path 2>&1";
|
||||
}
|
||||
else if(stripos($path, 'file://') === 1)
|
||||
{
|
||||
$ssh = false;
|
||||
$remote = false;
|
||||
$command = "$client info --non-interactive --no-auth-cache $path 2>&1";
|
||||
}
|
||||
else
|
||||
{
|
||||
$ssh = false;
|
||||
$remote = true;
|
||||
$command = "$client info --username $account --password $password --non-interactive --no-auth-cache $path 2>&1";
|
||||
}
|
||||
exec($command, $output, $result);
|
||||
if($result)
|
||||
{
|
||||
$versionCommand = "$client --version --quiet 2>&1";
|
||||
exec($versionCommand, $versionOutput, $versionResult);
|
||||
if($versionResult)
|
||||
{
|
||||
$message = sprintf($this->lang->repo->error->output, $versionCommand, $versionResult, join("\n", $versionOutput));
|
||||
echo $message;
|
||||
die(js::alert($this->lang->repo->error->cmd . '\n' . str_replace(array("\n", "'"), array('\n', '"'), $message)));
|
||||
}
|
||||
if($ssh and version_compare(end($versionOutput), '1.6', '<')) die(js::alert($this->lang->repo->error->version));
|
||||
$message = sprintf($this->lang->repo->error->output, $command, $result, join("\n", $output));
|
||||
echo $message;
|
||||
if(stripos($message, 'Expected FS format between') !== false and strpos($message, 'found format') !== false) die(js::alert($this->lang->repo->error->clientVersion));
|
||||
if(preg_match('/[^\:\/\\A-Za-z0-9_\-\'\"]/', $path)) die(js::alert($this->lang->repo->error->encoding . '\n' . str_replace(array("\n", "'"), array('\n', '"'), $message)));
|
||||
die(js::alert($this->lang->repo->error->connect . '\n' . str_replace(array("\n", "'"), array('\n', '"'), $message)));
|
||||
}
|
||||
}
|
||||
elseif($scm == 'Git')
|
||||
{
|
||||
if(!chdir($path))
|
||||
{
|
||||
if(!is_dir($path)) die(js::alert(sprintf($this->lang->repo->error->noFile, $path)));
|
||||
if(!is_executable($path)) die(js::alert(sprintf($this->lang->repo->error->noPriv, $path)));
|
||||
die(js::alert($this->lang->repo->error->path));
|
||||
}
|
||||
|
||||
$command = "$client tag 2>&1";
|
||||
exec($command, $output, $result);
|
||||
if($result)
|
||||
{
|
||||
echo sprintf($this->lang->repo->error->output, $command, $result, join("\n", $output));
|
||||
die(js::alert($this->lang->repo->error->connect));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get latest comment.
|
||||
*
|
||||
* @param int $repoID
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getLatestComment($repoID, $branchID='')
|
||||
{
|
||||
$count = $this->dao->select('count(DISTINCT t1.id) as count')->from(TABLE_REPOHISTORY)->alias('t1')
|
||||
->leftJoin(TABLE_REPOBRANCH)->alias('t2')->on('t1.id=t2.revision')
|
||||
->where('t1.repo')->eq($repoID)
|
||||
->beginIF($branchID)->andWhere('t2.branch')->eq($branchID)->fi()
|
||||
->fetch('count');
|
||||
|
||||
$lastComment = $this->dao->select('t1.*')->from(TABLE_REPOHISTORY)->alias('t1')
|
||||
->leftJoin(TABLE_REPOBRANCH)->alias('t2')->on('t1.id=t2.revision')
|
||||
->where('t1.repo')->eq($repoID)
|
||||
->beginIF($branchID)->andWhere('t2.branch')->eq($branchID)->fi()
|
||||
->orderBy('t1.time desc')
|
||||
->limit(1)
|
||||
->fetch();
|
||||
if(empty($lastComment)) return null;
|
||||
|
||||
$repo = $this->getByID($repoID);
|
||||
if($repo->SCM == 'Git' and $lastComment->commit != $count)
|
||||
{
|
||||
$this->fixCommit($repo->id);
|
||||
$lastComment->commit = $count;
|
||||
}
|
||||
|
||||
return $lastComment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save commit.
|
||||
*
|
||||
* @param int $repoID
|
||||
* @param array $logs
|
||||
* @param int $version
|
||||
* @param string $branch
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function saveCommit($repoID, $logs, $version, $branch = '')
|
||||
{
|
||||
$count = 0;
|
||||
if(empty($logs)) return $count;
|
||||
|
||||
foreach($logs['commits'] as $i => $commit)
|
||||
{
|
||||
$existsRevision = $this->dao->select('id,revision')->from(TABLE_REPOHISTORY)->where('repo')->eq($repoID)->andWhere('revision')->eq($commit->revision)->fetch();
|
||||
if($existsRevision)
|
||||
{
|
||||
if($branch) $this->dao->replace(TABLE_REPOBRANCH)->set('repo')->eq($repoID)->set('revision')->eq($existsRevision->id)->set('branch')->eq($branch)->exec();
|
||||
continue;
|
||||
}
|
||||
|
||||
$commit->repo = $repoID;
|
||||
$commit->commit = $version;
|
||||
$commit->comment = htmlspecialchars($commit->comment);
|
||||
$this->dao->insert(TABLE_REPOHISTORY)->data($commit)->exec();
|
||||
if(!dao::isError())
|
||||
{
|
||||
$commitID = $this->dao->lastInsertID();
|
||||
if($branch) $this->dao->replace(TABLE_REPOBRANCH)->set('repo')->eq($repoID)->set('revision')->eq($commitID)->set('branch')->eq($branch)->exec();
|
||||
foreach($logs['files'][$i] as $file)
|
||||
{
|
||||
$parentPath = dirname($file->path);
|
||||
|
||||
$file->parent = $parentPath == '\\' ? '/' : $parentPath;
|
||||
$file->revision = $commitID;
|
||||
$file->repo = $repoID;
|
||||
$this->dao->insert(TABLE_REPOFILES)->data($file)->exec();
|
||||
}
|
||||
$revisionPairs[$commit->revision] = $commit->revision;
|
||||
$version++;
|
||||
$count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
dao::getError();
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save exists log branch.
|
||||
*
|
||||
* @param int $repoID
|
||||
* @param string $branch
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function saveExistsLogBranch($repoID, $branch)
|
||||
{
|
||||
$lastBranchLog = $this->dao->select('t1.time')->from(TABLE_REPOHISTORY)->alias('t1')
|
||||
->leftJoin(TABLE_REPOBRANCH)->alias('t2')->on('t1.id=t2.revision')
|
||||
->where('t1.repo')->eq($repoID)
|
||||
->andWhere('t2.branch')->eq($branch)
|
||||
->orderBy('time')
|
||||
->limit(1)
|
||||
->fetch();
|
||||
$stmt = $this->dao->select('*')->from(TABLE_REPOHISTORY)->where('repo')->eq($repoID)->andWhere('time')->lt($lastBranchLog->time)->query();
|
||||
while($log = $stmt->fetch())
|
||||
{
|
||||
$this->dao->REPLACE(TABLE_REPOBRANCH)->set('repo')->eq($repoID)->set('revision')->eq($log->id)->set('branch')->eq($branch)->exec();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix commit.
|
||||
*
|
||||
* @param int $repoID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function fixCommit($repoID)
|
||||
{
|
||||
$stmt = $this->dao->select('DISTINCT t1.id')->from(TABLE_REPOHISTORY)->alias('t1')
|
||||
->leftJoin(TABLE_REPOBRANCH)->alias('t2')->on('t1.id=t2.revision')
|
||||
->where('t1.repo')->eq($repoID)
|
||||
// ->beginIF($this->cookie->repoBranch)->andWhere('t2.branch')->eq($this->cookie->repoBranch)->fi()
|
||||
->orderBy('time')
|
||||
->query();
|
||||
|
||||
$i = 1;
|
||||
while($repoHistory = $stmt->fetch())
|
||||
{
|
||||
$this->dao->update(TABLE_REPOHISTORY)->set('`commit`')->eq($i)->where('id')->eq($repoHistory->id)->exec();
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark synced status.
|
||||
*
|
||||
* @param int $repoID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function markSynced($repoID)
|
||||
{
|
||||
$this->fixCommit($repoID);
|
||||
$this->dao->update(TABLE_REPO)->set('synced')->eq(1)->where('id')->eq($repoID)->exec();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create link for repo
|
||||
*
|
||||
* @param string $method
|
||||
* @param string $params
|
||||
* @param string $pathParams
|
||||
* @param string $viewType
|
||||
* @param bool $onlybody
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function createLink($method, $params = '', $pathParams = '', $viewType = '', $onlybody = false)
|
||||
{
|
||||
$link = helper::createLink('cirepo', $method, $params, $viewType, $onlybody);
|
||||
if(empty($pathParams)) return $link;
|
||||
|
||||
$link .= strpos($link, '?') === false ? '?' : '&';
|
||||
$link .= $pathParams;
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* list repos for jenkins task edit
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function listForSelection($whr)
|
||||
{
|
||||
$repos = $this->dao->select('id, name')->from(TABLE_REPO)
|
||||
->where('deleted')->eq('0')
|
||||
->beginIF(!empty(whr))->andWhere('(' . $whr . ')')->fi()
|
||||
->orderBy(id)
|
||||
->fetchPairs();
|
||||
$repos[''] = '';
|
||||
return $repos;
|
||||
}
|
||||
|
||||
/**
|
||||
* list repos for ci task edit
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function listForSync($whr)
|
||||
{
|
||||
$repos = $this->dao->select('*')->from(TABLE_REPO)
|
||||
->where('deleted')->eq('0')
|
||||
->beginIF(!empty(whr))->andWhere('(' . $whr . ')')->fi()
|
||||
->orderBy(id)
|
||||
->fetchAll();
|
||||
return $repos;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The browse view file of repo module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2017 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Gang Liu <liugang@cnezsoft.com>
|
||||
* @package repo
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../ci/lang/zh-cn.php'; ?>
|
||||
<?php include '../../ci/view/header.html.php'; ?>
|
||||
<?php js::set('confirmDelete', $lang->repo->confirmDelete); ?>
|
||||
|
||||
<div id='mainContent' class='main-row'>
|
||||
<div class='side-col' id='sidebar'>
|
||||
<?php include '../../ci/view/menu.html.php'; ?>
|
||||
</div>
|
||||
<div class='main-col main-content'>
|
||||
<form class='main-table' id='ajaxForm' method='post'>
|
||||
<table id='repoList' class='table has-sort-head table-fixed'>
|
||||
<thead>
|
||||
<tr>
|
||||
<?php $vars = "orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"; ?>
|
||||
<th class='w-60px'><?php common::printOrderLink('id', $orderBy, $vars, $lang->repo->id); ?></th>
|
||||
<th class='w-120px'><?php common::printOrderLink('SCM', $orderBy, $vars, $lang->repo->type); ?></th>
|
||||
<th class='w-200px text-left'><?php common::printOrderLink('name', $orderBy, $vars, $lang->repo->name); ?></th>
|
||||
<th class='w-200px text-left'><?php echo $lang->repo->path; ?></th>
|
||||
<th class='c-actions-4'><?php echo $lang->actions; ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($repoList as $id => $repo): ?>
|
||||
<tr>
|
||||
<td class='text-center'><?php echo $id; ?></td>
|
||||
<td class='text'><?php echo zget($lang->repo->scmList, $repo->SCM); ?></td>
|
||||
<td class='text' title='<?php echo $repo->name; ?>'><?php echo $repo->name; ?></td>
|
||||
<td class='text' title='<?php echo $repo->path; ?>'><?php echo $repo->path; ?></td>
|
||||
<td class='c-actions text-right'>
|
||||
<?php
|
||||
common::printIcon('cirepo', 'browseBranch', "repoID=$id", '', 'list', 'file-text');
|
||||
common::printIcon('cirepo', 'sync', "repoID=$id", '', 'list', 'refresh');
|
||||
echo ' ';
|
||||
common::printIcon('cirepo', 'edit', "repoID=$id", '', 'list', 'edit');
|
||||
if (common::hasPriv('cirepo', 'delete')) {
|
||||
$deleteURL = $this->createLink('cirepo', 'delete', "repoID=$id&confirm=yes");
|
||||
echo html::a("javascript:ajaxDelete(\"$deleteURL\", \"repoList\", confirmDelete)", '<i class="icon-trash"></i>', '', "title='{$lang->repo->delete}' class='btn'");
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php if ($repoList): ?>
|
||||
<div class='table-footer'><?php $pager->show('rignt', 'pagerjs'); ?></div>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php'; ?>
|
||||
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The view branch file of branch module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2017 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chenqi <chenqi@cnezsoft.com>
|
||||
* @package ci
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../ci/lang/zh-cn.php'; ?>
|
||||
<?php include '../../ci/view/header.html.php'; ?>
|
||||
|
||||
<div id='mainContent' class='main-row'>
|
||||
<div class='side-col' id='sidebar'>
|
||||
<?php include '../../ci/view/menu.html.php'; ?>
|
||||
</div>
|
||||
<div class='main-col main-content'>
|
||||
<form class='main-table' id='ajaxForm' method='post'>
|
||||
<table id='branchList' class='table has-sort-head table-fixed'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class='w-60px'><?php echo $lang->ci->numb; ?></th>
|
||||
<th class='w-120px'><?php echo $lang->ci->name; ?></th>
|
||||
<th class='c-actions-4'><?php echo $lang->actions; ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $index = 0;
|
||||
foreach ($branches as $branch): ?>
|
||||
<tr>
|
||||
<td class='text'><?php echo ++$index; ?></td>
|
||||
<td class='text' title='<?php echo $branch->branch; ?>'><?php echo $branch->branch; ?></td>
|
||||
<td class='c-actions text-right'></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php if ($branchs): ?>
|
||||
<div class='table-footer'><?php $pager->show('rignt', 'pagerjs'); ?></div>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php'; ?>
|
||||
@@ -1,97 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The create view file of repo module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2017 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Gang Liu <liugang@cnezsoft.com>
|
||||
* @package repo
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../ci/lang/zh-cn.php'; ?>
|
||||
<?php include '../../ci/view/header.html.php'; ?>
|
||||
<?php include '../../common/view/form.html.php'; ?>
|
||||
|
||||
<?php js::set('type', 'account')?>
|
||||
|
||||
<div id='mainContent' class='main-row'>
|
||||
<div class='side-col' id='sidebar'>
|
||||
<?php include '../../ci/view/menu.html.php'; ?>
|
||||
</div>
|
||||
<div class='main-col main-content'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
<h2><?php echo $lang->repo->create; ?></h2>
|
||||
</div>
|
||||
<form id='repoForm' method='post' class='form-ajax'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th class='thWidth'></th>
|
||||
<td colspan="2"><?php echo $tips; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='thWidth'><?php echo $lang->repo->type; ?></th>
|
||||
<td style="width:550px"><?php echo html::select('SCM', $lang->repo->scmList, 'git', "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->repo->name; ?></th>
|
||||
<td class='required'><?php echo html::input('name', '', "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->repo->path; ?></th>
|
||||
<td class='required'><?php echo html::input('path', '', "class='form-control'"); ?></td>
|
||||
<td class='muted'><?php echo $lang->repo->example->path;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->repo->encoding; ?></th>
|
||||
<td class='required'><?php echo html::input('encoding', 'utf-8', "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->repo->client;?></th>
|
||||
<td class='required'><?php echo html::input('client', '', "class='form-control'")?></td>
|
||||
<td class='muted'><?php echo $lang->repo->example->client;?></td>
|
||||
</tr>
|
||||
<tr id="credentials-field">
|
||||
<th class='thWidth'><?php echo $lang->credentials->common; ?></th>
|
||||
<td class='required' style="width:550px"><?php echo html::select('credentials', $credentialsList, $jenkins->credentials, "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><?php echo $lang->repo->acl;?></th>
|
||||
<td class='acl'>
|
||||
<div class='input-group mgb-10'>
|
||||
<span class='input-group-addon'><?php echo $lang->repo->group?></span>
|
||||
<?php echo html::select('acl[groups][]', $groups, '', "class='form-control chosen' multiple")?>
|
||||
</div>
|
||||
<div class='input-group'>
|
||||
<span class='input-group-addon user-addon'><?php echo $lang->repo->user?></span>
|
||||
<?php echo html::select('acl[users][]', $users, '', "class='form-control chosen' multiple")?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><?php echo $lang->repo->desc; ?></th>
|
||||
<td><?php echo html::textarea('desc', '', "rows='3' class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td class='text-center form-actions'>
|
||||
<?php echo html::submitButton(); ?>
|
||||
<?php echo html::backButton(); ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include '../../common/view/footer.html.php'; ?>
|
||||
@@ -1,97 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The edit view file of repo module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2017 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Gang Liu <liugang@cnezsoft.com>
|
||||
* @package repo
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../ci/lang/zh-cn.php'; ?>
|
||||
<?php include '../../ci/view/header.html.php'; ?>
|
||||
<?php include '../../common/view/form.html.php'; ?>
|
||||
|
||||
<?php js::set('type', $repo->type)?>
|
||||
|
||||
<div id='mainContent' class='main-row'>
|
||||
<div class='side-col' id='sidebar'>
|
||||
<?php include '../../ci/view/menu.html.php'; ?>
|
||||
</div>
|
||||
<div class='main-col main-content'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
<h2><?php echo $lang->repo->edit; ?></h2>
|
||||
</div>
|
||||
<form id='repoForm' method='post' class='form-ajax'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th class='thWidth'></th>
|
||||
<td colspan="2"><?php echo $tips; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='thWidth'><?php echo $lang->repo->type; ?></th>
|
||||
<td style="width:550px"><?php echo html::select('SCM', $lang->repo->scmList, $repo->SCM, "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->repo->name; ?></th>
|
||||
<td class='required'><?php echo html::input('name', $repo->name, "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->repo->path; ?></th>
|
||||
<td class='required'><?php echo html::input('path', $repo->path, "class='form-control'"); ?></td>
|
||||
<td class='muted'><?php echo $lang->repo->example->path;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->repo->encoding; ?></th>
|
||||
<td class='required'><?php echo html::input('encoding', $repo->encoding, "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->repo->client;?></th>
|
||||
<td class='required'><?php echo html::input('client', $repo->client, "class='form-control'")?></td>
|
||||
<td class='muted'><?php echo $lang->repo->example->client;?></td>
|
||||
</tr>
|
||||
<tr id="credentials-field">
|
||||
<th class='thWidth'><?php echo $lang->credentials->common; ?></th>
|
||||
<td class='required' style="width:550px"><?php echo html::select('credentials', $credentialsList, $repo->credentials, "class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><?php echo $lang->repo->acl;?></th>
|
||||
<td>
|
||||
<div class='input-group mgb-10'>
|
||||
<span class='input-group-addon'><?php echo $lang->repo->group?></span>
|
||||
<?php echo html::select('acl[groups][]', $groups, empty($repo->acl->groups) ? '' : join(',', $repo->acl->groups), "class='form-control chosen' multiple")?>
|
||||
</div>
|
||||
<div class='input-group'>
|
||||
<span class='input-group-addon user-addon'><?php echo $lang->repo->user?></span>
|
||||
<?php echo html::select('acl[users][]', $users, empty($repo->acl->users) ? '' : join(',', $repo->acl->users), "class='form-control chosen' multiple")?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><?php echo $lang->repo->desc; ?></th>
|
||||
<td><?php echo html::textarea('desc', $repo->desc, "rows='3' class='form-control'"); ?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th></th>
|
||||
<td class='text-center form-actions'>
|
||||
<?php echo html::submitButton(); ?>
|
||||
<?php echo html::backButton() ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php'; ?>
|
||||
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The showSyncComment view file of repo module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2010 QingDao Nature Easy Soft Network Technology Co,LTD (www.cnezsoft.com)
|
||||
* @license LGPL (http://www.gnu.org/licenses/lgpl.html)
|
||||
* @author Yidong Wang <yidong@cnezsoft.com>
|
||||
* @package repo
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../ci/lang/zh-cn.php'; ?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div id="mainContent" class="main-content">
|
||||
<div class='cell'>
|
||||
<div class='alert with-icon'>
|
||||
<i class="icon-check-sign"></i>
|
||||
<div class='content'>
|
||||
<h3><?php echo $lang->repo->notice->syncing;?></h3>
|
||||
<hr>
|
||||
<p><?php echo $lang->repo->notice->syncedCount?><span id='commits'><?php echo $version?></span></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script language='Javascript'>
|
||||
$(function(){
|
||||
var link = createLink('cirepo', 'ajaxSyncComment', "repoID=<?php echo $repoID?>&type=batch&needPull=<?php echo $needPull?>");
|
||||
|
||||
function syncComments()
|
||||
{
|
||||
$.get(link, function(data)
|
||||
{
|
||||
if(data == 'finish')
|
||||
{
|
||||
$('#caption').text('<?php echo $lang->repo->notice->syncComplete?>');
|
||||
return self.location = createLink('cirepo', 'browse');
|
||||
}
|
||||
$('#commits').html(parseInt($('#commits').html()) + parseInt(data));
|
||||
setTimeout(syncComments, 10);
|
||||
});
|
||||
}
|
||||
setTimeout(syncComments, 500);
|
||||
})
|
||||
</script>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
@@ -1,3 +0,0 @@
|
||||
<?php
|
||||
$config->citask->create->requiredFields = 'name,repo,buildType,jenkins,jenkinsTask,triggerType';
|
||||
$config->citask->edit->requiredFields = 'name,repo,buildType,jenkins,jenkinsTask,triggerType';
|
||||
@@ -1,216 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The control file of ci module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chenqi <chenqi@cnezsoft.com>
|
||||
* @package product
|
||||
* @version $Id: ${FILE_NAME} 5144 2020/1/8 8:10 下午 chenqi@cnezsoft.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
class citask extends control
|
||||
{
|
||||
/**
|
||||
* ci constructor.
|
||||
* @param string $moduleName
|
||||
* @param string $methodName
|
||||
*/
|
||||
public function __construct($moduleName = '', $methodName = '')
|
||||
{
|
||||
parent::__construct($moduleName, $methodName);
|
||||
$this->app->loadLang('ci');
|
||||
}
|
||||
|
||||
/**
|
||||
* Browse ci task.
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function browse($orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$this->view->taskList = $this->citask->listAll($orderBy, $pager);
|
||||
|
||||
$this->view->title = $this->lang->ci->task . $this->lang->colon . $this->lang->citask->browse;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = $this->lang->ci->task;
|
||||
$this->view->position[] = $this->lang->ci->browse;
|
||||
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->module = 'citask';
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ci task.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
if($_POST)
|
||||
{
|
||||
$this->citask->create();
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
|
||||
}
|
||||
|
||||
$this->app->loadLang('action');
|
||||
|
||||
$this->view->title = $this->lang->ci->task . $this->lang->colon . $this->lang->ci->create;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = html::a(inlink('browse'), $this->lang->ci->common);
|
||||
$this->view->position[] = $this->lang->ci->create;
|
||||
|
||||
$this->view->repoList = $this->loadModel('cirepo')->listForSelection("true");
|
||||
$this->view->jenkinsList = $this->loadModel('cijenkins')->listForSelection("true");
|
||||
$this->view->module = 'citask';
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a ci task.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
$citask = $this->citask->getByID($id);
|
||||
if($_POST)
|
||||
{
|
||||
$this->citask->update($id);
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
|
||||
}
|
||||
|
||||
$this->app->loadLang('action');
|
||||
|
||||
$this->view->citask = $citask;
|
||||
|
||||
$this->view->repoList = $this->loadModel('cirepo')->listForSelection("true");
|
||||
$this->view->jenkinsList = $this->loadModel('cijenkins')->listForSelection("true");
|
||||
$this->view->module = 'citask';
|
||||
|
||||
$this->view->title = $this->lang->ci->task . $this->lang->colon . $this->lang->ci->edit;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = html::a(inlink('browse'), $this->lang->ci->task);
|
||||
$this->view->position[] = $this->lang->ci->edit;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a ci task.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
$this->citask->delete(TABLE_CI_TASK, $id);
|
||||
|
||||
$command = 'moduleName=citask&methodName=exe&parm=' . $id;
|
||||
$this->dao->delete()->from(TABLE_CRON)->where('command')->eq($command)->exec();
|
||||
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
|
||||
$this->send(array('result' => 'success'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Exec a ci task.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function exe($id)
|
||||
{
|
||||
error_log("===exeCitask " . $id);
|
||||
|
||||
$this->citask->exe($id);
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
|
||||
$this->send(array('result' => 'success'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Browse jenkins build.
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function browseBuild($taskID = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$this->view->buildList = $this->citask->listBuild($taskID, $orderBy, $pager);
|
||||
|
||||
$this->view->title = $this->lang->ci->task . $this->lang->colon . $this->lang->citask->browseBuild;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = html::a(inlink('browse'), $this->lang->ci->task);
|
||||
$this->view->position[] = $this->lang->citask->browseBuild;
|
||||
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->module = 'citask';
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* View jenkins build logs.
|
||||
*
|
||||
* @param int $buildID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function viewBuildLogs($buildID)
|
||||
{
|
||||
$build = $this->citask->getBuild($buildID);
|
||||
$this->view->logs = str_replace("\r\n","<br />", $build->logs);
|
||||
|
||||
$this->view->title = $this->lang->ci->task . $this->lang->colon . $this->lang->citask->viewLogs;
|
||||
$this->view->position[] = $this->lang->ci->common;
|
||||
$this->view->position[] = html::a(inlink('browse'), $this->lang->ci->task);
|
||||
$this->view->position[] = html::a(inlink('browseBuild', "taskID=" . $build->citask), $this->lang->citask->browseBuild);
|
||||
$this->view->position[] = $this->lang->citask->viewLogs;
|
||||
|
||||
$this->view->module = 'citask';
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a request to jenkins to check build status.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function checkBuildStatus()
|
||||
{
|
||||
$this->citask->checkBuildStatus();
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
|
||||
$this->send(array('result' => 'success'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
$(function()
|
||||
{
|
||||
$('#' + module + 'Tab').addClass('btn-active-text');
|
||||
})
|
||||
@@ -1 +0,0 @@
|
||||
<?php
|
||||
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
$lang->citask->common = '构建任务';
|
||||
$lang->citask->browseBuild = '构建历史';
|
||||
$lang->citask->viewLogs = '构建日志';
|
||||
|
||||
$lang->citask->exeNow = '立即执行';
|
||||
$lang->citask->delete = '删除构建任务';
|
||||
$lang->citask->confirmDelete = '确认删除该构建任务吗?';
|
||||
|
||||
$lang->citask->buildStatus = '构建状态';
|
||||
$lang->citask->buildTime = '构建时间';
|
||||
|
||||
$lang->citask->id = 'ID';
|
||||
$lang->citask->name = '名称';
|
||||
$lang->citask->repo = '代码库';
|
||||
$lang->citask->jenkins = 'Jenkins服务';
|
||||
$lang->citask->jenkinsTask = 'Jenkins任务名';
|
||||
$lang->citask->buildType = '构建类型';
|
||||
$lang->citask->triggerType = '触发方式';
|
||||
$lang->citask->scheduleType = '时间计划';
|
||||
$lang->citask->cornExpression = 'Corn表达式';
|
||||
$lang->citask->custom = '自定义';
|
||||
|
||||
$lang->citask->tagKeywords = '标签关键字';
|
||||
$lang->citask->commentKeywords = '注释关键字';
|
||||
$lang->citask->extTask = '执行任务';
|
||||
|
||||
$lang->citask->at = '在';
|
||||
$lang->citask->time = '时间';
|
||||
$lang->citask->exe = '执行';
|
||||
$lang->citask->scheduleInterval = '每隔';
|
||||
$lang->citask->scheduleDay = '天数';
|
||||
$lang->citask->day = '天';
|
||||
$lang->citask->lastExe = '最后执行';
|
||||
$lang->citask->scheduleTime = '时间';
|
||||
|
||||
$lang->citask->example = '举例';
|
||||
$lang->citask->tagEx = 'build_#15,其中15为Jenkins任务编号';
|
||||
$lang->citask->commitEx = 'start build #15,其中15为Jenkins任务编号';
|
||||
$lang->citask->cronSample = '如 0 0 2 * * 2-6/1 表示每个工作日凌晨2点';
|
||||
|
||||
$lang->citask->buildStatus = array('success'=>'成功', 'fail'=>'失败', 'created'=>'新建', 'building'=>'构建中');
|
||||
$lang->citask->dayTypeList = array('workDay'=>'工作日', 'everyDay'=>'每天');
|
||||
$lang->citask->buildTypeList = array('build'=>'仅构建', 'buildAndDeploy'=>'构建部署', 'buildAndTest'=>'构建测试');
|
||||
$lang->citask->triggerTypeList = array('tag'=>'打标签', 'commit'=>'代码提交注释', 'schedule'=>'定时计划');
|
||||
$lang->citask->scheduleTypeList = array('cron'=>'Cron表达式', 'custom'=>'自定义');
|
||||
@@ -1,385 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The model file of ci task module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chenqi <chenqi@cnezsoft.com>
|
||||
* @package product
|
||||
* @version $Id: $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
|
||||
class citaskModel extends model
|
||||
{
|
||||
/**
|
||||
* Get a ci task by id.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getByID($id)
|
||||
{
|
||||
$jenkins = $this->dao->select('*')->from(TABLE_CI_TASK)->where('id')->eq($id)->fetch();
|
||||
return $jenkins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ci task list.
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @param bool $decode
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function listAll($orderBy = 'id_desc', $pager = null, $decode = true)
|
||||
{
|
||||
$list = $this->dao->
|
||||
select('t1.*, t2.name repoName, t3.name as jenkinsName')->from(TABLE_CI_TASK)->alias('t1')
|
||||
->leftJoin(TABLE_REPO)->alias('t2')->on('t1.repo=t2.id')
|
||||
->leftJoin(TABLE_JENKINS)->alias('t3')->on('t1.jenkins=t3.id')
|
||||
->where('t1.deleted')->eq('0')
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ci task.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$task = fixer::input('post')
|
||||
->add('createdBy', $this->app->user->account)
|
||||
->add('createdDate', helper::now())
|
||||
->get();
|
||||
|
||||
$this->dao->insert(TABLE_CI_TASK)->data($task)
|
||||
->batchCheck($this->config->citask->requiredFields, 'notempty')
|
||||
|
||||
->batchCheckIF($task->triggerType === 'schedule' && $task->scheduleType == 'cron', "cronExpression", 'notempty')
|
||||
->batchCheckIF($task->triggerType === 'schedule' && $task->scheduleType == 'custom', "scheduleDay,scheduleTime,scheduleInterval", 'notempty')
|
||||
|
||||
->autoCheck()
|
||||
->exec();
|
||||
|
||||
if ($task->triggerType === 'schedule') {
|
||||
$taskId = $this->dao->lastInsertID();
|
||||
|
||||
if ($task->scheduleType == 'custom') {
|
||||
$arr = explode(":", $task->scheduleTime);
|
||||
$hour = $arr[0];
|
||||
$min = $arr[1];
|
||||
|
||||
if ($task->scheduleDay == 'everyDay') {
|
||||
$days = '1-7';
|
||||
} else if ($task->scheduleDay == 'workDay') {
|
||||
$days = '1-5';
|
||||
}
|
||||
|
||||
$cron = (object)array('m' => $min, 'h' => $hour, 'dom' => '*', 'mon' => '*',
|
||||
'dow' => $days . '/' . $task->scheduleInterval, 'command' => 'moduleName=citask&methodName=exe&parm=' . $taskId,
|
||||
'remark' => ($this->lang->citask->extTask . $taskId), 'type' => 'zentao',
|
||||
'buildin' => '-1', 'status' => 'normal', 'lastTime' => '0000-00-00 00:00:00');
|
||||
$this->dao->insert(TABLE_CRON)->data($cron)->exec();
|
||||
} else if ($task->scheduleType == 'cron') {
|
||||
$arr = explode(' ', $task->cronExpression);
|
||||
if (count($arr) >= 6) {
|
||||
$cron = (object)array('m' => $arr[1], 'h' => $arr[2], 'dom' => $arr[3], 'mon' => $arr[4],
|
||||
'dow' => $arr[5], 'command' => 'moduleName=citask&methodName=exe&parm=' . $taskId,
|
||||
'remark' => ($this->lang->citask->extTask . $taskId), 'type' => 'zentao',
|
||||
'buildin' => '-1', 'status' => 'normal', 'lastTime' => '0000-00-00 00:00:00');
|
||||
$this->dao->insert(TABLE_CRON)->data($cron)->exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a ci task.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function update($id)
|
||||
{
|
||||
$task = fixer::input('post')
|
||||
->add('editedBy', $this->app->user->account)
|
||||
->add('editedDate', helper::now())
|
||||
->get();
|
||||
|
||||
$this->dao->update(TABLE_CI_TASK)->data($task)
|
||||
->batchCheck($this->config->citask->requiredFields, 'notempty')
|
||||
|
||||
->batchCheckIF($task->triggerType === 'schedule' && $task->scheduleType == 'cron', "cronExpression", 'notempty')
|
||||
->batchCheckIF($task->triggerType === 'schedule' && $task->scheduleType == 'custom', "scheduleDay,scheduleTime,scheduleInterval", 'notempty')
|
||||
|
||||
->autoCheck()
|
||||
->where('id')->eq($id)
|
||||
->exec();
|
||||
|
||||
if ($task->triggerType === 'schedule') {
|
||||
$command = 'moduleName=citask&methodName=exe&parm=' . $id;
|
||||
|
||||
if ($task->scheduleType == 'custom') {
|
||||
$arr = explode(":", $task->scheduleTime);
|
||||
$hour = $arr[0];
|
||||
$min = $arr[1];
|
||||
|
||||
$taskId = $this->dao->lastInsertID();
|
||||
if ($task->scheduleDay == 'everyDay') {
|
||||
$days = '1-7';
|
||||
} else if ($task->scheduleDay == 'workDay') {
|
||||
$days = '2-6';
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_CRON)
|
||||
->set('m')->eq($min)
|
||||
->set('h')->eq($hour)
|
||||
->set('dom')->eq('*')
|
||||
->set('mon')->eq('*')
|
||||
->set('dow')->eq($days . '/' . $task->scheduleInterval)
|
||||
->set('lastTime')->eq('0000-00-00 00:00:00')
|
||||
->where('command')->eq($command)->exec();
|
||||
} else if ($task->scheduleType == 'cron') {
|
||||
$arr = explode(' ', $task->cronExpression);
|
||||
if (count($arr) >= 6) {
|
||||
$this->dao->update(TABLE_CRON)
|
||||
->set('m')->eq($arr[1])
|
||||
->set('h')->eq($arr[2])
|
||||
->set('dom')->eq($arr[3])
|
||||
->set('mon')->eq($arr[4])
|
||||
->set('dow')->eq($arr[5])
|
||||
->set('lastTime')->eq('0000-00-00 00:00:00')
|
||||
->where('command')->eq($command)->exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute ci task.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function exe($taskID)
|
||||
{
|
||||
$po = $this->dao->select('task.id taskId, task.name taskName, task.repo, task.jenkinsTask, jenkins.name jenkinsName,jenkins.serviceUrl,jenkins.credentials')
|
||||
->from(TABLE_CI_TASK)->alias('task')
|
||||
->leftJoin(TABLE_JENKINS)->alias('jenkins')->on('task.jenkins=jenkins.id')
|
||||
->where('task.id')->eq($taskID)
|
||||
->fetch();
|
||||
|
||||
$credentials = $this->loadModel('cicredentials')->getByID($po->credentials); // jenkins must use a token or account credentials
|
||||
if ($credentials->type === 'token') {
|
||||
$jenkinsTokenOrPassword = $credentials->token;
|
||||
} else if ($credentials->type === 'account') {
|
||||
$jenkinsTokenOrPassword = $credentials->password;
|
||||
}
|
||||
$jenkinsUser = $credentials->username;
|
||||
$jenkinsServer = $po->serviceUrl;
|
||||
|
||||
$r = '://' . $jenkinsUser . ':' . $jenkinsTokenOrPassword . '@';
|
||||
$jenkinsServer = str_replace('://', $r, $jenkinsServer);
|
||||
$buildUrl = sprintf('%s/job/%s/build/api/json', $jenkinsServer, $po->jenkinsTask);
|
||||
|
||||
$po->queueItem = $this->sendBuildRequest($buildUrl);
|
||||
$this->saveCibuild($po);
|
||||
|
||||
return !dao::isError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get jenkins build list.
|
||||
*
|
||||
* @param int $taskID
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @param bool $decode
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function listBuild($taskID, $orderBy = 'id_desc', $pager = null, $decode = true)
|
||||
{
|
||||
$list = $this->dao->
|
||||
select('id, name, status, createdDate')->from(TABLE_CI_BUILD)
|
||||
->where('deleted')->eq('0')
|
||||
->andWhere('citask')->eq($taskID)
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get jenkins build logs.
|
||||
*
|
||||
* @param int $buildID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getBuild($buildID)
|
||||
{
|
||||
$build = $this->dao->select('*')->from(TABLE_CI_BUILD)->where('id')->eq($buildID)->fetch();
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save build to db.
|
||||
*
|
||||
* @param object $task
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function saveCibuild($task)
|
||||
{
|
||||
$build = new stdClass();
|
||||
$build->citask = $task->taskId;
|
||||
$build->name = $task->taskName;
|
||||
$build->queueItem = $task->queueItem;
|
||||
$build->status = 'created';
|
||||
$build->createdBy = $this->app->user->account;
|
||||
$build->createdDate = helper::now();
|
||||
|
||||
$this->dao->insert(TABLE_CI_BUILD)->data($build)->exec();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update ci build status.
|
||||
*
|
||||
* @param object $task
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function updateCibuildStatus($build, $status)
|
||||
{
|
||||
$this->dao->update(TABLE_CI_BUILD)->set('status')->eq($status)->where('id')->eq($build->id)->exec();
|
||||
|
||||
$this->dao->update(TABLE_CI_TASK)
|
||||
->set('lastExec')->eq(helper::now())
|
||||
->set('lastStatus')->eq($status)
|
||||
->where('id')->eq($build->citask)->exec();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a request to jenkins to check build status.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function checkBuildStatus()
|
||||
{
|
||||
$pos = $this->dao->select('build.*, task.jenkinsTask, jenkins.name jenkinsName,jenkins.serviceUrl,jenkins.credentials')
|
||||
->from(TABLE_CI_BUILD)->alias('build')
|
||||
->leftJoin(TABLE_CI_TASK)->alias('task')->on('build.citask=task.id')
|
||||
->leftJoin(TABLE_JENKINS)->alias('jenkins')->on('task.jenkins=jenkins.id')
|
||||
->where('build.status')->ne('success')
|
||||
->andWhere('build.status')->ne('fail')
|
||||
->fetchAll();
|
||||
|
||||
foreach($pos as $po) {
|
||||
$credentials = $this->loadModel('cicredentials')->getByID($po->credentials); // jenkins must use a token or account credentials
|
||||
if ($credentials->type === 'token') {
|
||||
$jenkinsTokenOrPassword = $credentials->token;
|
||||
} else if ($credentials->type === 'account') {
|
||||
$jenkinsTokenOrPassword = $credentials->password;
|
||||
}
|
||||
$jenkinsUser = $credentials->username;
|
||||
$jenkinsServer = $po->serviceUrl;
|
||||
|
||||
$r = '://' . $jenkinsUser . ':' . $jenkinsTokenOrPassword . '@';
|
||||
$jenkinsServer = str_replace('://', $r, $jenkinsServer);
|
||||
$queueUrl = sprintf('%s/queue/item/%s/api/json', $jenkinsServer, $po->queueItem);
|
||||
|
||||
$response = common::http($queueUrl);
|
||||
if (strripos($response,"404") > -1) { // queue已过期
|
||||
$infoUrl = sprintf('%s/job/%s/%s/api/json', $jenkinsServer, $po->jenkinsTask, $po->queueItem);
|
||||
$response = common::http($infoUrl);
|
||||
$buildInfo = json_decode($response);
|
||||
$result = strtolower($buildInfo->result);
|
||||
$this->updateCibuildStatus($po, $result);
|
||||
|
||||
$logUrl = sprintf('%s/job/%s/%s/consoleText', $jenkinsServer, $po->jenkinsTask, $po->queueItem);
|
||||
$response = common::http($logUrl);
|
||||
$logs = json_decode($response);
|
||||
|
||||
$this->dao->update(TABLE_CI_BUILD)->set('logs')->eq($response)->where('id')->eq($po->id)->exec();
|
||||
} else {
|
||||
$queueInfo = json_decode($response);
|
||||
|
||||
if (!empty($queueInfo->executable)) {
|
||||
$buildUrl = $queueInfo->executable->url . 'api/json?pretty=true';
|
||||
$buildUrl = str_replace('://', $r, $buildUrl);
|
||||
|
||||
$response = common::http($buildUrl);
|
||||
$buildInfo = json_decode($response);
|
||||
|
||||
if ($buildInfo->building) {
|
||||
$this->updateCibuildStatus($po, 'building');
|
||||
} else {
|
||||
$result = strtolower($buildInfo->result);
|
||||
$this->updateCibuildStatus($po, $result);
|
||||
|
||||
$logUrl = $buildInfo->url . 'logText/progressiveText/api/json';
|
||||
$logUrl = str_replace('://', $r, $logUrl);
|
||||
|
||||
$response = common::http($logUrl);
|
||||
$logs = json_decode($response);
|
||||
|
||||
$this->dao->update(TABLE_CI_BUILD)->set('logs')->eq($response)->where('id')->eq($po->id)->exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function sendBuildRequest($url)
|
||||
{
|
||||
if(!extension_loaded('curl')) return json_encode(array('result' => 'fail', 'message' => $lang->error->noCurlExt));
|
||||
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
|
||||
curl_setopt($curl, CURLOPT_USERAGENT, 'Sae T OAuth2 v0.1');
|
||||
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
|
||||
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
|
||||
curl_setopt($curl, CURLOPT_ENCODING, "");
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
|
||||
curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||||
curl_setopt($curl, CURLOPT_HEADER, FALSE);
|
||||
|
||||
$headers[] = "API-RemoteIP: " . $_SERVER['REMOTE_ADDR'];
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
|
||||
//
|
||||
curl_setopt ($curl , CURLOPT_HEADER, 1 );
|
||||
|
||||
curl_setopt($curl, CURLOPT_POST, true);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, new stdClass());
|
||||
|
||||
$response = curl_exec($curl);
|
||||
$errors = curl_error($curl);
|
||||
curl_close($curl);
|
||||
|
||||
if ( preg_match ( "!Location: .*item/(.*)/!", $response , $matches ) ) {
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -400,10 +400,7 @@ $lang->admin->subMenu->sso = new stdclass();
|
||||
$lang->admin->subMenu->sso->ranzhi = '然之协同|admin|sso';
|
||||
|
||||
$lang->admin->subMenu->sso->ci = array('link' => '持续集成|ci|index', 'subModule' => 'ci');
|
||||
$lang->admin->subMenu->sso->cicredentials = array('link' => '凭证|cicredentials|browse', 'subModule' => 'cicredentials');
|
||||
$lang->admin->subMenu->sso->cijenkins = array('link' => 'Jenkins|cijenkins|browse', 'subModule' => 'cijenkins');
|
||||
$lang->admin->subMenu->sso->cirepo = array('link' => '代码库|cirepo|browse', 'subModule' => 'cirepo');
|
||||
$lang->admin->subMenu->sso->citask = array('link' => '构建任务|citask|browse', 'subModule' => 'citask');
|
||||
$lang->admin->subMenu->sso->jenkins = array('link' => 'Jenkins|jenkins|browse', 'subModule' => 'jenkins');
|
||||
|
||||
$lang->admin->subMenu->dev = new stdclass();
|
||||
$lang->admin->subMenu->dev->api = array('link' => 'API|dev|api');
|
||||
@@ -434,10 +431,7 @@ $lang->message = new stdclass();
|
||||
$lang->search = new stdclass();
|
||||
|
||||
$lang->ci = new stdclass();
|
||||
$lang->cicredentials = new stdclass();
|
||||
$lang->cijenkins = new stdclass();
|
||||
$lang->cirepo = new stdclass();
|
||||
$lang->citask = new stdclass();
|
||||
$lang->jenkins = new stdclass();
|
||||
|
||||
$lang->convert->menu = $lang->admin->menu;
|
||||
$lang->upgrade->menu = $lang->admin->menu;
|
||||
@@ -453,10 +447,7 @@ $lang->webhook->menu = $lang->admin->menu;
|
||||
$lang->message->menu = $lang->admin->menu;
|
||||
|
||||
$lang->ci->menu = $lang->admin->menu;
|
||||
$lang->cicredentials->menu = $lang->admin->menu;
|
||||
$lang->cijenkins->menu = $lang->admin->menu;
|
||||
$lang->cirepo->menu = $lang->admin->menu;
|
||||
$lang->citask->menu = $lang->admin->menu;
|
||||
$lang->jenkins->menu = $lang->admin->menu;
|
||||
|
||||
/* 菜单分组。*/
|
||||
$lang->menugroup = new stdclass();
|
||||
@@ -494,10 +485,7 @@ $lang->menugroup->webhook = 'admin';
|
||||
$lang->menugroup->message = 'admin';
|
||||
|
||||
$lang->menugroup->ci = 'admin';
|
||||
$lang->menugroup->cicredentials = 'admin';
|
||||
$lang->menugroup->cijenkins = 'admin';
|
||||
$lang->menugroup->cirepo = 'admin';
|
||||
$lang->menugroup->citask = 'admin';
|
||||
$lang->menugroup->jenkins = 'admin';
|
||||
|
||||
/* 错误提示信息。*/
|
||||
$lang->error = new stdclass();
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* @version $Id: ${FILE_NAME} 5144 2020/1/8 8:10 下午 chenqi@cnezsoft.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
class cijenkins extends control
|
||||
class jenkins extends control
|
||||
{
|
||||
/**
|
||||
* cijenkins constructor.
|
||||
@@ -10,7 +10,7 @@
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
|
||||
class cijenkinsModel extends model
|
||||
class jenkinsModel extends model
|
||||
{
|
||||
/**
|
||||
* Get a jenkins by id.
|
||||
Reference in New Issue
Block a user