mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-16 04:45:20 +03:00
Added Build Type select for CI builds
This commit is contained in:
parent
40ed78ab35
commit
befafc07e6
6 changed files with 255 additions and 39 deletions
|
@ -2137,6 +2137,9 @@
|
|||
"firmwareFlasherNoReboot": {
|
||||
"message": "No reboot sequence"
|
||||
},
|
||||
"firmwareFlasherOnlineSelectBuildType": {
|
||||
"message": "Select build type to see available boards."
|
||||
},
|
||||
"firmwareFlasherOnlineSelectBoardDescription": {
|
||||
"message": "Select your board to see available online firmware releases - Select the correct firmware appropriate for your board."
|
||||
},
|
||||
|
@ -2185,6 +2188,21 @@
|
|||
"firmwareFlasherOptionLoading": {
|
||||
"message": "Loading ..."
|
||||
},
|
||||
"firmwareFlasherOptionLabelBuildTypeRelease": {
|
||||
"message": "Release"
|
||||
},
|
||||
"firmwareFlasherOptionLabelBuildTypeReleaseCandidate": {
|
||||
"message": "Release And Release Candidate"
|
||||
},
|
||||
"firmwareFlasherOptionLabelBuildTypeDevelopment": {
|
||||
"message": "Development"
|
||||
},
|
||||
"firmwareFlasherOptionLabelBuildTypeAKK3_3": {
|
||||
"message": "3.3 AKK & RDQ VTX Patch"
|
||||
},
|
||||
"firmwareFlasherOptionLabelBuildTypeAKK3_4": {
|
||||
"message": "3.4 AKK & RDQ VTX Patch"
|
||||
},
|
||||
"firmwareFlasherOptionLabelSelectFirmware": {
|
||||
"message": "Choose a Firmware / Board"
|
||||
},
|
||||
|
|
|
@ -198,7 +198,7 @@ input[type="number"]::-webkit-inner-spin-button {
|
|||
width: 136px;
|
||||
}
|
||||
|
||||
#port-picker .auto_connect {
|
||||
#port-picker .auto_connect, .gray {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
|
|
97
src/js/jenkins_loader.js
Normal file
97
src/js/jenkins_loader.js
Normal file
|
@ -0,0 +1,97 @@
|
|||
'use strict;'
|
||||
|
||||
var JenkinsLoader = function (url, jobName) {
|
||||
var self = this;
|
||||
|
||||
self._url = url;
|
||||
self._jobName = jobName;
|
||||
self._jobUrl = self._url + '/job/' + self._jobName;
|
||||
self._buildsRequest = '/api/json?tree=builds[number,result,timestamp,artifacts[relativePath],changeSet[items[commitId,msg]]]';
|
||||
self._builds = {};
|
||||
|
||||
self._buildsDataTag = `${self._jobUrl}BuildsData`;
|
||||
self._cacheLastUpdateTag = `${self._jobUrl}BuildsLastUpdate`
|
||||
}
|
||||
|
||||
JenkinsLoader.prototype.loadBuilds = function (callback) {
|
||||
var self = this;
|
||||
|
||||
chrome.storage.local.get([self._cacheLastUpdateTag, self._buildsDataTag], function (result) {
|
||||
var buildsDataTimestamp = $.now();
|
||||
var cachedBuildsData = result[self._buildsDataTag];
|
||||
var cachedBuildsLastUpdate = result[self._cacheLastUpdateTag];
|
||||
|
||||
if (!cachedBuildsData || !cachedBuildsLastUpdate || buildsDataTimestamp - cachedBuildsLastUpdate > 3600 * 1000) {
|
||||
var request = self._jobUrl + self._buildsRequest;
|
||||
|
||||
$.get(request, function (buildsInfo) {
|
||||
// filter successful builds
|
||||
self._builds = buildsInfo.builds.filter(build => build.result == 'SUCCESS')
|
||||
.map(build => ({
|
||||
number: build.number,
|
||||
artifacts: build.artifacts.map(artifact => artifact.relativePath),
|
||||
changes: build.changeSet.items.map(item => '* ' + item.msg).join('<br>\n'),
|
||||
date: new Date(build.timestamp)
|
||||
}));
|
||||
|
||||
self._parseBuilds(callback);
|
||||
}).fail(function (data) {
|
||||
GUI.log(i18n.getMessage('releaseCheckFailed', [self._jobName, 'failed to load builds']));
|
||||
|
||||
self._builds = cachedBuildsData;
|
||||
self._parseBuilds(callback);
|
||||
});
|
||||
} else {
|
||||
if (cachedBuildsData) {
|
||||
GUI.log(i18n.getMessage('releaseCheckCached', [self._jobName]));
|
||||
}
|
||||
|
||||
self._builds = cachedBuildsData;
|
||||
self._parseBuilds(callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
JenkinsLoader.prototype._parseBuilds = function (callback) {
|
||||
var self = this;
|
||||
|
||||
// convert from `build -> targets` to `target -> builds` mapping
|
||||
var targetBuilds = {};
|
||||
|
||||
var targetFromFilenameExpression = /betaflight_([\d.]+)?_?(\w+)(\-.*)?\.(.*)/;
|
||||
|
||||
self._builds.forEach(build => {
|
||||
build.artifacts.forEach(relativePath => {
|
||||
var match = targetFromFilenameExpression.exec(relativePath);
|
||||
|
||||
if (!match) {
|
||||
return;
|
||||
}
|
||||
|
||||
var version = match[1];
|
||||
var target = match[2];
|
||||
|
||||
var formattedDate = ("0" + build.date.getDate()).slice(-2) + "-" + ("0" + (build.date.getMonth()+1)).slice(-2) + "-" +
|
||||
build.date.getFullYear() + " " + ("0" + build.date.getHours()).slice(-2) + ":" + ("0" + build.date.getMinutes()).slice(-2);
|
||||
|
||||
var descriptor = {
|
||||
'releaseUrl': self._jobUrl + '/' + build.number,
|
||||
'name' : self._jobName + ' #' + build.number,
|
||||
'version' : version + ' #' + build.number,
|
||||
'url' : self._jobUrl + '/' + build.number + '/artifact/' + relativePath,
|
||||
'file' : relativePath.split('/').slice(-1)[0],
|
||||
'target' : target,
|
||||
'date' : formattedDate,
|
||||
'notes' : build.changes
|
||||
};
|
||||
|
||||
if (targetBuilds[target]) {
|
||||
targetBuilds[target].push(descriptor);
|
||||
} else {
|
||||
targetBuilds[target] = [ descriptor ];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
callback(targetBuilds);
|
||||
}
|
|
@ -93,17 +93,51 @@ TABS.firmware_flasher.initialize = function (callback) {
|
|||
$("a.load_remote_file").text(i18n.getMessage('firmwareFlasherButtonLoadOnline'));
|
||||
};
|
||||
|
||||
function buildBoardOptions(releaseData) {
|
||||
function buildJenkinsBoardOptions(builds) {
|
||||
if (!builds) {
|
||||
$('select[name="board"]').empty().append('<option value="0">Offline</option>');
|
||||
$('select[name="firmware_version"]').empty().append('<option value="0">Offline</option>');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var boards_e = $('select[name="board"]');
|
||||
var versions_e = $('select[name="firmware_version"]');
|
||||
|
||||
var selectTargets = [];
|
||||
Object.keys(builds)
|
||||
.sort()
|
||||
.forEach(function(target, i) {
|
||||
var descriptors = builds[target];
|
||||
descriptors.forEach(function(descriptor){
|
||||
if($.inArray(target, selectTargets) == -1) {
|
||||
selectTargets.push(target);
|
||||
var select_e =
|
||||
$("<option value='{0}'>{0}</option>".format(
|
||||
descriptor.target
|
||||
)).data('summary', descriptor);
|
||||
boards_e.append(select_e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
TABS.firmware_flasher.releases = builds;
|
||||
|
||||
chrome.storage.local.get('selected_board', function (result) {
|
||||
if (result.selected_board) {
|
||||
var boardBuilds = builds[result.selected_board]
|
||||
$('select[name="board"]').val(boardBuilds ? result.selected_board : 0).trigger('change');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function buildBoardOptions(releaseData, showDevReleases) {
|
||||
if (!releaseData) {
|
||||
$('select[name="board"]').empty().append('<option value="0">Offline</option>');
|
||||
$('select[name="firmware_version"]').empty().append('<option value="0">Offline</option>');
|
||||
} else {
|
||||
var boards_e = $('select[name="board"]').empty();
|
||||
var showDevReleases = ($('input.show_development_releases').is(':checked'));
|
||||
boards_e.append($("<option value='0'>{0}</option>".format(i18n.getMessage('firmwareFlasherOptionLabelSelectBoard'))));
|
||||
|
||||
var versions_e = $('select[name="firmware_version"]').empty();
|
||||
versions_e.append($("<option value='0'>{0}</option>".format(i18n.getMessage('firmwareFlasherOptionLabelSelectFirmwareVersion'))));
|
||||
var boards_e = $('select[name="board"]');
|
||||
var versions_e = $('select[name="firmware_version"]');
|
||||
|
||||
var releases = {};
|
||||
var sortedTargets = [];
|
||||
|
@ -158,8 +192,7 @@ TABS.firmware_flasher.initialize = function (callback) {
|
|||
"file" : asset.name,
|
||||
"target" : target,
|
||||
"date" : formattedDate,
|
||||
"notes" : release.body,
|
||||
"status" : release.prerelease ? "release-candidate" : "stable"
|
||||
"notes" : release.body
|
||||
};
|
||||
releases[target].push(descriptor);
|
||||
});
|
||||
|
@ -181,21 +214,81 @@ TABS.firmware_flasher.initialize = function (callback) {
|
|||
});
|
||||
});
|
||||
TABS.firmware_flasher.releases = releases;
|
||||
|
||||
chrome.storage.local.get('selected_board', function (result) {
|
||||
if (result.selected_board) {
|
||||
$('select[name="board"]').val(result.selected_board);
|
||||
$('select[name="board"]').trigger("change");
|
||||
var boardReleases = releases[result.selected_board]
|
||||
$('select[name="board"]').val(boardReleases ? result.selected_board : 0).trigger('change');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function showOrHideBuildTypeSelect() {
|
||||
var showDevReleases = $(this).is(':checked');
|
||||
|
||||
if (showDevReleases) {
|
||||
$('tr.build_type').show();
|
||||
} else {
|
||||
$('tr.build_type').hide();
|
||||
buildType_e.val(0).trigger('change');
|
||||
}
|
||||
}
|
||||
|
||||
var buildTypes = [
|
||||
{
|
||||
tag: 'firmwareFlasherOptionLabelBuildTypeRelease',
|
||||
loader: () => self.releaseChecker.loadReleaseData(releaseData => buildBoardOptions(releaseData, false))
|
||||
},
|
||||
{
|
||||
tag: 'firmwareFlasherOptionLabelBuildTypeReleaseCandidate',
|
||||
loader: () => self.releaseChecker.loadReleaseData(releaseData => buildBoardOptions(releaseData, true))
|
||||
},
|
||||
{
|
||||
tag: 'firmwareFlasherOptionLabelBuildTypeDevelopment',
|
||||
loader: () => new JenkinsLoader('https://ci.betaflight.tech', 'Betaflight').loadBuilds(buildJenkinsBoardOptions)
|
||||
},
|
||||
{
|
||||
tag: 'firmwareFlasherOptionLabelBuildTypeAKK3_3',
|
||||
loader: () => new JenkinsLoader('https://ci.betaflight.tech', 'Betaflight Maintenance 3.3 (AKK - RDQ VTX Patch)').loadBuilds(buildJenkinsBoardOptions)
|
||||
},
|
||||
{
|
||||
tag: 'firmwareFlasherOptionLabelBuildTypeAKK3_4',
|
||||
loader: () => new JenkinsLoader('https://ci.betaflight.tech', 'Betaflight Maintenance 3.4 (AKK - RDQ VTX Patch)').loadBuilds(buildJenkinsBoardOptions)
|
||||
}
|
||||
];
|
||||
|
||||
var buildType_e = $('select[name="build_type"]');
|
||||
buildTypes.forEach((build, index) => {
|
||||
buildType_e.append($("<option value='{0}' selected>{1}</option>".format(index, i18n.getMessage(build.tag))))
|
||||
});
|
||||
|
||||
showOrHideBuildTypeSelect();
|
||||
$('input.show_development_releases').change(showOrHideBuildTypeSelect);
|
||||
|
||||
// translate to user-selected language
|
||||
i18n.localizePage();
|
||||
|
||||
// bind events
|
||||
$('input.show_development_releases').click(function () {
|
||||
self.releaseChecker.loadReleaseData(buildBoardOptions);
|
||||
chrome.storage.local.get('selected_build_type', function (result) {
|
||||
// ensure default build type is selected
|
||||
buildType_e.val(result.selected_build_type || 0).trigger('change');
|
||||
});
|
||||
|
||||
buildType_e.change(function() {
|
||||
$("a.load_remote_file").addClass('disabled');
|
||||
var build_type = $(this).val();
|
||||
|
||||
$('select[name="board"]').empty()
|
||||
.append($("<option value='0'>{0}</option>".format(i18n.getMessage('firmwareFlasherOptionLabelSelectBoard'))));
|
||||
|
||||
$('select[name="firmware_version"]').empty()
|
||||
.append($("<option value='0'>{0}</option>".format(i18n.getMessage('firmwareFlasherOptionLabelSelectFirmwareVersion'))));
|
||||
|
||||
if (!GUI.connect_lock) {
|
||||
buildTypes[build_type].loader();
|
||||
}
|
||||
|
||||
chrome.storage.local.set({'selected_build_type': build_type});
|
||||
});
|
||||
|
||||
$('select[name="board"]').change(function() {
|
||||
|
@ -214,24 +307,23 @@ TABS.firmware_flasher.initialize = function (callback) {
|
|||
versions_e.append($("<option value='0'>{0}</option>".format(i18n.getMessage('firmwareFlasherOptionLabelSelectFirmwareVersion'))));
|
||||
} else {
|
||||
versions_e.append($("<option value='0'>{0} {1}</option>".format(i18n.getMessage('firmwareFlasherOptionLabelSelectFirmwareVersionFor'), target)));
|
||||
|
||||
TABS.firmware_flasher.releases[target].forEach(function(descriptor) {
|
||||
var select_e =
|
||||
$("<option value='{0}'>{0} - {1} - {2}</option>".format(
|
||||
descriptor.version,
|
||||
descriptor.target,
|
||||
descriptor.date,
|
||||
))
|
||||
.css("font-weight", FirmwareCache.has(descriptor)
|
||||
? "bold"
|
||||
: "normal"
|
||||
)
|
||||
.data('summary', descriptor);
|
||||
|
||||
versions_e.append(select_e);
|
||||
});
|
||||
}
|
||||
|
||||
TABS.firmware_flasher.releases[target].forEach(function(descriptor) {
|
||||
var select_e =
|
||||
$("<option value='{0}'>{0} - {1} - {2} ({3})</option>".format(
|
||||
descriptor.version,
|
||||
descriptor.target,
|
||||
descriptor.date,
|
||||
descriptor.status
|
||||
))
|
||||
.css("font-weight", FirmwareCache.has(descriptor)
|
||||
? "bold"
|
||||
: "normal"
|
||||
)
|
||||
.data('summary', descriptor);
|
||||
|
||||
versions_e.append(select_e);
|
||||
});
|
||||
}
|
||||
chrome.storage.local.set({'selected_board': target});
|
||||
});
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
<script type="text/javascript" src="./js/Features.js"></script>
|
||||
<script type="text/javascript" src="./js/Beepers.js"></script>
|
||||
<script type="text/javascript" src="./js/release_checker.js"></script>
|
||||
<script type="text/javascript" src="./js/jenkins_loader.js"></script>
|
||||
<script type="text/javascript" src="./js/main.js"></script>
|
||||
<script type="text/javascript" src="./js/tabs/landing.js"></script>
|
||||
<script type="text/javascript" src="./js/tabs/setup.js"></script>
|
||||
|
|
|
@ -3,6 +3,20 @@
|
|||
<div class="options gui_box">
|
||||
<div class="spacer">
|
||||
<table class="cf_table" style="margin-top: 10px;">
|
||||
<tr class="option">
|
||||
<td><label> <input class="show_development_releases toggle" type="checkbox" /> <span
|
||||
i18n="firmwareFlasherShowDevelopmentReleases"></span>
|
||||
</label></td>
|
||||
<td><span class="description" i18n="firmwareFlasherShowDevelopmentReleasesDescription"></span></td>
|
||||
</tr>
|
||||
<tr class="build_type">
|
||||
<td>
|
||||
<select name="build_type">
|
||||
<!-- options generated at runtime -->
|
||||
</select>
|
||||
</td>
|
||||
<td><span class="description" i18n="firmwareFlasherOnlineSelectBuildType"></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><select name="board">
|
||||
<option value="0" i18n="firmwareFlasherOptionLoading">Loading ...</option>
|
||||
|
@ -33,7 +47,7 @@
|
|||
</label></td>
|
||||
<td><span class="description" i18n="firmwareFlasherFullChipEraseDescription"></span></td>
|
||||
</tr>
|
||||
<tr class="option manual_baud_rate">
|
||||
<tr class="option manual_baud_rate noboarder">
|
||||
<td><label> <input class="flash_manual_baud toggle" type="checkbox" /> <span
|
||||
i18n="firmwareFlasherManualBaud"></span> <select id="flash_manual_baud_rate"
|
||||
i18n_title="firmwareFlasherBaudRate">
|
||||
|
@ -50,12 +64,6 @@
|
|||
</label></td>
|
||||
<td><span class="description" i18n="firmwareFlasherManualBaudDescription"></span></td>
|
||||
</tr>
|
||||
<tr class="option noboarder">
|
||||
<td><label> <input class="show_development_releases toggle" type="checkbox" /> <span
|
||||
i18n="firmwareFlasherShowDevelopmentReleases"></span>
|
||||
</label></td>
|
||||
<td><span class="description" i18n="firmwareFlasherShowDevelopmentReleasesDescription"></span></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue