Previously it was not possible to test features that required an
authenticated user when:
* using `yarn start` with Vagrant (bug 1363722), which meant slower
watch builds
* pointing the UI at the prod/stage API (bug 1317752), which was
extremely limiting
Now login works in all environments, since the frontend no longer uses a
URL prefix, but instead webpack-dev-server proxies non-webpack URLs to
the chosen `BACKEND_DOMAIN` - avoiding cross-domain issues. Cookies are
rewritten to remove any `secure` directive (which is set on production),
so that they can still be read from HTTP localhost. The `Referer` has to
also be changed to stop Django's CSRF checks from rejecting request.
The slower "build into `dist` and watch" mode is therefore no longer
necessary, so `yarn start:local` instead invokes webpack-dev-server just
like `yarn start` - and the `local-watch.js` workaround has been
removed.
Support for the "publish to GitHub with hardcoded `SERVICE_DOMAIN`"
workflow has been dropped, since it was already rarely used and there is
no way to make it support login.
The API domain environment variable was renamed to `BACKEND_DOMAIN` to
avoid potential confusion given it no longer behaves the same as
`SERVICE_DOMAIN` used to.
NB: For full stack Vagrant workflows users must now connect to port
*5000* on localhost, not 8000.
* Add hooks for actions
* Remove task from context for kind == hook
Also display hookGroupId/hookId for kind=hook
in the modal.
* Move taskcluster-lib-scopes to the vendor chunk
The last remaining `ProvidePlugin` definition cannot be removed since
AngularJS and Flot both expect `window.jQuery` to be defined (and
whilst AngularJS falls back to jqLite, it's buggy). It's not possible
to set `window.jQuery` manually in the entrypoints, since ES6 imports
are hoisted, thereby giving no opportunity to modify window first.
* Alphabetize keyboard shortcuts to help avoid introducing conflicts
* Also make a few autoclassify shortcuts use ctrl to reduce confusion
* Enable multi-select on a mac in the autoclassify panel
The `login.html` partial is a leftover from the switch to Auth0 in
bug 1395356, and `errorActions.html` appears to have never been used
since it landed in 8e56de8 (bug 1321798).
Since it's hidden and has never been used.
The `thSettingsPanel.html` partial is a leftover from when this
feature was first added in 3e625f3 / 6b0c56e.
* enable react/prop-types eslint rule
While enabling this, I set all the PropTypes as ``isRequired`` then ran the app
and wherever I hit issues where the value was undefined, then I removed ``isRequired``.
* Enable react/require-default-props eslint rule
In some cases "null" was the best default. I think this is OK. But having empty arrays
for others meant less checking in the actual code, so bonus! :)
After looking at these, I think I want to go back to using "th" prefix and "ph" prefix.
It is a nice way to see right off the bat that these are constants that are established
by our code and not some external library. So converting ``platformMap`` back to
``thPlatformMap``. It also makes for less code/blame churn as we move to imported
constants.
* Move thOptionOrder to constants.js
* Move thFailureResults to constants.js
* Move thRepoGroupOrder to constants.js
* Move thFavIcons to constants.js
* Move phCompareDefaultOriginalRepo to constants.js
* Move phCompareDefaultNewRepo to constants.js
* Move thDefaultRepo to constants.js
* Move thTitleSuffixLimit to constants.js
* Move phTimeRanges to constants.js
* Move thDateFormat to constants.js
* Move phDefaultTimeRangeValue to constants.js
* Move phTimeRangeValues to constants.js
* Move phBlockers to constants.js
* Move phDefaultFramework to constants.js
* Move phAlertSummaryStatusMap to constants.js
* Move phAlertSummaryIssueTrackersMap to constants.js
* Move phAlertStatusMap to constants.js
* Move thJobNavSelectors to constants.js
* Move thPerformanceBranches to constants.js
* Move phDashboardValues to dashboard.js
* Move phCompareBaseLineDefaultTimeRange to constants.js
* Move thPinboardCountError to constants.js
* Remove now-unused values.js
* Move thResultStatusFilters to constants.js
* Move thEvents to constants.js
* Move thAggregateIds to a aggregateIdHelper.js
* Move thReftestStatus to jobHelper.js
* Remove now-unused provider.js
Since we've moving away from vendored packages.
The only differences between the vendored file and that in the NPM
package were the changes to `require('angular')` and export the
created AngularJS module. However Angular is already imported prior
to this package being imported, and we can just pass the module name
as a string instead of relying on the export.
* Bug ID -> Bug
* Left align column
* Make the bug number itself a link to the bug, instead of an additional link
* Use CSS instead of javascript to show/hide details link
* Rename the component to a *Tab and move to /details-panel folder
* cleanup indentation
* cleanup props and panel elements
* Use deconstruction for props object
* simplify onclick event calls with anonymous functions
* Move filerInAddress logic to FailureSummaryTab
* Move the data-fetching into the main controller like the other
tabs so we can do away with the special controller for the
failure summary tab.
* Move functions to helpers instead of filters and take less
values as params
* Eliminate failure_summary/controller
* Moved logic to either the parent controller or into helpers and
the FailureSummaryTab
* Use helper function for bugzilla url
Adds a new view to display intermittent test failure occurrences,
to replace the functionality currently provided by the legacy
OrangeFactor tool.
Includes the new API endpoints originally reviewed in #3271.
* Don't use SERVICE_DOMAIN for references to the front-end code
* Change getRootUrl to getApiUrl to better represent what it is for
* Convert other usages of SERVICE_DOMAIN to getApiUrl
* Convert usages of SERVICE_DOMAIN to getProjectUrl
* Convert uses of SERVICE_DOMAIN to getServiceUrl
* Convert tests to use ``urlHelper``
https://eslint.org/docs/rules/no-use-before-define
Three files have been excluded from this rule entirely, since they
would require significant changes that might as well wait until they
are rewritten in React. It's likely these files may also need to be
excluded from future `var` to `let`/`const` conversions as a result.
From the AirBnb style guide GitHub issue comments:
> Some enjoy using hoisting to define helper methods at the bottom of
> the file. This guide discourages relying on hoisting; instead
> suggesting importing the helpers from another file when possible.
I believe this was the main bug causing the slowdown. It was setting state
in ``filterPlatform`` which is called once per platform when a filter change is
made. But that ``setState`` was updating ALL the platforms for that push.
* Remove unnecessary clonejobs artifact
* Fix the regression with expand/collapse counts
* Very minor optimizations and cleanup
* Add some unit tests for groups
These refs were not actually used, so can be removed. It does appear to
improve rendering speed, especially when changin filtering. I had noticed
that the JobGroup was re-rendering more times than it should, and this
change stops that. I believe more work is to be done here, but this is one
step.
This also includes a couple other small tweaks that may help speed.
The failure classification pin button was broken for bug suggestions
that fell under the "all others" category, since the `BugListItem`
for them weren't passed the `$timeout` prop, unlike for the
"open recent" `BugListItem` instance.
* Move JobDetailsPane to details-panel folder
* Convert to 2 space indent
* Cleanup props with deconstruction
* Subsume some filters into jobdetailspane
* Subsume logic for job signature filtering
* Subsume logic for visibleFields and visibleTimeFields
* Only need latest classification, not whole array
* Ensure all helper functions are named
* Move getBugUrl, getSlaveHealthUrl, getInspectTaskUrl, getWorkerExplorerUrl,
getLogViewerUrl, getRootUrl, getProjectUrl and getProjectJobUrl to urlHelper
* Move getJobsUrl to only place its used
* Replace thServiceDomain with SERVICE_DOMAIN
* remove thUrl provider
Previously all templates were being included on every page, regardless
of whether they were being used, bloating the bundles. In addition,
`templateUrl` has a number of issues compared to `template`:
https://medium.com/@frosty/angularjs-template-vs-templateurl-cdde055b7907
There are now no more instances of non-global `require()`s (or any
require()s for that matter), so we can enable that eslint rule:
https://eslint.org/docs/rules/global-require
Improves the bundle sizes as follows:
* index: -60KB
* logviewer: -138KB
* perf: -84KB
The third argument was changed from a bool to an options object in
bug 1402062 - so these instances would fail with:
`Error: Must pass an object as last argument to thNotify.send!`
This converts virtually all of the CJS imports, apart from:
* the partials/plugin template loading in cache-loader - since that
is being handled in bug 1441614
* `.eslintrc.js` / `neutrino-custom/*` - since they are used by node
directly (which doesn't yet support ES6 modules) rather than via
webpack.
File extensions have been omitted for JS/JSX, otherwise eslint reports:
`Unexpected use of file extension "js" for "..." (import/extensions)`
Since otherwise once converted to ES6 imports, eslint will report:
`Absolute imports should come before relative imports (import/first)`
See:
https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/first.md
I've split this out of the commit switching to ES6 imports to make
the diff easier to follow.
Note: This changes the order of the CSS imports in userguide and perf,
however I can't see anything that's broken as a result locally.
An AngularJS module declares a dependency on another module like so:
```
const fooModule = angular.module('foo', ['name_of_dep_module']);
```
This is suboptimal, since:
a) the dependency is only validated at runtime not during the build
b) the module name often doesn't match the NPM package name, making
it hard to know whether imports are unused.
As such, many AngularJS packages now export a string containing the
module name, which allows for an ES6-like approach (it still uses
globals underneath, but better than nothing):
```
import nameOfDepModule from 'dep-module';
const fooModule = angular.module('foo', [nameOfDepModule]);
```
Just to complicate things, some modules don't export the module name,
but the actual module object itself. This can't be passed to
`angular.module()` directly, so for these modules we have to use the
`name` property on the module instead:
https://docs.angularjs.org/api/ng/type/angular.Module#name
eg:
```
import depModuleObject from 'awkward-dep-module';
const fooModule = angular.module('foo', [depModuleObject.name]);
```
In fact, the treeherder modules do just that - however its not worth
fixing, since otherwise we'd have to change every file that registers
directives/filters/values/... to fetch the module first, using
`angular.module('name-of-existing-module')`.
And whilst we're there, use explicit imports instead of relying on
the webpack `ProvidePlugin` to import it for us - which lets us also
remove the eslint global exemption plus unit test workaround.
* Move annotations tab to details-panel folder
* Convert to 2 space indent
* Cleanup props with deconstruction
* Subsume old annotations controller into component
This helps prevent:
https://www.owasp.org/index.php/Reverse_Tabnabbing
We're not also using `noreferrer`, since most browsers now support
`noopener` (https://caniuse.com/#search=noopener) and the link targets
are all Mozilla properties where the referrer may be useful.
The auth.js `window.open()` has not been changed, since the login
callback makes use of `window.opener`.
This was using an angular $timeout in the thPinboard service addBug
function. That caused the value to not be persisted. Moved the $timeout
to the ReactJS failure_summary_panel since that's where it's needed.
This also fixes Bug 1438315 - Pinned jobs take a long time
to show the annotation. These two bugs were related so it
made sense to fix them at the same time.
This adds some new components and removes the AngularJS ng-repeat for
pushes. In the course of this work, some of the AngularJS providers were
converted to helper functions.
In a couple cases, I had to add new code to the AngularJS areas so that it
would continue to interact well between Angular and React.
Also:
* Rename some functions and CSS classes from resultset to push
* Add unlistening for events during unmount of components
Since it's not being used. This will save us having to convert it to
React for now, and also means one less thing slowing down our builds.
Should it be needed in the future, it can be resurrected using the
Git log.
In case:
* multiple tabs are trying to renew at the same time, where one
tab will throw an error hence logging users out
* the renewal fails for transient reasons (eg wifi not re-established
after machine resumes from sleep)
This replaces the logic that was in clonejobs.js that formerly
handled rendering the pushes, platforms and jobs and converts it to
ReactJS. The ReactJS code is hosted as a directive in AngularJS
using ngReact reactDirective.
This also removes the feature where you can hide revisions because
it was believed to not be used and added unnecessary complications
to the code.
Co-authored-by: Casey Williams cwillia5@gmail.com
With ES6, the `'use strict'` directives are unnecessary:
https://eslint.org/docs/rules/strict
The directives have been left in the Neutrino configs, since they
are used by node directly, which doesn't yet support ES6 modules.
## Rough summary of the changes
### Front end
The auth callback is written in React and lives under the /login.html endpoint. It communicates with Treeherder using the localStorage.
### Credential expiration
The Django user session expiration is set to expire when the client access token or the id token expires (whichever one expires first). These values are controlled by the IAM team. Presently, the access token expires after 1 day and the id token expires after a week. That being said, the session will therefore expire after 1 day. If you want this value change, we simply need to send a request to the IAM team.
### Credential renewal
Renewals are set to happen every 15 minutes or so. The renewal is skewed slightly so that different open tabs don't renew at the same time. Once renewal happens, both tokens are renewed and the Django session is updated.
### Migration
If the userSession localStorage key is not set, then the user will be logged out including logging out from the Django session. In other words, all users will be automatically logged out when the merge to production happens.
In `configureStore.js` the same object was being exported twice, once
as the default export and once as a named export. Since default exports
are preferred if there is only one export in a file, I've removed the
named import and left the default one.
In `Groups.jsx` the `Groups` class was exported but unused, so has
been adjusted to no longer be exported, so the `App.jsx` import
doesn't trigger the warning:
`import Groups from './Groups';`
See:
https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-named-as-default.md
Currently `revision.txt` only exists on Heroku, since it's generated
by the Heroku-only `post_compile` script, just prior to `yarn build`.
However this means:
* HTTP 404s of `revision.txt` are seen in the browser console when
developing locally, which gives the appearance of something being
broken, even though it's not.
* when we convert the wildcard `CopyPlugin` rule to an explicit list
of files to copy (in a later commit), it will cause errors when
building locally, since `CopyPlugin` expects all declared files
to exist.
Adding a placeholder file prevents both of the above.
This ensures that webpack knows they are a dependency, meaning:
* no need to manually copy them to `dist/img/` using `CopyPlugin`
(the wildcard copy rules will be cleaned up in a later commit)
* they are inlined as a base64 encoded data URI by `url-loader`.
The changes to `thFaviconLink` are required to prevent:
```
Error: [$interpolate:interr] Can't interpolate: {{favicon}}
Error: [$sce:insecurl] Blocked loading resource from url not allowed
by $sceDelegate policy. URL: data:image/png;base64,...
```
Which are due to AngularJS not trusting data URIs by default. See:
https://docs.angularjs.org/error/$sce/insecurl
Neutrino 4 configures `file-loader` as the loader for HTML (rather than
the more usual `html-loader`), which means the HTML is not parsed to
look for further dependencies such as `<img src="...">` tags. Our
custom Neutrino config overrode that to `raw-loader` (presumably to
work around bugs caused by the use of `file-loader`), which doesn't
parse HTML either.
Instead, these assets were being manually copied to `dist/img/` by
`neutrino-custom/production.js`'s `CopyPlugin` rule, effectively
circumventing the webpack build process.
Newer Neutrino correctly uses `html-loader`, causing our HTML to be
parsed during the webpack build for the first time. However now that
the images are being resolved at build time rather than runtime, the
relative paths need to be updated to account for the directory layout
differences between `src/` and `dist/`, to prevent build errors.
A significant benefit of this change is that images referenced from
HTML will now be output with hashed filenames, meaning they get given
long-lived `Cache-Control` headers by WhiteNoise.
See:
https://webpack.js.org/loaders/file-loader/https://webpack.js.org/loaders/raw-loader/https://webpack.js.org/loaders/html-loader/
Presently, when the build system of a job is buildbot, there is a hyper
link on the machine name that takes a user to the slave health
dashboard. When a job runs outside of buildbot, there is a worker
explorer. A worker explorer shows information like most recent task IDs
claimed. Also, a user can perform actions on the machine if they own the
required scopes (e.g., quarantine & terminate instance). This commit
provides a shortcut to the worker explorer when the build system is not
buildbot.
AngularJS 1.6 made bindings no longer be pre-assigned by default,
which breaks Perfherder's compare view, since the controller relies
on the bindings being present at initialisation. Until it is adjusted
to use the new `$onInit()` method, the legacy mode has been re-enabled:
https://docs.angularjs.org/guide/migration#commit-bcd0d4
Found by adjusting the eslint `no-unused-vars` rule, changing the
`args` preference from `after-used` to `all`:
https://eslint.org/docs/rules/no-unused-vars.html#options
That rule is too noisy to enable by default. Ideally we could use the
AngularJS eslint plugin/config (which has specific rules for this),
but it's not compatible with latest eslint:
https://github.com/Gillespie59/eslint-plugin-angular/issues/490
Unless these DI parameters can have side-effects I'm not aware of,
this change should be reasonably safe, since eslint's `no-undef` rule
will error if anything was removed that was being directly referenced.
Angular v1.4.4 deprecated `$http`'s `.success()` and `.error()`
callbacks in favour of `.then()` and `.catch()`. The deprecated forms
are finally removed in Angular 1.6, so we need to stop using them:
https://docs.angularjs.org/guide/migration#-http-
It wasn't unvendored at the time of the switch to Neutrino/webpack
due to the official `flot` NPM package being out of date. However
there are now unofficial up to date flot packages on NPM that we can
use instead - which avoids the clutter and grep false-positives of
vendoring.
I've diffed the vendored files with those in `jquery.flot` and they
are identical, so this change should be a no-op in terms of
functionality.
The issue seen with the old Grunt+babel build process no longer
occurs, so we don't need the modified vendored version. As an added
bonus, the upstream version supports the ES6 import style which we
want to start using soon:
https://github.com/omichelsen/angular-clipboard#use-with-a-module-loader
This reverts commit b37ef957a2.
There appears to be a bug with the webpack module resolution, such that Treeherder's upgraded Hawk 7 is being used by taskcluster-client, even though that has a separate dependency on Hawk 6, and so should be using its own copy of Hawk.
For now, let's roll back to Hawk 7 for Treeherder's direct dependency (used by the login flow), to work around this.
Modify the code to:
* share assets and global settings wherever possible
* update links going both directions
* other small UI tweaks for uniformity with Treeherder
* Fixed a few routing dead-ends on the react side
* Removed the dead TestDetail file we weren't using anyway
* fix production domain urls
Since everything but standard retrigger/cancellation is now handled
client-side by tcactions, making the backend parts that provided pulse
messages to pulse_actions redundant (since it was decommissioned in
bug 1379172).
This also fixes linking to specific datapoints on the graph from the job
detail view, which was broken. Note that the links are not backwards
compatible, but people linking to selected datapoints in graphs is pretty
rare (and the links are highly time-sensitive in any case).
This changes the times shown in the UI to be padded with a leading
zero if the hour is only a single digit (ie between midnight and 10am).
This fixes the test failure in `test_open_single_result()`, since
that expects the hour to use padding.
Now that no submissions are using revision_hash, it can be removed.
This removes everything but the model field, which will be handled
later.
I've removed revision_hash from the Pulse jobs schema without bumping
the version, which wouldn't normally be ok, but no one is still using
it, and I'd rather have explicit failures later than if we left the
schema unchanged.
This means we no longer display tests as being a "summary" in the
test chooser (you can generally figure that out by noticing that there
is no subtest specified).
Windows can show double-bolding with "font-weight: bolder". But our
logic for highlighting common terms sometimes adds nested <strong>
elements due to substrings. This makes them all just "bold" regardless
of how much they're nested.
This means we no longer display tests as being a "summary" in the
test chooser (you can generally figure that out by noticing that there
is no subtest specified).
When moving a _.filter() function to Array.filter(), an
"s" was left out throwing a type error. $scope.highlightedRevision
should have been $scope.highlightedRevisions
Remove existing lodash filter function and replace with
es6's array.filter(). Some whitespace changes were
made for clarity or because the linter got upset.
Also upgrade Enzyme from 2.7.1 to 3.1.1
Most notable change here is that React.PropTypes is now
moved to a separate package and referenced just by
PropTypes. So this needed some import and linting changes.
* Make the performance data api accept signature id as input
* Rewrite most of the frontend to use that API in preference to passing
in signature hashes
* Correspondingly increase the chunks of comparison data we fetch
at once
This adds the upgrade to Bootstrap 4, and some basic changes and
some CSS tweaks we needed to keep out UI consistent.
The simpler changes are things like:
* Classes that were renamed
* Adding classes that are now needed (dropdown-item, etc)
* Change an item from a button to a span
* Changing order of items (modal header close button, etc)
* CSS class syntax changes
The other changes are lots of CSS padding, margin, font and
other spacing tweaks.
It used toLocaleFormat, which was never standard and seems to no longer be defined
in recent Firefox versions. Use toUTCString instead, which seems to be available
everywhere.