mirror of
https://github.com/ohwgiles/laminar.git
synced 2024-10-27 20:34:20 +00:00
allow setting a job description
adding DESCRIPTION=foo to $JOBNAME.conf will display "foo" in the job overview page on the frontend Resolves #97
This commit is contained in:
parent
40b708c594
commit
2bf04d8157
@ -604,6 +604,14 @@ All=.*
|
|||||||
|
|
||||||
Changes to this file are detected immediately and will be visible on next page refresh.
|
Changes to this file are detected immediately and will be visible on next page refresh.
|
||||||
|
|
||||||
|
## Adding a description to a job
|
||||||
|
|
||||||
|
Edit `/var/lib/laminar/cfg/jobs/$JOBNAME.conf`:
|
||||||
|
|
||||||
|
```
|
||||||
|
DESCRIPTION=Anything here will appear on the job page in the frontend <em>unescaped</em>.
|
||||||
|
```
|
||||||
|
|
||||||
## Setting the page title
|
## Setting the page title
|
||||||
|
|
||||||
Change `LAMINAR_TITLE` in `/etc/laminar.conf` to your preferred page title. Laminar must be restarted for this change to take effect.
|
Change `LAMINAR_TITLE` in `/etc/laminar.conf` to your preferred page title. Laminar must be restarted for this change to take effect.
|
||||||
|
@ -317,7 +317,8 @@ std::string Laminar::getStatus(MonitorScope scope) {
|
|||||||
j.set("number", build).set("started", started);
|
j.set("number", build).set("started", started);
|
||||||
j.EndObject();
|
j.EndObject();
|
||||||
});
|
});
|
||||||
|
auto desc = jobDescriptions.find(scope.job);
|
||||||
|
j.set("description", desc == jobDescriptions.end() ? "" : desc->second);
|
||||||
} else if(scope.type == MonitorScope::ALL) {
|
} else if(scope.type == MonitorScope::ALL) {
|
||||||
j.startArray("jobs");
|
j.startArray("jobs");
|
||||||
db->stmt("SELECT name,number,startedAt,completedAt,result FROM builds b JOIN (SELECT name n,MAX(number) l FROM builds GROUP BY n) q ON b.name = q.n AND b.number = q.l")
|
db->stmt("SELECT name,number,startedAt,completedAt,result FROM builds b JOIN (SELECT name n,MAX(number) l FROM builds GROUP BY n) q ON b.name = q.n AND b.number = q.l")
|
||||||
@ -543,6 +544,10 @@ bool Laminar::loadConfiguration() {
|
|||||||
ctxPtnList.insert(ctx);
|
ctxPtnList.insert(ctx);
|
||||||
jobContexts[jobName].swap(ctxPtnList);
|
jobContexts[jobName].swap(ctxPtnList);
|
||||||
}
|
}
|
||||||
|
std::string desc = conf.get<std::string>("DESCRIPTION");
|
||||||
|
if(!desc.empty()) {
|
||||||
|
jobDescriptions[jobName] = desc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +120,8 @@ private:
|
|||||||
|
|
||||||
std::unordered_map<std::string, std::set<std::string>> jobContexts;
|
std::unordered_map<std::string, std::set<std::string>> jobContexts;
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::string> jobDescriptions;
|
||||||
|
|
||||||
std::unordered_map<std::string, std::string> jobGroups;
|
std::unordered_map<std::string, std::string> jobGroups;
|
||||||
|
|
||||||
Settings settings;
|
Settings settings;
|
||||||
|
@ -228,6 +228,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-5 col-md-6 col-lg-7">
|
<div class="col-sm-5 col-md-6 col-lg-7">
|
||||||
<h3>{{$route.params.name}}</h3>
|
<h3>{{$route.params.name}}</h3>
|
||||||
|
<div v-html="description"></div>
|
||||||
<dl class="dl-horizontal">
|
<dl class="dl-horizontal">
|
||||||
<dt>Last Successful Run</dt>
|
<dt>Last Successful Run</dt>
|
||||||
<dd><router-link v-if="lastSuccess" :to="'/jobs/'+$route.params.name+'/'+lastSuccess.number">#{{lastSuccess.number}}</router-link> {{lastSuccess?' - at '+formatDate(lastSuccess.started):'never'}}</dd>
|
<dd><router-link v-if="lastSuccess" :to="'/jobs/'+$route.params.name+'/'+lastSuccess.number">#{{lastSuccess.number}}</router-link> {{lastSuccess?' - at '+formatDate(lastSuccess.started):'never'}}</dd>
|
||||||
|
@ -507,6 +507,7 @@ const Jobs = function() {
|
|||||||
|
|
||||||
var Job = function() {
|
var Job = function() {
|
||||||
var state = {
|
var state = {
|
||||||
|
description: '',
|
||||||
jobsRunning: [],
|
jobsRunning: [],
|
||||||
jobsRecent: [],
|
jobsRecent: [],
|
||||||
lastSuccess: null,
|
lastSuccess: null,
|
||||||
@ -524,6 +525,7 @@ var Job = function() {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
status: function(msg) {
|
status: function(msg) {
|
||||||
|
state.description = msg.description;
|
||||||
state.jobsRunning = msg.running;
|
state.jobsRunning = msg.running;
|
||||||
state.jobsRecent = msg.recent;
|
state.jobsRecent = msg.recent;
|
||||||
state.lastSuccess = msg.lastSuccess;
|
state.lastSuccess = msg.lastSuccess;
|
||||||
|
@ -51,11 +51,16 @@ public:
|
|||||||
return kj::heap<EventSource>(*ioContext, bind_http.c_str(), path);
|
return kj::heap<EventSource>(*ioContext, bind_http.c_str(), path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void defineJob(const char* name, const char* scriptContent) {
|
void defineJob(const char* name, const char* scriptContent, const char* configContent = nullptr) {
|
||||||
KJ_IF_MAYBE(f, tmp.fs->tryOpenFile(kj::Path{"cfg", "jobs", std::string(name) + ".run"},
|
KJ_IF_MAYBE(f, tmp.fs->tryOpenFile(kj::Path{"cfg", "jobs", std::string(name) + ".run"},
|
||||||
kj::WriteMode::CREATE | kj::WriteMode::CREATE_PARENT | kj::WriteMode::EXECUTABLE)) {
|
kj::WriteMode::CREATE | kj::WriteMode::CREATE_PARENT | kj::WriteMode::EXECUTABLE)) {
|
||||||
(*f)->writeAll(std::string("#!/bin/sh\n") + scriptContent + "\n");
|
(*f)->writeAll(std::string("#!/bin/sh\n") + scriptContent + "\n");
|
||||||
}
|
}
|
||||||
|
if(configContent) {
|
||||||
|
KJ_IF_MAYBE(f, tmp.fs->tryOpenFile(kj::Path{"cfg", "jobs", std::string(name) + ".conf"}, kj::WriteMode::CREATE)) {
|
||||||
|
(*f)->writeAll(configContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RunExec {
|
struct RunExec {
|
||||||
|
@ -151,3 +151,15 @@ TEST_F(LaminarFixture, Abort) {
|
|||||||
ASSERT_TRUE(laminar->abort("job1", 1));
|
ASSERT_TRUE(laminar->abort("job1", 1));
|
||||||
EXPECT_EQ(LaminarCi::JobResult::ABORTED, res.wait(ioContext->waitScope).getResult());
|
EXPECT_EQ(LaminarCi::JobResult::ABORTED, res.wait(ioContext->waitScope).getResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(LaminarFixture, JobDescription) {
|
||||||
|
defineJob("foo", "true", "DESCRIPTION=bar");
|
||||||
|
auto es = eventSource("/jobs/foo");
|
||||||
|
ioContext->waitScope.poll();
|
||||||
|
ASSERT_EQ(1, es->messages().size());
|
||||||
|
auto json = es->messages().front().GetObject();
|
||||||
|
ASSERT_TRUE(json.HasMember("data"));
|
||||||
|
auto data = json["data"].GetObject();
|
||||||
|
ASSERT_TRUE(data.HasMember("description"));
|
||||||
|
EXPECT_STREQ("bar", data["description"].GetString());
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user