Skip to content

Commit dd30a42

Browse files
committed
fix #33: track CI failures through the cron job
1 parent 6f027a3 commit dd30a42

File tree

5 files changed

+98
-4
lines changed

5 files changed

+98
-4
lines changed

cron.php

+10
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,16 @@ function run_patch_stats() {
196196
new PatchComment($patch, "New branch hash: $newhash"));
197197
echo "Patch $patch->id changed hash from $oldhash to $newhash\n";
198198
}
199+
200+
if ($pr = $patch->getPR()) {
201+
foreach ($patch->getHashes() as $hash) {
202+
$failed = $pr->failedCIjobs($hash);
203+
foreach ($failed as $job) {
204+
$patch->addCIError($hash, $job['name']);
205+
}
206+
}
207+
}
208+
199209
echo "Updated patch $patch->id\n";
200210

201211
} catch (ValidationException $ex) {

entities/Patch.php

+32-3
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ abstract class Patch
6969
*/
7070
public $comments;
7171

72+
/** @OneToMany(targetEntity="PatchCIError", mappedBy="patch", cascade={"persist"})
73+
* @OrderBy({"id" = "ASC"})
74+
*/
75+
public $ci_failures;
76+
7277
/** @ManyToMany(targetEntity="User") */
7378
public $students;
7479

@@ -202,8 +207,9 @@ static function factory(ProjGroup $group, string $url, $type,
202207
}
203208

204209
public function __construct() {
205-
$this->comments = new \Doctrine\Common\Collections\ArrayCollection();
206-
$this->students = new \Doctrine\Common\Collections\ArrayCollection();
210+
$this->comments = new \Doctrine\Common\Collections\ArrayCollection();
211+
$this->ci_failures = new \Doctrine\Common\Collections\ArrayCollection();
212+
$this->students = new \Doctrine\Common\Collections\ArrayCollection();
207213
}
208214

209215
abstract public function isValid() : bool;
@@ -329,10 +335,33 @@ public function wasMerged() {
329335
$this->status == PATCH_MERGED_ILLEGAL;
330336
}
331337

332-
public function getSubmitter() : User {
338+
public function getSubmitter() : ?User {
333339
return $this->comments[0]->user;
334340
}
335341

342+
public function getSubmitterName() : string {
343+
$user = $this->getSubmitter();
344+
return $user ? $user->shortName() : '(Bot)';
345+
}
346+
347+
public function getHashes() {
348+
$hashes = [];
349+
foreach ($this->comments as $comment) {
350+
if (preg_match('/New branch hash: (\S+)/', $comment->text, $m))
351+
$hashes[] = $m[1];
352+
}
353+
$hashes[] = $this->hash;
354+
return $hashes;
355+
}
356+
357+
public function addCIError($hash, $name) {
358+
foreach ($this->ci_failures as $error) {
359+
if ($error->hash == $hash && $error->name == $name)
360+
return;
361+
}
362+
$this->ci_failures->add(new PatchCIError($this, $hash, $name));
363+
}
364+
336365
public function set_status($status) {
337366
$status = (int)$status;
338367
if (!isset(self::get_status_options()[$status]))

entities/PatchCIError.php

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
// Copyright (c) 2022-present Instituto Superior Técnico.
3+
// Distributed under the MIT license that can be found in the LICENSE file.
4+
5+
use Doctrine\ORM\Mapping\Column;
6+
use Doctrine\ORM\Mapping\Entity;
7+
use Doctrine\ORM\Mapping\GeneratedValue;
8+
use Doctrine\ORM\Mapping\Id;
9+
use Doctrine\ORM\Mapping\JoinColumn;
10+
use Doctrine\ORM\Mapping\ManyToOne;
11+
12+
/** @Entity */
13+
class PatchCIError
14+
{
15+
/** @Id @Column @GeneratedValue */
16+
public int $id;
17+
18+
/** @ManyToOne(inversedBy="ci_failures")
19+
* @JoinColumn(nullable=false)
20+
*/
21+
public Patch $patch;
22+
23+
/** @Column(length=64) */
24+
public string $hash;
25+
26+
/** @Column(length=128) */
27+
public string $name;
28+
29+
public function __construct(Patch $patch, string $hash, string $name) {
30+
$this->patch = $patch;
31+
$this->hash = $hash;
32+
$this->name = $name;
33+
}
34+
}

pages/editpatch.php

+21
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,27 @@
7676
}
7777
echo "</table>\n";
7878

79+
$ci_failures = [];
80+
foreach ($patch->ci_failures as $ci) {
81+
$ci_failures[$ci->hash][] = $ci->name;
82+
}
83+
84+
if ($ci_failures) {
85+
echo <<<HTML
86+
<p>&nbsp;</p>
87+
<p><b>CI Failures:</b></p>
88+
<table>
89+
<tr><th>Commit hash</th><th>Failed CI jobs</th></tr>
90+
HTML;
91+
92+
foreach ($ci_failures as $hash => $names) {
93+
echo "<tr><td>$hash</td><td>",
94+
nl2br(htmlspecialchars(implode("\n", $names))),
95+
"</td></tr>\n";
96+
}
97+
echo "</table>\n";
98+
}
99+
79100
// Add approve/reject buttons to simplify the life of TAs
80101
$extra_buttons = '';
81102
if ($patch->status <= PATCH_REVIEWED && auth_at_least(ROLE_TA)) {

pages/patches.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
'+' => $patch->lines_added,
8888
'-' => $patch->lines_deleted,
8989
'Files' => $patch->files_modified,
90-
'Submitter' => htmlspecialchars($patch->getSubmitter()->shortName()),
90+
'Submitter' => htmlspecialchars($patch->getSubmitterName()),
9191
'Authors' => implode(', ', $authors),
9292
];
9393
}

0 commit comments

Comments
 (0)