Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions app/Models/Build.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,16 @@ public function site(): BelongsTo
}

/**
* @return HasMany<BuildError, $this>
*/
public function buildErrors(): HasMany
{
return $this->hasMany(BuildError::class, 'buildid');
}

/**
* @deprecated 02/09/2026 Use buildErrors() instead
*
* @return HasMany<BasicBuildAlert, $this>
*/
public function basicAlerts(): HasMany
Expand All @@ -194,6 +204,8 @@ public function basicAlerts(): HasMany
}

/**
* @deprecated 02/09/2026 Use buildErrors() instead
*
* @return HasMany<BasicBuildAlert, $this>
*/
public function basicErrors(): HasMany
Expand All @@ -203,6 +215,8 @@ public function basicErrors(): HasMany
}

/**
* @deprecated 02/09/2026 Use buildErrors() instead
*
* @return HasMany<BasicBuildAlert, $this>
*/
public function basicWarnings(): HasMany
Expand All @@ -212,6 +226,8 @@ public function basicWarnings(): HasMany
}

/**
* @deprecated 02/09/2026 Use buildErrors() instead
*
* @return HasMany<RichBuildAlert, $this>
*/
public function richAlerts(): HasMany
Expand Down
67 changes: 67 additions & 0 deletions app/Models/BuildError.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace App\Models;

use Database\Factories\BuildErrorFactory;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

/**
* @property int $id
* @property int $buildid
* @property ?string $workingdirectory
* @property string $sourcefile
* @property bool $newstatus
* @property int $type
* @property string $stdoutput
* @property string $stderror
* @property ?string $exitcondition
* @property ?string $language
* @property ?string $targetname
* @property ?string $outputfile
* @property ?string $outputtype
* @property ?int $logline
* @property ?int $sourceline
* @property ?int $repeatcount
*
* @mixin Builder<BuildError>
*/
class BuildError extends Model
{
/** @use HasFactory<BuildErrorFactory> */
use HasFactory;

protected $table = 'builderrors';

public $timestamps = false;

protected $fillable = [
'buildid',
'workingdirectory',
'sourcefile',
'newstatus',
'type',
'stdoutput',
'stderror',
'exitcondition',
'language',
'targetname',
'outputfile',
'outputtype',
'logline',
'sourceline',
'repeatcount',
];

protected $casts = [
'buildid' => 'integer',
'type' => 'integer', // TODO: Convert this to an enum
'logline' => 'integer',
'stdoutput' => 'string',
'stderror' => 'string',
'sourceline' => 'integer',
'repeatcount' => 'integer',
'newstatus' => 'boolean',
];
}
2 changes: 2 additions & 0 deletions app/cdash/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ add_feature_test_in_transaction(/Feature/GraphQL/UpdateFileTypeTest)

add_feature_test_in_transaction(/Feature/GraphQL/PinnedTestMeasurementTypeTest)

add_feature_test_in_transaction(/Feature/GraphQL/BuildErrorTypeTest)

add_feature_test_in_transaction(/Feature/RouteAccessTest)

add_feature_test_in_transaction(/Feature/Monitor)
Expand Down
29 changes: 29 additions & 0 deletions database/factories/BuildErrorFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Database\Factories;

use App\Models\BuildError;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

/**
* @extends Factory<BuildError>
*/
class BuildErrorFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'sourcefile' => Str::uuid()->toString(),
'newstatus' => 0,
'type' => 0,
'stdoutput' => Str::uuid()->toString(),
'stderror' => Str::uuid()->toString(),
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;

return new class extends Migration {
public function up(): void
{
DB::statement('ALTER TABLE buildfailure RENAME TO builderrors');

// Add builderror columns which don't already exist in buildfailure (now named builderrors)
DB::statement('ALTER TABLE builderrors ADD COLUMN logline integer');
DB::statement('ALTER TABLE builderrors ADD COLUMN sourceline integer');
DB::statement('ALTER TABLE builderrors ADD COLUMN repeatcount integer');

// Drop not-null constraints on buildfailure-specific columns
DB::statement('ALTER TABLE builderrors ALTER COLUMN workingdirectory DROP NOT NULL');
DB::statement('ALTER TABLE builderrors ALTER COLUMN exitcondition DROP NOT NULL');
DB::statement('ALTER TABLE builderrors ALTER COLUMN language DROP NOT NULL');
DB::statement('ALTER TABLE builderrors ALTER COLUMN targetname DROP NOT NULL');
DB::statement('ALTER TABLE builderrors ALTER COLUMN targetname DROP NOT NULL');
DB::statement('ALTER TABLE builderrors ALTER COLUMN outputfile DROP NOT NULL');
DB::statement('ALTER TABLE builderrors ALTER COLUMN outputtype DROP NOT NULL');

// By copying builderror into what was previously called buildfailure, we preserve the
// buildfailure IDs and create new ones for builderror records.
DB::insert('
INSERT INTO builderrors (
buildid,
type,
logline,
stderror,
sourcefile,
sourceline,
repeatcount,
newstatus,
stdoutput
)
SELECT
buildid,
type,
logline,
stderror,
sourcefile,
sourceline,
repeatcount,
newstatus,
stdoutput
FROM builderror
');

DB::statement('DROP TABLE builderror');

DB::statement('
CREATE VIEW builderror AS
SELECT
builderrors.id,
builderrors.buildid,
builderrors.type,
builderrors.logline,
builderrors.stderror,
builderrors.sourcefile,
builderrors.sourceline,
builderrors.repeatcount,
builderrors.newstatus,
builderrors.stdoutput
FROM
builderrors
WHERE
builderrors.id IS NOT NULL
AND builderrors.buildid IS NOT NULL
AND builderrors.type IS NOT NULL
AND builderrors.logline IS NOT NULL
AND builderrors.stderror IS NOT NULL
AND builderrors.sourcefile IS NOT NULL
AND builderrors.sourceline IS NOT NULL
AND builderrors.repeatcount IS NOT NULL
AND builderrors.newstatus IS NOT NULL
AND builderrors.stdoutput IS NOT NULL
');
DB::statement('ALTER VIEW builderror ALTER COLUMN logline SET DEFAULT 0');
DB::statement("ALTER VIEW builderror ALTER COLUMN sourcefile SET DEFAULT ''");
DB::statement('ALTER VIEW builderror ALTER COLUMN sourceline SET DEFAULT 0');
DB::statement('ALTER VIEW builderror ALTER COLUMN repeatcount SET DEFAULT 0');

DB::statement('
CREATE VIEW buildfailure AS
SELECT
builderrors.id,
builderrors.buildid,
builderrors.workingdirectory,
builderrors.sourcefile,
builderrors.newstatus,
builderrors.type,
builderrors.stdoutput,
builderrors.stderror,
builderrors.exitcondition,
builderrors.language,
builderrors.targetname,
builderrors.outputfile,
builderrors.outputtype
FROM
builderrors
WHERE
builderrors.id IS NOT NULL
AND builderrors.buildid IS NOT NULL
AND builderrors.workingdirectory IS NOT NULL
AND builderrors.sourcefile IS NOT NULL
AND builderrors.newstatus IS NOT NULL
AND builderrors.type IS NOT NULL
AND builderrors.stdoutput IS NOT NULL
AND builderrors.stderror IS NOT NULL
AND builderrors.exitcondition IS NOT NULL
AND builderrors.language IS NOT NULL
AND builderrors.targetname IS NOT NULL
AND builderrors.outputfile IS NOT NULL
AND builderrors.outputtype IS NOT NULL
');
}

public function down(): void
{
}
};
45 changes: 43 additions & 2 deletions graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -726,17 +726,22 @@ type Build {
filters: _ @filter
): [Test!]! @hasMany(type: CONNECTION) @orderBy(column: "id", direction: DESC)

"""
A list of warnings and errors submitted for this build.
"""
buildErrors: [BuildError!]! @hasMany(type: CONNECTION) @orderBy(column: "id", direction: DESC)

# TODO: Make an "errors" field which returns the union of basic and rich errors
"""
A list of "basic" errors submitted for this build.
"""
basicErrors: [BasicBuildAlert!]! @hasMany(type: CONNECTION) @orderBy(column: "id", direction: DESC)
basicErrors: [BasicBuildAlert!]! @hasMany(type: CONNECTION) @orderBy(column: "id", direction: DESC) @deprecated(reason: "This field will be removed in the next major version of CDash. Use buildErrors instead.")

# TODO: Make a "warnings" field which returns the union of basic and rich warnings
"""
A list of "basic" warnings submitted for this build.
"""
basicWarnings: [BasicBuildAlert!]! @hasMany(type: CONNECTION) @orderBy(column: "id", direction: DESC)
basicWarnings: [BasicBuildAlert!]! @hasMany(type: CONNECTION) @orderBy(column: "id", direction: DESC) @deprecated(reason: "This field will be removed in the next major version of CDash. Use buildErrors instead.")

project: Project! @belongsTo

Expand Down Expand Up @@ -963,6 +968,42 @@ type BasicBuildAlert {
}


type BuildError {
"Unique primary key."
id: ID! @filterable

type: BuildErrorType! @filterable

sourceFile: String! @rename(attribute: "sourcefile") @filterable

stdOutput: String! @rename(attribute: "stdoutput") @filterable

stdError: String! @rename(attribute: "stderror") @filterable

workingDirectory: String @rename(attribute: "workingdirectory") @filterable

exitCondition: String @rename(attribute: "exitcondition") @filterable

language: String @filterable

targetName: String @rename(attribute: "targetname") @filterable

outputFile: String @rename(attribute: "outputfile") @filterable

outputType: String @rename(attribute: "outputtype") @filterable

logLine: Int @rename(attribute: "logline") @filterable

sourceLine: Int @rename(attribute: "sourceline") @filterable
}


enum BuildErrorType {
ERROR @enum(value: "0")
WARNING @enum(value: "1")
}


"Site."
type Site {
"Unique primary key."
Expand Down
Loading