diff --git a/module/ci/config.php b/module/ci/config.php
deleted file mode 100644
index a8901822eb..0000000000
--- a/module/ci/config.php
+++ /dev/null
@@ -1,6 +0,0 @@
-job = new stdclass();
-$config->job->create = new stdclass();
-$config->job->create->requiredFields = 'name,repo,jenkins,jenkinsJob,triggerType';
-$config->job->edit = new stdclass();
-$config->job->edit->requiredFields = 'name,repo,jenkins,jenkinsJob,triggerType';
diff --git a/module/ci/control.php b/module/ci/control.php
index 2393bf3bb6..372ed52b0e 100644
--- a/module/ci/control.php
+++ b/module/ci/control.php
@@ -19,16 +19,7 @@ class ci extends control
public function __construct($moduleName = '', $methodName = '')
{
parent::__construct($moduleName, $methodName);
-
- $repoID = $this->session->repoID;
- foreach($this->lang->repo->menu as $key => $menu)
- {
- common::setMenuVars($this->lang->ci->menu, $key, $repoID);
- }
-
-// if(common::hasPriv('ci', 'createJob') and strpos(',browsejob,', $this->methodName) > -1) {
-// $this->lang->modulePageActions = html::a(helper::createLink('ci', 'createJob'), " " . $this->lang->ci->create, '', "class='btn btn-primary'");
-// }
+ $this->ci->setMenu();
}
/**
@@ -44,197 +35,6 @@ class ci extends control
$this->display();
}
- /**
- * Browse ci job.
- *
- * @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->jobList = $this->ci->listJob($orderBy, $pager);
-
- $this->view->title = $this->lang->ci->job . $this->lang->colon . $this->lang->ci->browse;
- $this->view->position[] = $this->lang->ci->job;
- $this->view->position[] = $this->lang->ci->browse;
-
- $this->view->orderBy = $orderBy;
- $this->view->pager = $pager;
- $this->view->method = 'browseJob';
-
- $this->display();
- }
-
- /**
- * Create a ci job.
- *
- * @access public
- * @return void
- */
- public function createJob()
- {
- if($_POST)
- {
- $this->ci->createJob();
- if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browseJob')));
- }
-
- $this->app->loadLang('action');
-
- $this->view->title = $this->lang->ci->job . $this->lang->colon . $this->lang->ci->create;
- $this->view->position[] = html::a(inlink('browseJob'), $this->lang->ci->job);
- $this->view->position[] = $this->lang->ci->create;
-
- $repoList = $this->loadModel('repo')->getAllRepos();
- $repoPairs = array(0 => '');
- $repoTypes = array();
- foreach($repoList as $repo)
- {
- $repoPairs[$repo->id] = $repo->name;
- $repoTypes[$repo->id] = $repo->SCM;
- }
- $this->view->repoPairs = $repoPairs;
- $this->view->repoTypes = $repoTypes;
- $this->view->jenkinsList = $this->loadModel('jenkins')->listForSelection("true");
-
- $this->display();
- }
-
- /**
- * Edit a ci job.
- *
- * @param int $id
- * @access public
- * @return void
- */
- public function editJob($id)
- {
- $job = $this->ci->getJobByID($id);
- if($_POST)
- {
- $this->ci->updateJob($id);
- if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browseJob')));
- }
-
- $this->app->loadLang('action');
-
- $this->view->title = $this->lang->ci->job . $this->lang->colon . $this->lang->ci->edit;
- $this->view->position[] = html::a(inlink('browseJob'), $this->lang->ci->job);
- $this->view->position[] = $this->lang->ci->edit;
-
- $repo = $this->loadModel('repo')->getRepoByID($job->repo);
- $repoList = $this->loadModel('repo')->getAllRepos();
- $repoPairs = array(0 => '', $repo->id => $repo->name);
- $repoTypes[$repo->id] = $repo->SCM;
- foreach($repoList as $repo)
- {
- $repoPairs[$repo->id] = $repo->name;
- $repoTypes[$repo->id] = $repo->SCM;
- }
-
- $this->view->repoPairs = $repoPairs;
- $this->view->repoTypes = $repoTypes;
- $this->view->job = $job;
- $this->view->jenkinsList = $this->loadModel('jenkins')->listForSelection("true");
-
- $this->display();
- }
-
- /**
- * Delete a ci job.
- *
- * @param int $id
- * @access public
- * @return void
- */
- public function deleteJob($id)
- {
- $this->ci->delete(TABLE_INTEGRATION, $id);
-
- $command = 'moduleName=ci&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 job.
- *
- * @param int $id
- * @access public
- * @return void
- */
- public function exeJob($id)
- {
- $result = $this->ci->exeJob($id);
- if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
- if(!$result) $this->send(array('result' => 'fail', 'message' => 'not found'));
-
- $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($jobID = 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->ci->listBuild($jobID, $orderBy, $pager);
- $this->view->job = $this->ci->getJobByID($jobID);
-
- $this->view->title = $this->lang->ci->job . $this->lang->colon . $this->lang->job->browseBuild;
- $this->view->position[] = html::a(inlink('browseJob'), $this->lang->ci->job);
- $this->view->position[] = $this->lang->job->browseBuild;
-
- $this->view->orderBy = $orderBy;
- $this->view->pager = $pager;
-
- $this->view->method = 'browseBuild';
- $this->display();
- }
-
- /**
- * View jenkins build logs.
- *
- * @param int $buildID
- * @access public
- * @return void
- */
- public function viewBuildLogs($buildID)
- {
- $build = $this->ci->getBuildByID($buildID);
- $this->view->logs = str_replace("\r\n","
", $build->logs);
- $this->view->build = $build;
-
- $this->view->title = $this->lang->ci->job . $this->lang->colon . $this->lang->job->viewLogs;
- $this->view->position[] = html::a(inlink('browseJob'), $this->lang->ci->job);
- $this->view->position[] = html::a(inlink('browseBuild', "jobID=" . $build->cijob), $this->lang->job->browseBuild);
- $this->view->position[] = $this->lang->job->viewLogs;
-
- $this->view->module = 'ci';
- $this->display();
- }
-
/**
* Send a request to jenkins to check build status.
*
@@ -248,5 +48,4 @@ class ci extends control
$this->send(array('result' => 'success'));
}
-
}
diff --git a/module/ci/lang/en.php b/module/ci/lang/en.php
index 7a337710a7..5c582d0e66 100644
--- a/module/ci/lang/en.php
+++ b/module/ci/lang/en.php
@@ -1,50 +1,6 @@
ci->common = 'CI';
-$lang->ci->at = ' at ';
-
-$lang->ci->jenkins = 'Jenkins';
-$lang->ci->repo = 'Repo';
-$lang->ci->job = 'Job';
-$lang->ci->task = 'Job';
-$lang->ci->history = 'Build';
-$lang->ci->browse = 'View';
-$lang->ci->create = 'Create';
-$lang->ci->edit = 'Edit';
-
-$lang->job->browseBuild = 'Build Histories';
-$lang->job->viewLogs = 'Build Logs';
-
-$lang->job->exeNow = 'Execute now';
-$lang->job->delete = 'Delete';
-$lang->job->confirmDelete = 'Do you want to delete this Build?';
-
-$lang->job->buildStatus = 'Build Status';
-$lang->job->buildTime = 'Build Time';
-
-$lang->job->id = 'ID';
-$lang->job->name = 'Name';
-$lang->job->repo = 'Repo';
-$lang->job->svnFolder = 'SVN Tag Watch Path';
-$lang->job->jenkins = 'Jenkins Server';
-$lang->job->jenkinsJob = 'Jenkins Task';
-$lang->job->triggerType = 'Trigger';
-$lang->job->scheduleType = 'Schedule';
-$lang->job->cronExpression = 'Cron Expression';
-$lang->job->custom = 'Custom';
-
-$lang->job->at = 'executed on';
-$lang->job->exe = '';
-$lang->job->scheduleInterval = 'Every';
-$lang->job->day = 'days';
-$lang->job->lastExe = 'Last Executed';
-$lang->job->scheduleTime = 'Time';
-
-$lang->job->example = 'e.g.';
-$lang->job->tagEx = 'build_#15, to build Jenkins job that id is 15.';
-$lang->job->commitEx = 'start build #15, to build Jenkins job that id is 15.';
-$lang->job->cronSample = 'e.g. 0 0 2 * * 2-6/1 means 2:00 a.m. every weekday.';
-
-$lang->job->buildStatusList = array('success' => 'Success', 'fail' => 'Fail', 'created' => 'Created', 'building' => 'Building', 'create_fail' => 'Fail to create', 'timeout' => 'Exec Timeout');
-$lang->job->dayTypeList = array('workDay' => 'Weekdays', 'everyDay' => 'Every Day');
-$lang->job->triggerTypeList = array('tag' => 'Tag', 'commit' => 'Code Commit', 'schedule' => 'Schedule');
-$lang->job->scheduleTypeList = array('cron' => 'Crontab', 'custom' => 'Custom');
+$lang->ci->common = 'CI';
+$lang->ci->at = ' at ';
+$lang->ci->job = 'Job';
+$lang->ci->task = 'Job';
+$lang->ci->history = 'Build';
diff --git a/module/ci/lang/zh-cn.php b/module/ci/lang/zh-cn.php
index d50872d519..6c0280971f 100644
--- a/module/ci/lang/zh-cn.php
+++ b/module/ci/lang/zh-cn.php
@@ -1,55 +1,6 @@
ci->common = '持续集成';
-$lang->ci->at = '于';
-
-$lang->ci->jenkins = 'Jenkins';
-$lang->ci->repo = '版本库';
-$lang->ci->job = '构建';
-$lang->ci->task = '任务';
-$lang->ci->history = '历史';
-$lang->ci->browse = '浏览';
-$lang->ci->create = '创建';
-$lang->ci->edit = '编辑';
-
-$lang->job = new stdclass();
-$lang->job->browseBuild = '构建历史';
-$lang->job->viewLogs = '构建日志';
-
-$lang->job->create = '创建构建任务';
-$lang->job->edit = '编辑构建任务';
-$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->svnFolder = 'SVN Tag监控路径';
-$lang->job->jenkins = 'Jenkins服务';
-$lang->job->buildType = '构建类型';
-$lang->job->jenkinsJob = 'Jenkins任务名';
-$lang->job->triggerType = '触发方式';
-$lang->job->scheduleType = '时间计划';
-$lang->job->cronExpression = 'Cron表达式';
-$lang->job->custom = '自定义';
-
-$lang->job->at = '在';
-$lang->job->time = '时间';
-$lang->job->exe = '执行';
-$lang->job->scheduleInterval = '每隔';
-$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->buildStatusList = array('success' => '成功', 'fail' => '失败', 'created' => '新建', 'building' => '构建中', 'create_fail' => '创建失败', 'timeout' => '执行超时');
-$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' => 'Crontab', 'custom' => '自定义');
+$lang->ci->common = '持续集成';
+$lang->ci->at = '于';
+$lang->ci->job = '构建';
+$lang->ci->task = '任务';
+$lang->ci->history = '历史';
diff --git a/module/ci/model.php b/module/ci/model.php
index fb82aebf27..4a34fab5ce 100644
--- a/module/ci/model.php
+++ b/module/ci/model.php
@@ -1,9 +1,6 @@
* @package product
* @version $Id: $
@@ -12,238 +9,18 @@
class ciModel extends model
{
-
/**
- * Get ci job list.
- *
- * @param string $orderBy
- * @param object $pager
- * @param bool $decode
+ * Set menu.
+ *
* @access public
- * @return array
+ * @return void
*/
- public function listJob($orderBy = 'id_desc', $pager = null, $decode = true)
+ public function setMenu()
{
- $list = $this->dao->
- select('t1.*, t2.name repoName, t3.name as jenkinsName')->from(TABLE_INTEGRATION)->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 job by id.
- *
- * @param int $id
- * @access public
- * @return object
- */
- public function getJobByID($id)
- {
- $jenkins = $this->dao->select('*')->from(TABLE_INTEGRATION)->where('id')->eq($id)->fetch();
- return $jenkins;
- }
-
- /**
- * Create a ci job.
- *
- * @access public
- * @return bool
- */
- public function createJob()
- {
- $job = fixer::input('post')
- ->add('createdBy', $this->app->user->account)
- ->add('createdDate', helper::now())
- ->remove('repoType')
- ->get();
-
- $this->dao->insert(TABLE_INTEGRATION)->data($job)
- ->batchCheck($this->config->job->create->requiredFields, 'notempty')
-
- ->batchCheckIF($job->triggerType === 'schedule' && $job->scheduleType == 'cron', "cronExpression", 'notempty')
- ->batchCheckIF($job->triggerType === 'schedule' && $job->scheduleType == 'custom', "scheduleDay,scheduleTime,scheduleInterval", 'notempty')
- ->batchCheckIF($this->post->repoType == 'Subversion', "svnFolder", 'notempty')
-
- ->autoCheck()
- ->exec();
-
- $jobId = $this->dao->lastInsertID();
- if($job->triggerType =='schedule')
- {
- $arr = explode(":", $job->scheduleTime);
- $hour = $arr[0];
- $min = $arr[1];
-
- if($job->scheduleDay == 'everyDay')
- {
- $days = '1-7';
- }
- elseif($job->scheduleDay == 'workDay')
- {
- $days = '1-5';
- }
-
- $cron = (object)array('m' => $min, 'h' => $hour, 'dom' => '*', 'mon' => '*',
- 'dow' => $days . '/' . $job->scheduleInterval, 'command' => 'moduleName=ci&methodName=exeJob&parm=' . $jobId,
- 'remark' => ($this->lang->ci->extJob . $jobId), '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 job.
- *
- * @param int $id
- * @access public
- * @return bool
- */
- public function updateJob($id)
- {
- $job = fixer::input('post')
- ->add('editedBy', $this->app->user->account)
- ->add('editedDate', helper::now())
- ->remove('repoType')
- ->get();
-
- $this->dao->update(TABLE_INTEGRATION)->data($job)
- ->batchCheck($this->config->job->edit->requiredFields, 'notempty')
-
- ->batchCheckIF($job->triggerType === 'schedule' && $job->scheduleType == 'cron', "cronExpression", 'notempty')
- ->batchCheckIF($job->triggerType === 'schedule' && $job->scheduleType == 'custom', "scheduleDay,scheduleTime,scheduleInterval", 'notempty')
- ->batchCheckIF($this->post->repoType == 'Subversion', "svnFolder", 'notempty')
-
- ->autoCheck()
- ->where('id')->eq($id)
- ->exec();
-
- if ($job->triggerType === 'schedule')
- {
- $command = 'moduleName=ci&methodName=exeJob&parm=' . $id;
-
- $arr = explode(":", $job->scheduleTime);
- $hour = $arr[0];
- $min = $arr[1];
-
- if($job->scheduleDay == 'everyDay')
- {
- $days = '1-7';
- }
- elseif($job->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 . '/' . $job->scheduleInterval)
- ->set('lastTime')->eq('0000-00-00 00:00:00')
- ->where('command')->eq($command)->exec();
- }
-
- return true;
- }
-
- /**
- * Execute ci job.
- *
- * @param int $id
- * @access public
- * @return bool
- */
- public function exeJob($jobID)
- {
- $job = $this->dao->select('job.id jobId, job.name jobName, job.repo, job.jenkinsJob, jenkins.name jenkinsName,jenkins.serviceUrl,jenkins.account,jenkins.token,jenkins.password')
- ->from(TABLE_INTEGRATION)->alias('job')
- ->leftJoin(TABLE_JENKINS)->alias('jenkins')->on('job.jenkins=jenkins.id')
- ->where('job.id')->eq($jobID)
- ->fetch();
-
- if (!$job) return false;
-
- $jenkinsServer = $po->serviceUrl;
- $jenkinsUser = $po->account;
- $jenkinsTokenOrPassword = $po->token ? $po->token : base64_decode($po->password);
-
- $r = '://' . $jenkinsUser . ':' . $jenkinsTokenOrPassword . '@';
- $jenkinsServer = str_replace('://', $r, $jenkinsServer);
- $buildUrl = sprintf('%s/job/%s/build/api/json', $jenkinsServer, $po->jenkinsJob);
-
- $po->queueItem = $this->sendBuildRequest($buildUrl);
- $this->saveBuild($po);
-
- return !dao::isError();
- }
-
- /**
- * Get jenkins build list.
- *
- * @param int $jobID
- * @param string $orderBy
- * @param object $pager
- * @param bool $decode
- * @access public
- * @return array
- */
- public function listBuild($jobID, $orderBy = 'id_desc', $pager = null, $decode = true)
- {
- $list = $this->dao->
- select('build.id, build.name, build.status, build.createdDate, job.triggerType, repo.name repoName, jenkins.name as jenkinsName')
- ->from(TABLE_COMPILE)->alias('build')
- ->leftJoin(TABLE_INTEGRATION)->alias('job')->on('build.cijob=job.id')
- ->leftJoin(TABLE_REPO)->alias('repo')->on('job.repo=repo.id')
- ->leftJoin(TABLE_JENKINS)->alias('jenkins')->on('job.jenkins=jenkins.id')
-
- ->where('build.deleted')->eq('0')
- ->andWhere('build.cijob')->eq($jobID)
- ->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_COMPILE)->where('id')->eq($buildID)->fetch();
- return $build;
- }
-
- /**
- * Save build to db.
- *
- * @param object $job
- * @access public
- * @return bool
- */
- public function saveBuild($job)
- {
- $build = new stdClass();
- $build->cijob = $job->jobId;
- $build->name = $job->jobName;
- $build->queueItem = $job->queueItem;
- $build->status = $job->queueItem ? 'created' : 'create_fail';
- $build->createdBy = $this->app->user->account;
- $build->createdDate = helper::now();
-
- $this->dao->insert(TABLE_COMPILE)->data($build)->exec();
+ $repoID = $this->session->repoID;
+ $moduleName = $this->app->getModuleName();
+ foreach($this->lang->{$moduleName}->menu as $key => $menu) common::setMenuVars($this->lang->{$moduleName}->menu, $key, $repoID);
+ $this->lang->{$moduleName}->menuOrder = $this->lang->ci->menuOrder;
}
/**
@@ -264,17 +41,18 @@ class ciModel extends model
->andWhere('build.createdDate')->gt(date(DT_DATETIME1, strtotime("-1 day")))
->fetchAll();
- foreach($pos as $po) {
- $jenkinsServer = $po->serviceUrl;
- $jenkinsUser = $po->account;
- $jenkinsTokenOrPassword = $po->token ? $po->token : base64_decode($po->password);
+ foreach($pos as $po)
+ {
+ $jenkinsServer = $po->serviceUrl;
+ $jenkinsUser = $po->account;
+ $jenkinsPassword = $po->token ? $po->token : base64_decode($po->password);
- $r = '://' . $jenkinsUser . ':' . $jenkinsTokenOrPassword . '@';
- $jenkinsServer = str_replace('://', $r, $jenkinsServer);
+ $jenkinsAuth = '://' . $jenkinsUser . ':' . $jenkinsTokenOrPassword . '@';
+ $jenkinsServer = str_replace('://', $jenkinsAuth, $jenkinsServer);
$queueUrl = sprintf('%s/queue/item/%s/api/json', $jenkinsServer, $po->queueItem);
$response = common::http($queueUrl);
- if (strripos($response,"404") > -1)
+ if(strripos($response, "404") > -1)
{ // queue expired, use another api
$infoUrl = sprintf('%s/job/%s/%s/api/json', $jenkinsServer, $po->jenkinsJob, $po->queueItem);
$response = common::http($infoUrl);
@@ -287,20 +65,25 @@ class ciModel extends model
$logs = json_decode($response);
$this->dao->update(TABLE_COMPILE)->set('logs')->eq($response)->where('id')->eq($po->id)->exec();
- } else
- {
+ }
+ else
+ {
$queueInfo = json_decode($response);
- if (!empty($queueInfo->executable)) {
+ 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) {
+ if($buildInfo->building)
+ {
$this->updateBuildStatus($po, 'building');
- } else {
+ }
+ else
+ {
$result = strtolower($buildInfo->result);
$this->updateBuildStatus($po, $result);
@@ -332,47 +115,20 @@ class ciModel extends model
$this->dao->update(TABLE_INTEGRATION)
->set('lastExec')->eq(helper::now())
->set('lastStatus')->eq($status)
- ->where('id')->eq($build->cijob)->exec();
+ ->where('id')->eq($build->cijob)
+ ->exec();
}
/**
* @param $url
* @return false|mixed|string
*/
- public function sendBuildRequest($url) // not to use common http
- {
- if(!extension_loaded('curl')) return json_encode(array('result' => 'fail', 'message' => $this->lang->error->noCurlExt));
+ public function sendRequest($url, $data)
+ {
+ if(!empty($data->PARAM_TAG)) $data->PARAM_REVISION = '';
- $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 '';
- }
+ $response = common::http($url, $data, true);
+ if(preg_match("!Location: .*item/(.*)/!", $response, $matches)) return $matches[1];
+ return '';
+ }
}
diff --git a/module/ci/view/browsebuild.html.php b/module/ci/view/browsebuild.html.php
deleted file mode 100644
index 1f30abd80a..0000000000
--- a/module/ci/view/browsebuild.html.php
+++ /dev/null
@@ -1,83 +0,0 @@
-
- * @package ci
- * @version $Id$
- * @link http://www.zentao.net
- */
-?>
-
-
-
-
- inlink('browsejob', ""), "{$lang->ci->task}", '', "class='btn btn-link" . ('browseJob' == $method ? ' btn-active-text' : '') . "'");
- echo html::a($this->inlink('browsebuild', ""), "{$lang->ci->history}", '', "class='btn btn-link" . ('browseBuild' == $method ? ' btn-active-text' : '') . "'");
- ?>
-
-
- " . $lang->ci->create, '', "class='btn btn-primary'");
- }
- ?>
-
-
-
-
-
diff --git a/module/ci/view/browsejob.html.php b/module/ci/view/browsejob.html.php
deleted file mode 100644
index a64db7d3f2..0000000000
--- a/module/ci/view/browsejob.html.php
+++ /dev/null
@@ -1,94 +0,0 @@
-
- * @package ci
- * @version $Id$
- * @link http://www.zentao.net
- */
-?>
-
-job->confirmDelete); ?>
-
-
-
- inlink('browsejob', ""), "{$lang->ci->task}", '', "class='btn btn-link" . ('browseJob' == $method ? ' btn-active-text' : '') . "'");
- echo html::a($this->inlink('browsebuild', ""), "{$lang->ci->history}", '', "class='btn btn-link" . ('browseBuild' == $method ? ' btn-active-text' : '') . "'");
- ?>
-
-
- " . $lang->ci->create, '', "class='btn btn-primary'");
- }
- ?>
-
-
-
-
-
diff --git a/module/ci/view/viewbuildlogs.html.php b/module/ci/view/viewbuildlogs.html.php
deleted file mode 100644
index 331c23a687..0000000000
--- a/module/ci/view/viewbuildlogs.html.php
+++ /dev/null
@@ -1,33 +0,0 @@
-
- * @package ci
- * @version $Id$
- * @link http://www.zentao.net
- */
-?>
-
-
-
-
-
- cijob"), " ". $lang->goback, '', "class='btn btn-secondary'");?>
-
-
-
-
-
diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php
index c5edc99894..4b59803caa 100644
--- a/module/common/lang/zh-cn.php
+++ b/module/common/lang/zh-cn.php
@@ -335,14 +335,18 @@ $lang->caselib->menu->caselib = array('link' => '用例库|caselib|browse|libI
$lang->ci = new stdclass();
$lang->ci->menu = new stdclass();
$lang->ci->menu->browse = array('link' =>'浏览|repo|browse|repoID=%s', 'alias' => 'diff,view,revision,log,blame,showsynccomment');
-$lang->ci->menu->job = array('link' =>'构建|ci|browsejob', 'alias' => 'createjob,editjob,browsebuild,viewbuildlogs');
+$lang->ci->menu->job = array('link' =>'构建|integration|browse', 'subModule' => 'compile,integration');
$lang->ci->menu->maintain = array('link' =>'版本库|repo|maintain', 'alias' => 'create,edit');
$lang->ci->menu->jenkins = array('link' =>'Jenkins|jenkins|browse', 'alias' => 'create,edit');
-$lang->repo = new stdclass();
-$lang->jenkins = new stdclass();
-$lang->repo->menu = $lang->ci->menu;
-$lang->jenkins->menu = $lang->ci->menu;
+$lang->repo = new stdclass();
+$lang->jenkins = new stdclass();
+$lang->compile = new stdclass();
+$lang->integration = new stdclass();
+$lang->repo->menu = $lang->ci->menu;
+$lang->jenkins->menu = $lang->ci->menu;
+$lang->compile->menu = $lang->ci->menu;
+$lang->integration->menu = $lang->ci->menu;
/* 文档视图菜单设置。*/
$lang->doc = new stdclass();
@@ -484,6 +488,8 @@ $lang->menugroup->message = 'admin';
$lang->menugroup->repo = 'ci';
$lang->menugroup->jenkins = 'ci';
+$lang->menugroup->compile = 'ci';
+$lang->menugroup->integration = 'ci';
/* 错误提示信息。*/
$lang->error = new stdclass();
diff --git a/module/common/model.php b/module/common/model.php
index f52c05bab7..81d73d047f 100644
--- a/module/common/model.php
+++ b/module/common/model.php
@@ -1820,7 +1820,7 @@ EOD;
* @access public
* @return string
*/
- public static function http($url, $data = null)
+ public static function http($url, $data = null, $optHeader = false)
{
global $lang, $app;
if(!extension_loaded('curl')) return json_encode(array('result' => 'fail', 'message' => $lang->error->noCurlExt));
@@ -1841,6 +1841,7 @@ EOD;
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
+ if($optHeader) curl_setopt($curl, CURLOPT_HEADER, true);
if(!empty($data))
{
curl_setopt($curl, CURLOPT_POST, true);
diff --git a/module/compile/control.php b/module/compile/control.php
new file mode 100644
index 0000000000..054b5879b6
--- /dev/null
+++ b/module/compile/control.php
@@ -0,0 +1,74 @@
+
+ * @package compile
+ * @version $Id$
+ * @link http://www.zentao.net
+ */
+class compile extends control
+{
+ /**
+ * Construct
+ *
+ * @param string $moduleName
+ * @param string $methodName
+ * @access public
+ * @return void
+ */
+ public function __construct($moduleName = '', $methodName = '')
+ {
+ parent::__construct($moduleName, $methodName);
+ $this->loadModel('ci')->setMenu();
+ }
+
+ /**
+ * Browse jenkins build.
+ *
+ * @param string $orderBy
+ * @param int $recTotal
+ * @param int $recPerPage
+ * @param int $pageID
+ * @access public
+ * @return void
+ */
+ public function browse($jobID = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
+ {
+ $this->app->loadClass('pager', $static = true);
+ $pager = new pager($recTotal, $recPerPage, $pageID);
+
+ $this->view->title = $this->lang->ci->job . $this->lang->colon . $this->lang->compile->browse;
+ $this->view->position[] = html::a($this->createLink('integration', 'browse'), $this->lang->ci->job);
+ $this->view->position[] = $this->lang->compile->browse;
+
+ $this->view->buildList = $this->compile->getList($jobID, $orderBy, $pager);
+ $this->view->job = $this->loadModel('integration')->getByID($jobID);
+ $this->view->orderBy = $orderBy;
+ $this->view->pager = $pager;
+ $this->display();
+ }
+
+ /**
+ * View jenkins build logs.
+ *
+ * @param int $buildID
+ * @access public
+ * @return void
+ */
+ public function logs($buildID)
+ {
+ $build = $this->compile->getByID($buildID);
+ $this->view->logs = str_replace("\r\n","
", $build->logs);
+ $this->view->build = $build;
+
+ $this->view->title = $this->lang->ci->job . $this->lang->colon . $this->lang->compile->logs;
+ $this->view->position[] = html::a($this->createLink('integration', 'browse'), $this->lang->ci->job);
+ $this->view->position[] = html::a($this->createLink('compile', 'browse', "jobID=" . $build->cijob), $this->lang->compile->browse);
+ $this->view->position[] = $this->lang->compile->logs;
+ $this->display();
+ }
+}
+
diff --git a/module/compile/lang/en.php b/module/compile/lang/en.php
new file mode 100644
index 0000000000..0f81e70164
--- /dev/null
+++ b/module/compile/lang/en.php
@@ -0,0 +1,15 @@
+compile->browse = 'Build Histories';
+$lang->compile->logs = 'Build Logs';
+
+$lang->compile->id = 'ID';
+$lang->compile->name = 'Name';
+$lang->compile->status = 'Build Status';
+$lang->compile->time = 'Build Time';
+
+$lang->compile->statusList['success'] = 'Success';
+$lang->compile->statusList['fail'] = 'Fail';
+$lang->compile->statusList['created'] = 'Created';
+$lang->compile->statusList['building'] = 'Building';
+$lang->compile->statusList['create_fail'] = 'Fail to create';
+$lang->compile->statusList['timeout'] = 'Exec Timeout';
diff --git a/module/compile/lang/zh-cn.php b/module/compile/lang/zh-cn.php
new file mode 100644
index 0000000000..2766e54c60
--- /dev/null
+++ b/module/compile/lang/zh-cn.php
@@ -0,0 +1,15 @@
+compile->browse = '构建历史';
+$lang->compile->logs = '构建日志';
+
+$lang->compile->id = 'ID';
+$lang->compile->name = '名称';
+$lang->compile->status = '构建状态';
+$lang->compile->time = '构建时间';
+
+$lang->compile->statusList['success'] = '成功';
+$lang->compile->statusList['fail'] = '失败';
+$lang->compile->statusList['created'] = '新建';
+$lang->compile->statusList['building'] = '构建中';
+$lang->compile->statusList['create_fail'] = '创建失败';
+$lang->compile->statusList['timeout'] = '执行超时';
diff --git a/module/compile/model.php b/module/compile/model.php
new file mode 100644
index 0000000000..7c14e7d66e
--- /dev/null
+++ b/module/compile/model.php
@@ -0,0 +1,67 @@
+
+ * @package compile
+ * @version $Id$
+ * @link http://www.zentao.net
+ */
+class compileModel extends model
+{
+ /**
+ * Get build list.
+ *
+ * @param int $jobID
+ * @param string $orderBy
+ * @param object $pager
+ * @access public
+ * @return array
+ */
+ public function getList($jobID, $orderBy = 'id_desc', $pager = null)
+ {
+ return $this->dao->select('t1.id, t1.name, t1.status, t1.createdDate, t2.triggerType, t3.name as repoName, t4.name as jenkinsName')->from(TABLE_COMPILE)->alias('t1')
+ ->leftJoin(TABLE_INTEGRATION)->alias('t2')->on('t1.cijob=t2.id')
+ ->leftJoin(TABLE_REPO)->alias('t3')->on('t2.repo=t3.id')
+ ->leftJoin(TABLE_JENKINS)->alias('t4')->on('t2.jenkins=t4.id')
+ ->where('t1.deleted')->eq('0')
+ ->andWhere('t1.cijob')->eq($jobID)
+ ->orderBy($orderBy)
+ ->page($pager)
+ ->fetchAll('id');
+ }
+
+ /**
+ * Get by id
+ *
+ * @param int $buildID
+ * @access public
+ * @return object
+ */
+ public function getByID($buildID)
+ {
+ return $this->dao->select('*')->from(TABLE_COMPILE)->where('id')->eq($buildID)->fetch();
+ }
+
+ /**
+ * Save build by job
+ *
+ * @param object $job
+ * @access public
+ * @return void
+ */
+ public function saveBuild($job)
+ {
+ $build = new stdClass();
+ $build->cijob = $job->jobId;
+ $build->name = $job->jobName;
+ $build->queueItem = $job->queueItem;
+ $build->status = $job->queueItem ? 'created' : 'create_fail';
+ $build->createdBy = $this->app->user->account;
+ $build->createdDate = helper::now();
+
+ $this->dao->insert(TABLE_COMPILE)->data($build)->exec();
+ }
+}
diff --git a/module/compile/view/browse.html.php b/module/compile/view/browse.html.php
new file mode 100644
index 0000000000..d4e8477276
--- /dev/null
+++ b/module/compile/view/browse.html.php
@@ -0,0 +1,63 @@
+
+ * @package compile
+ * @version $Id$
+ * @link http://www.zentao.net
+ */
+?>
+
+
+
+ createLink('integration', 'browse'), "{$lang->ci->task}", '', "class='btn btn-link'");
+ echo html::a($this->createLink('compile', 'browse'), "{$lang->ci->history}", '', "class='btn btn-link btn-active-text'");
+ ?>
+
+
+
+
+
diff --git a/module/compile/view/logs.html.php b/module/compile/view/logs.html.php
new file mode 100644
index 0000000000..7a0e262e81
--- /dev/null
+++ b/module/compile/view/logs.html.php
@@ -0,0 +1,27 @@
+
+ * @package compile
+ * @version $Id$
+ * @link http://www.zentao.net
+ */
+?>
+
+
+
+
+ cijob"), " ". $lang->goback, '', "class='btn btn-secondary'");?>
+
+
+
+
diff --git a/module/integration/config.php b/module/integration/config.php
new file mode 100644
index 0000000000..dd9ddf2640
--- /dev/null
+++ b/module/integration/config.php
@@ -0,0 +1,6 @@
+integration = new stdclass();
+$config->integration->create = new stdclass();
+$config->integration->edit = new stdclass();
+$config->integration->create->requiredFields = 'name,repo,jenkins,jenkinsJob,triggerType';
+$config->integration->edit->requiredFields = 'name,repo,jenkins,jenkinsJob,triggerType';
diff --git a/module/integration/control.php b/module/integration/control.php
new file mode 100644
index 0000000000..efc38e4692
--- /dev/null
+++ b/module/integration/control.php
@@ -0,0 +1,169 @@
+
+ * @package integration
+ * @version $Id$
+ * @link http://www.zentao.net
+ */
+class integration extends control
+{
+ /**
+ * Construct
+ *
+ * @param string $moduleName
+ * @param string $methodName
+ * @access public
+ * @return void
+ */
+ public function __construct($moduleName = '', $methodName = '')
+ {
+ parent::__construct($moduleName, $methodName);
+ $this->loadModel('ci')->setMenu();
+ }
+
+ /**
+ * Browse ci job.
+ *
+ * @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->app->loadLang('compile');
+ $this->view->jobList = $this->integration->getList($orderBy, $pager);
+
+ $this->view->title = $this->lang->ci->job . $this->lang->colon . $this->lang->integration->browse;
+ $this->view->position[] = $this->lang->ci->job;
+ $this->view->position[] = $this->lang->integration->browse;
+
+ $this->view->orderBy = $orderBy;
+ $this->view->pager = $pager;
+ $this->display();
+ }
+
+ /**
+ * Create a ci job.
+ *
+ * @access public
+ * @return void
+ */
+ public function create()
+ {
+ if($_POST)
+ {
+ $this->integration->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->job . $this->lang->colon . $this->lang->integration->create;
+ $this->view->position[] = html::a(inlink('browse'), $this->lang->ci->job);
+ $this->view->position[] = $this->lang->integration->create;
+
+ $repoList = $this->loadModel('repo')->getAllRepos();
+ $repoPairs = array(0 => '');
+ $repoTypes = array();
+ foreach($repoList as $repo)
+ {
+ $repoPairs[$repo->id] = $repo->name;
+ $repoTypes[$repo->id] = $repo->SCM;
+ }
+ $this->view->repoPairs = $repoPairs;
+ $this->view->repoTypes = $repoTypes;
+ $this->view->jenkinsList = $this->loadModel('jenkins')->getPairs();
+
+ $this->display();
+ }
+
+ /**
+ * Edit a ci job.
+ *
+ * @param int $id
+ * @access public
+ * @return void
+ */
+ public function edit($id)
+ {
+ $job = $this->integration->getByID($id);
+ if($_POST)
+ {
+ $this->integration->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->job . $this->lang->colon . $this->lang->integration->edit;
+ $this->view->position[] = html::a(inlink('browse'), $this->lang->ci->job);
+ $this->view->position[] = $this->lang->integration->edit;
+
+ $repo = $this->loadModel('repo')->getRepoByID($job->repo);
+ $repoList = $this->loadModel('repo')->getAllRepos();
+ $repoPairs = array(0 => '', $repo->id => $repo->name);
+ $repoTypes[$repo->id] = $repo->SCM;
+ foreach($repoList as $repo)
+ {
+ $repoPairs[$repo->id] = $repo->name;
+ $repoTypes[$repo->id] = $repo->SCM;
+ }
+
+ $this->view->repoPairs = $repoPairs;
+ $this->view->repoTypes = $repoTypes;
+ $this->view->job = $job;
+ $this->view->jenkinsList = $this->loadModel('jenkins')->getPairs();
+
+ $this->display();
+ }
+
+ /**
+ * Delete a ci job.
+ *
+ * @param int $id
+ * @access public
+ * @return void
+ */
+ public function delete($id, $confirm = 'no')
+ {
+ if($confirm != 'yes')
+ {
+ die(js::confirm($this->lang->integration->confirmDelete, inlink('delete', "jobID=$id&confirm=yes")));
+ }
+
+ $this->integration->delete(TABLE_INTEGRATION, $id);
+
+ $command = 'moduleName=ci&methodName=exe&parm=' . $id;
+ $this->dao->delete()->from(TABLE_CRON)->where('command')->eq($command)->exec();
+
+ die(js::reload('parent'));
+ }
+
+ /**
+ * Exec a ci job.
+ *
+ * @param int $id
+ * @access public
+ * @return void
+ */
+ public function exec($id)
+ {
+ $result = $this->integration->exec($id);
+ if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
+ if(!$result) $this->send(array('result' => 'fail', 'message' => 'not found'));
+
+ $this->send(array('result' => 'success'));
+ }
+}
diff --git a/module/ci/css/createJob.css b/module/integration/css/create.css
similarity index 100%
rename from module/ci/css/createJob.css
rename to module/integration/css/create.css
diff --git a/module/ci/css/editJob.css b/module/integration/css/edit.css
similarity index 100%
rename from module/ci/css/editJob.css
rename to module/integration/css/edit.css
diff --git a/module/ci/js/createjob.js b/module/integration/js/create.js
similarity index 100%
rename from module/ci/js/createjob.js
rename to module/integration/js/create.js
diff --git a/module/ci/js/editjob.js b/module/integration/js/edit.js
similarity index 97%
rename from module/ci/js/editjob.js
rename to module/integration/js/edit.js
index 61661642e2..8794917787 100644
--- a/module/ci/js/editjob.js
+++ b/module/integration/js/edit.js
@@ -69,8 +69,8 @@ $(function()
triggerTypeChanged(triggerType);
});
-function exeJob(id) {
- var link = createLink('ci', 'exeJob', 'id=' + id);
+function execJob(id) {
+ var link = createLink('integration', 'exec', 'id=' + id);
$.ajax({
type:"POST",
url: link,
diff --git a/module/integration/lang/en.php b/module/integration/lang/en.php
new file mode 100644
index 0000000000..86b407f8e4
--- /dev/null
+++ b/module/integration/lang/en.php
@@ -0,0 +1,46 @@
+integration->browse = 'Browse Integration';
+$lang->integration->create = 'Create Integration';
+$lang->integration->edit = 'Edit Integration';
+$lang->integration->execNow = 'Execute now';
+$lang->integration->delete = 'Delete Integration';
+$lang->integration->confirmDelete = 'Do you want to delete this Build?';
+
+$lang->integration->id = 'ID';
+$lang->integration->name = 'Name';
+$lang->integration->repo = 'Repo';
+$lang->integration->svnFolder = 'SVN Tag Watch Path';
+$lang->integration->jenkins = 'Jenkins Server';
+$lang->integration->buildType = 'Build Type';
+$lang->integration->jenkinsJob = 'Jenkins Task';
+$lang->integration->triggerType = 'Trigger';
+$lang->integration->scheduleType = 'Schedule';
+$lang->integration->cronExpression = 'Cron Expression';
+$lang->integration->custom = 'Custom';
+
+$lang->integration->at = 'executed on';
+$lang->integration->time = 'Time';
+$lang->integration->exec = 'Execute';
+$lang->integration->scheduleInterval = 'Every';
+$lang->integration->day = 'days';
+$lang->integration->lastExec = 'Last Executed';
+$lang->integration->scheduleTime = 'Time';
+
+$lang->integration->example = 'e.g.';
+$lang->integration->tagEx = 'build_#15, to build Jenkins job that id is 15.';
+$lang->integration->commitEx = 'start build #15, to build Jenkins job that id is 15.';
+$lang->integration->cronSample = 'e.g. 0 0 2 * * 2-6/1 means 2:00 a.m. every weekday.';
+
+$lang->integration->dayTypeList['workDay'] = 'Weekdays';
+$lang->integration->dayTypeList['everyDay'] = 'Every Day';
+
+$lang->integration->buildTypeList['build'] = 'Only Build';
+$lang->integration->buildTypeList['buildAndDeploy'] = 'Build And Deploy';
+$lang->integration->buildTypeList['buildAndTest'] = 'Build And Test';
+
+$lang->integration->triggerTypeList['tag'] = 'Tag';
+$lang->integration->triggerTypeList['commit'] = 'Code Commit';
+$lang->integration->triggerTypeList['schedule'] = 'Schedule';
+
+$lang->integration->scheduleTypeList['cron'] = 'Crontab';
+$lang->integration->scheduleTypeList['custom'] = 'Custom';
diff --git a/module/integration/lang/zh-cn.php b/module/integration/lang/zh-cn.php
new file mode 100644
index 0000000000..8195a9d6e0
--- /dev/null
+++ b/module/integration/lang/zh-cn.php
@@ -0,0 +1,46 @@
+integration->browse = '浏览构建任务';
+$lang->integration->create = '创建构建任务';
+$lang->integration->edit = '编辑构建任务';
+$lang->integration->execNow = '立即执行';
+$lang->integration->delete = '删除构建任务';
+$lang->integration->confirmDelete = '确认删除该构建任务吗?';
+
+$lang->integration->id = 'ID';
+$lang->integration->name = '名称';
+$lang->integration->repo = '代码库';
+$lang->integration->svnFolder = 'SVN Tag监控路径';
+$lang->integration->jenkins = 'Jenkins服务';
+$lang->integration->buildType = '构建类型';
+$lang->integration->jenkinsJob = 'Jenkins任务名';
+$lang->integration->triggerType = '触发方式';
+$lang->integration->scheduleType = '时间计划';
+$lang->integration->cronExpression = 'Cron表达式';
+$lang->integration->custom = '自定义';
+
+$lang->integration->at = '在';
+$lang->integration->time = '时间';
+$lang->integration->exec = '执行';
+$lang->integration->scheduleInterval = '每隔';
+$lang->integration->day = '天';
+$lang->integration->lastExec = '最后执行';
+$lang->integration->scheduleTime = '时间';
+
+$lang->integration->example = '举例';
+$lang->integration->tagEx = 'build_#15,其中15为Jenkins任务编号';
+$lang->integration->commitEx = 'start build #15,其中15为Jenkins任务编号';
+$lang->integration->cronSample = '如 0 0 2 * * 2-6/1 表示每个工作日凌晨2点';
+
+$lang->integration->dayTypeList['workDay'] = '工作日';
+$lang->integration->dayTypeList['everyDay'] = '每天';
+
+$lang->integration->buildTypeList['build'] = '仅构建';
+$lang->integration->buildTypeList['buildAndDeploy'] = '构建部署';
+$lang->integration->buildTypeList['buildAndTest'] = '构建测试';
+
+$lang->integration->triggerTypeList['tag'] = '打标签';
+$lang->integration->triggerTypeList['commit'] = '代码提交注释';
+$lang->integration->triggerTypeList['schedule'] = '定时计划';
+
+$lang->integration->scheduleTypeList['cron'] = 'Crontab';
+$lang->integration->scheduleTypeList['custom'] = '自定义';
diff --git a/module/integration/model.php b/module/integration/model.php
new file mode 100644
index 0000000000..30a48f03bc
--- /dev/null
+++ b/module/integration/model.php
@@ -0,0 +1,188 @@
+
+ * @package integration
+ * @version $Id$
+ * @link http://www.zentao.net
+ */
+class integrationModel extends model
+{
+ /**
+ * Get by id.
+ *
+ * @param int $id
+ * @access public
+ * @return object
+ */
+ public function getByID($id)
+ {
+ return $this->dao->select('*')->from(TABLE_INTEGRATION)->where('id')->eq($id)->fetch();
+ }
+
+ /**
+ * Get integration list.
+ *
+ * @param string $orderBy
+ * @param object $pager
+ * @access public
+ * @return array
+ */
+ public function getList($orderBy = 'id_desc', $pager = null)
+ {
+ return $this->dao->select('t1.*, t2.name as repoName, t3.name as jenkinsName')->from(TABLE_INTEGRATION)->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');
+ }
+
+ /**
+ * Create integration
+ *
+ * @access public
+ * @return void
+ */
+ public function create()
+ {
+ $integration = fixer::input('post')
+ ->add('createdBy', $this->app->user->account)
+ ->add('createdDate', helper::now())
+ ->remove('repoType')
+ ->get();
+
+ $this->dao->insert(TABLE_INTEGRATION)->data($integration)
+ ->batchCheck($this->config->integration->create->requiredFields, 'notempty')
+
+ ->batchCheckIF($integration->triggerType === 'schedule' && $integration->scheduleType == 'cron', "cronExpression", 'notempty')
+ ->batchCheckIF($integration->triggerType === 'schedule' && $integration->scheduleType == 'custom', "scheduleDay,scheduleTime,scheduleInterval", 'notempty')
+ ->batchCheckIF($this->post->repoType == 'Subversion', "svnFolder", 'notempty')
+
+ ->autoCheck()
+ ->exec();
+
+ $integrationId = $this->dao->lastInsertID();
+ if($integration->triggerType =='schedule')
+ {
+ $arr = explode(":", $integration->scheduleTime);
+ $hour = $arr[0];
+ $min = $arr[1];
+
+ if($integration->scheduleDay == 'everyDay')
+ {
+ $days = '1-7';
+ }
+ elseif($integration->scheduleDay == 'workDay')
+ {
+ $days = '1-5';
+ }
+
+ $cron = (object)array('m' => $min, 'h' => $hour, 'dom' => '*', 'mon' => '*',
+ 'dow' => $days . '/' . $integration->scheduleInterval, 'command' => 'moduleName=ci&methodName=exeJob&parm=' . $integrationId,
+ 'remark' => ($this->lang->ci->extJob . $integrationId), 'type' => 'zentao',
+ 'buildin' => '-1', 'status' => 'normal', 'lastTime' => '0000-00-00 00:00:00');
+ $this->dao->insert(TABLE_CRON)->data($cron)->exec();
+ }
+
+ return true;
+ }
+
+ /**
+ * Update integration
+ *
+ * @param int $id
+ * @access public
+ * @return void
+ */
+ public function update($id)
+ {
+ $integration = fixer::input('post')
+ ->add('editedBy', $this->app->user->account)
+ ->add('editedDate', helper::now())
+ ->remove('repoType')
+ ->get();
+
+ $this->dao->update(TABLE_INTEGRATION)->data($integration)
+ ->batchCheck($this->config->integration->edit->requiredFields, 'notempty')
+
+ ->batchCheckIF($integration->triggerType === 'schedule' && $integration->scheduleType == 'cron', "cronExpression", 'notempty')
+ ->batchCheckIF($integration->triggerType === 'schedule' && $integration->scheduleType == 'custom', "scheduleDay,scheduleTime,scheduleInterval", 'notempty')
+ ->batchCheckIF($this->post->repoType == 'Subversion', "svnFolder", 'notempty')
+
+ ->autoCheck()
+ ->where('id')->eq($id)
+ ->exec();
+
+ if ($integration->triggerType === 'schedule')
+ {
+ $command = 'moduleName=ci&methodName=exeJob&parm=' . $id;
+
+ $arr = explode(":", $integration->scheduleTime);
+ $hour = $arr[0];
+ $min = $arr[1];
+
+ if($integration->scheduleDay == 'everyDay')
+ {
+ $days = '1-7';
+ }
+ elseif($integration->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 . '/' . $integration->scheduleInterval)
+ ->set('lastTime')->eq('0000-00-00 00:00:00')
+ ->where('command')->eq($command)->exec();
+ }
+
+ return true;
+ }
+
+ /**
+ * Execute integration
+ *
+ * @param int $integrationID
+ * @access public
+ * @return bool
+ */
+ public function exec($integrationID)
+ {
+ $integration = $this->dao->select('t1.id as jobId,t1.name as jobName,t1.repo,t1.jenkinsJob,t2.name as jenkinsName,t2.serviceUrl,t2.account,t2.token,t2.password')
+ ->from(TABLE_INTEGRATION)->alias('t1')
+ ->leftJoin(TABLE_JENKINS)->alias('t2')->on('t1.jenkins=t2.id')
+ ->where('t1.id')->eq($integrationID)
+ ->fetch();
+
+ if (!$integration) return false;
+
+ $jenkinsServer = $integration->serviceUrl;
+ $jenkinsUser = $integration->account;
+ $jenkinsPassword = $integration->token ? $integration->token : base64_decode($integration->password);
+
+ $jenkinsAuth = '://' . $jenkinsUser . ':' . $jenkinsPassword . '@';
+ $jenkinsServer = str_replace('://', $jenkinsAuth, $jenkinsServer);
+ $buildUrl = sprintf('%s/job/%s/buildWithParameters/api/json', $jenkinsServer, $integration->jenkinsJob);
+
+ $data = new stdClass();
+ // TODO: 将参数加入$data,代码完成后删除注释
+ // PARAM_TAG:git tag name or svn tag url
+ // PARAM_REVISION:git revision string or svn revision number
+ $data->PARAM_TAG = "tag111";
+ $data->PARAM_REVISION = "6c3a7bf931855842e261c7991bb143c1e0c3fb19";
+
+ $integration->queueItem = $this->loadModel('ci')->sendRequest($buildUrl, $data);
+ $this->loadModel('compile')->saveBuild($integration);
+
+ return !dao::isError();
+ }
+}
diff --git a/module/integration/view/browse.html.php b/module/integration/view/browse.html.php
new file mode 100644
index 0000000000..09e19ee148
--- /dev/null
+++ b/module/integration/view/browse.html.php
@@ -0,0 +1,65 @@
+
+ * @package ci
+ * @version $Id$
+ * @link http://www.zentao.net
+ */
+?>
+
+
+
+ createLink('integration', 'browse'), "{$lang->ci->task}", '', "class='btn btn-link btn-active-text'");?>
+
+
+ " . $lang->integration->create, '', "class='btn btn-primary'");?>
+
+
+
+
diff --git a/module/ci/view/createjob.html.php b/module/integration/view/create.html.php
similarity index 61%
rename from module/ci/view/createjob.html.php
rename to module/integration/view/create.html.php
index 567429043f..8df29c404d 100644
--- a/module/ci/view/createjob.html.php
+++ b/module/integration/view/create.html.php
@@ -1,11 +1,11 @@
- * @package job
+ * @package integration
* @version $Id$
* @link http://www.zentao.net
*/
@@ -19,51 +19,51 @@
-
job->create; ?>
+ integration->create; ?>