diff --git a/tests/push_health/test_compare.py b/tests/push_health/test_compare.py index 89218d428..b05f5e539 100644 --- a/tests/push_health/test_compare.py +++ b/tests/push_health/test_compare.py @@ -3,12 +3,12 @@ import datetime import responses from treeherder.model.models import Push -from treeherder.push_health.compare import (get_parent, +from treeherder.push_health.compare import (get_commit_history, get_response_object) def test_get_response_object(test_push, test_repository): - resp = get_response_object('1234', test_push, test_repository) + resp = get_response_object('1234', [1, 2], 2, test_push, test_repository) assert resp['parentSha'] == '1234' assert resp['id'] == 1 assert resp['exactMatch'] is False @@ -16,7 +16,7 @@ def test_get_response_object(test_push, test_repository): @responses.activate -def test_get_parent(test_push, test_repository): +def test_get_commit_history_automationrelevance(test_push, test_repository): test_revision = '4c45a777949168d16c03a4cba167678b7ab65f76' parent_revision = 'abcdef77949168d16c03a4cba167678b7ab65f76' Push.objects.create( @@ -25,28 +25,101 @@ def test_get_parent(test_push, test_repository): author='foo@bar.baz', time=datetime.datetime.now() ) - commits_url = '{}/json-pushes?version=2&full=1&changeset={}'.format( - test_repository.url, test_revision) - commits = {'pushes': {1: {'changesets': [{'parents': [parent_revision]}]}}} - responses.add(responses.GET, commits_url, json=commits, content_type='application/json', status=200) + autorel_commits = {'changesets': [ + { + 'author': 'Cheech Marin ', 'backsoutnodes': [], + 'desc': 'Bug 1612891 - Suppress parsing easing error in early returns of ConvertKeyframeSequence.\n\nWe add a stack based class and supress the exception of parsing easing\nin the destructor, to avoid hitting the potential assertions.\n\nDifferential Revision: https://phabricator.services.mozilla.com/D64268\nDifferential Diff: PHID-DIFF-c4e7dcfpalwiem7bxsnk', + 'node': '3ca259f9cbdea763e64f10e286e58b271d89ab9d', + 'parents': [parent_revision], + }, + { + 'author': 'libmozevent ', + 'desc': 'try_task_config for https://phabricator.services.mozilla.com/D64268\nDifferential Diff: PHID-DIFF-c4e7dcfpalwiem7bxsnk', + 'node': '18f68eb12ebbd88fe3a4fc3afe7df6529a0153fb', + 'parents': ['3ca259f9cbdea763e64f10e286e58b271d89ab9d'], + } + ], 'visible': True} - parent = get_parent(test_repository, test_revision, test_push) - assert parent['parentSha'] == parent_revision - assert parent['revision'] == parent_revision + autorel_url = 'https://hg.mozilla.org/{}/json-automationrelevance/{}'.format( + test_repository.name, test_revision) + responses.add( + responses.GET, + autorel_url, + json=autorel_commits, + content_type='application/json', + status=200 + ) + + history = get_commit_history(test_repository, test_revision, test_push) + assert history['parentSha'] == parent_revision + assert history['revision'] == parent_revision @responses.activate -def test_get_parent_not_found(test_push, test_repository): +def test_get_commit_history_json_pushes(test_push, test_repository): + test_revision = '4c45a777949168d16c03a4cba167678b7ab65f76' + parent_revision = 'abcdef77949168d16c03a4cba167678b7ab65f76' + Push.objects.create( + revision=parent_revision, + repository=test_repository, + author='foo@bar.baz', + time=datetime.datetime.now() + ) + + autorel_url = 'https://hg.mozilla.org/{}/json-automationrelevance/{}'.format( + test_repository.name, test_revision) + responses.add( + responses.GET, + autorel_url, + json={}, + content_type='application/json', + status=500 + ) + + jsonpushes_commits = { + 'pushes': {'108872': {'changesets': [ + { + 'author': 'Hiro Protagonist ', + 'desc': 'Bug 1617666 - Use a separate Debugger to improve performance of eval.', + 'node': '4fb5e268cf7440332e917e431f14e8bb6dc41a0d', + 'parents': [parent_revision], + } + ]}} + } + commits_url = '{}/json-pushes?version=2&full=1&changeset={}'.format( + test_repository.url, test_revision) + responses.add( + responses.GET, + commits_url, + json=jsonpushes_commits, + content_type='application/json', + status=200 + ) + + history = get_commit_history(test_repository, test_revision, test_push) + assert history['parentSha'] == parent_revision + assert history['revision'] == parent_revision + + +@responses.activate +def test_get_commit_history_not_found(test_push, test_repository): test_revision = '4c45a777949168d16c03a4cba167678b7ab65f76' # Does not exist as a Push in the DB. parent_revision = 'abcdef77949168d16c03a4cba167678b7ab65f76' commits_url = '{}/json-pushes?version=2&full=1&changeset={}'.format( test_repository.url, test_revision) - commits = {'pushes': {1: {'changesets': [{'parents': [parent_revision]}]}}} + commits = {'pushes': {1: {'changesets': [ + { + 'author': 'Boris Chiou ', 'backsoutnodes': [], + 'desc': 'Bug 1612891 - Suppress parsing easing error in early returns of ConvertKeyframeSequence.\n\nWe add a stack based class and supress the exception of parsing easing\nin the destructor, to avoid hitting the potential assertions.\n\nDifferential Revision: https://phabricator.services.mozilla.com/D64268\nDifferential Diff: PHID-DIFF-c4e7dcfpalwiem7bxsnk', + 'node': '3ca259f9cbdea763e64f10e286e58b271d89ab9d', + 'parents': [parent_revision], + }, + ]}}} responses.add(responses.GET, commits_url, json=commits, content_type='application/json', status=200) - parent = get_parent(test_repository, test_revision, test_push) + parent = get_commit_history(test_repository, test_revision, test_push) assert parent['parentSha'] == parent_revision assert parent['revision'] is None diff --git a/tests/ui/mock/push_health.json b/tests/ui/mock/push_health.json index 038532589..86f1bce30 100644 --- a/tests/ui/mock/push_health.json +++ b/tests/ui/mock/push_health.json @@ -3,8 +3,8 @@ "id": 630837, "result": "fail", "metrics": { - "parent": { - "name": "Parent", + "commitHistory": { + "name": "Commit History", "result": "none", "details": { "parentSha": "eeb6fd68c0223a72d8714734a34d3e6da69995e1", @@ -35,7 +35,40 @@ "running": 0, "success": 293, "testfailed": 5 - } + }, + "revisions": [ + { + "comments": "Bug 1596812 Part 1 - Update our custom nsisui.exe. r=agashlin\n\nSummary:\n\nMinify this file by removing the dialogs we don't need and hide all the\nunnecessary controls in the one we do need, so the stub installer code\ndoesn't have to do that manually (I would have removed those controls\naltogether, but the NSIS compiler errors out if you do that).\n\nDifferential Revision: https://phabricator.services.mozilla.com/D56576\n\n\n\nTest Plan:\n\nReviewers: agashlin\n\nSubscribers:\n\nBug #: 1596812\nDifferential Diff: PHID-DIFF-2cdiggedu3yo3ijopy7k", + "author": "Molly Howell ", + "revision": "298d6ae2f80cad932f8ec605395e7d263c86e734" + }, + { + "comments": "Bug 1596812 Part 2 - NSIS WebBrowser plugin. r=agashlin\n\nSummary:\n\nThis is all the code and build files for an NSIS plugin that enables\nrendering a web page as the content of an NSIS dialog.\n\nDocumentation and the compiled binary are in later commits in this series.\n\nDifferential Revision: https://phabricator.services.mozilla.com/D56577\n\nDepends on D56576\n\nTest Plan:\n\nReviewers: agashlin\n\nSubscribers:\n\nBug #: 1596812\nDifferential Diff: PHID-DIFF-qxemgpfgytrfewwdnp3c", + "author": "Molly Howell ", + "revision": "c639aa34f1249c0b280ad71b7a131c8a8bd40a28" + }, + { + "comments": "Bug 1596812 Part 3 - Compiled binary for the WebBrowser plugin. r=agashlin\n\nSummary:\n\nDifferential Revision: https://phabricator.services.mozilla.com/D56579\n\nDepends on D56577\n\nTest Plan:\n\nReviewers: agashlin\n\nSubscribers:\n\nBug #: 1596812\nDifferential Diff: PHID-DIFF-thzbkzegigfe45ytmmq3", + "author": "Molly Howell ", + "revision": "9ee489147076c8776003ff47bbf7ba4122afda44" + }, + { + "comments": "Bug 1596812 Part 4 - Add the WebBrowser plugin to the installer build files. r=agashlin\n\nSummary:\n\nDifferential Revision: https://phabricator.services.mozilla.com/D56580\n\nDepends on D56579\n\nTest Plan:\n\nReviewers: agashlin\n\nSubscribers:\n\nBug #: 1596812\nDifferential Diff: PHID-DIFF-fczkua6yvptm5a7nhwdj", + "author": "Molly Howell ", + "revision": "8dff5e5e9e4fa080e93fa358e42fd2422d1e2d60" + }, + { + "comments": "Bug 1596812 Part 5 - Add the web content files and include them in the installer build. r=agashlin\n\nSummary:\n\nDifferential Revision: https://phabricator.services.mozilla.com/D56581\n\nDepends on D56580\n\nTest Plan:\n\nReviewers: agashlin\n\nSubscribers:\n\nBug #: 1596812\nDifferential Diff: PHID-DIFF-klktifjsu4dzhdvk5464", + "author": "Molly Howell ", + "revision": "d00d10fe888660fe536a6e6e3f2a243c0a70431c" + }, + { + "comments": "try_task_config for https://phabricator.services.mozilla.com/D56581\nDifferential Diff: PHID-DIFF-klktifjsu4dzhdvk5464", + "author": "libmozevent ", + "revision": "62489dedc9c4af40387b91993fa70b0e643b6b71" + } + ], + "revisionCount": 6 } }, "linting": { "name": "Linting", "result": "pass", "details": [] }, diff --git a/tests/ui/push-health/CommitHistory_test.jsx b/tests/ui/push-health/CommitHistory_test.jsx new file mode 100644 index 000000000..6e8a114e4 --- /dev/null +++ b/tests/ui/push-health/CommitHistory_test.jsx @@ -0,0 +1,85 @@ +import React from 'react'; +import fetchMock from 'fetch-mock'; +import { render, cleanup, waitForElement } from '@testing-library/react'; + +import CommitHistory from '../../../ui/push-health/CommitHistory'; +import pushHealth from '../mock/push_health'; + +beforeEach(() => { + fetchMock.get( + '/api/project/autoland/push/health_summary/?revision=eeb6fd68c0223a72d8714734a34d3e6da69995e1', + { needInvestigation: 87, unsupported: 8 }, + ); +}); + +afterEach(() => { + cleanup(); + fetchMock.reset(); +}); + +describe('CommitHistory', () => { + const testCommitHistory = history => ; + + test('should show a parent commit and health icon for that parent', async () => { + const { details: commitHistory } = pushHealth.metrics.commitHistory; + const { getByText, queryByTestId } = render( + testCommitHistory(commitHistory), + ); + expect( + getByText('eeb6fd68c0223a72d8714734a34d3e6da69995e1'), + ).toBeInTheDocument(); + expect( + queryByTestId('health-status-eeb6fd68c0223a72d8714734a34d3e6da69995e1'), + ).not.toBeInTheDocument(); + expect( + await waitForElement(() => getByText('87 items')), + ).toBeInTheDocument(); + }); + + test('should show warning if not exact commit match', async () => { + const { details: commitHistory } = pushHealth.metrics.commitHistory; + + commitHistory.id = 123; + commitHistory.parentSha = '00000827c820f34b3b595f887f57b4c847316fcc'; + commitHistory.exactMatch = false; + + const { getByText } = render(testCommitHistory(commitHistory)); + expect( + getByText( + 'Warning: Could not find an exact match parent Push in Treeherder.', + ), + ).toBeInTheDocument(); + expect(getByText('Closest match:')).toBeInTheDocument(); + expect( + getByText('eeb6fd68c0223a72d8714734a34d3e6da69995e1'), + ).toBeInTheDocument(); + expect( + getByText('00000827c820f34b3b595f887f57b4c847316fcc'), + ).toBeInTheDocument(); + expect( + await waitForElement(() => getByText('87 items')), + ).toBeInTheDocument(); + }); + + test('should not have parent PushHealthStatus if no push id', async () => { + const { details: commitHistory } = pushHealth.metrics.commitHistory; + + commitHistory.id = null; + commitHistory.parentSha = '00000827c820f34b3b595f887f57b4c847316fcc'; + commitHistory.exactMatch = false; + + const { getByText, queryByTestId } = render( + testCommitHistory(commitHistory), + ); + expect( + await waitForElement(() => + getByText( + 'Warning: Could not find an exact match parent Push in Treeherder.', + ), + ), + ).toBeInTheDocument(); + expect( + queryByTestId('health-status-eeb6fd68c0223a72d8714734a34d3e6da69995e1'), + ).not.toBeInTheDocument(); + }); +}); diff --git a/tests/ui/push-health/PushParent_test.jsx b/tests/ui/push-health/PushParent_test.jsx deleted file mode 100644 index 31f91053b..000000000 --- a/tests/ui/push-health/PushParent_test.jsx +++ /dev/null @@ -1,114 +0,0 @@ -import React from 'react'; -import fetchMock from 'fetch-mock'; -import { render, cleanup, waitForElement } from '@testing-library/react'; - -import ParentPush from '../../../ui/push-health/ParentPush'; - -beforeEach(() => { - fetchMock.get( - '/api/project/mozilla-central/push/health_summary/?revision=76ee1827c820f34b3b595f887f57b4c847316fcc', - { needInvestigation: 87, unsupported: 8 }, - ); -}); - -afterEach(() => { - cleanup(); - fetchMock.reset(); -}); - -const getParent = ( - id = 636452, - parentSha = '76ee1827c820f34b3b595f887f57b4c847316fcc', - exactMatch = true, -) => { - return { - parentSha, - exactMatch, - revision: '76ee1827c820f34b3b595f887f57b4c847316fcc', - repository: { - id: 1, - repository_group: { - name: 'development', - description: - 'Collection of repositories where code initially lands in the development process', - }, - name: 'mozilla-central', - dvcs_type: 'hg', - url: 'https://hg.mozilla.org/mozilla-central', - branch: null, - codebase: 'gecko', - description: '', - active_status: 'active', - performance_alerts_enabled: false, - expire_performance_data: false, - is_try_repo: false, - tc_root_url: 'https://firefox-ci-tc.services.mozilla.com', - }, - id, - jobCounts: { - completed: 8117, - pending: 236, - running: 117, - success: 8025, - retry: 40, - testfailed: 52, - }, - }; -}; - -describe('PushParent', () => { - const testPushParent = parent => ; - - test('should show a parent commit and health icon for that parent', async () => { - const parent = getParent(); - const { getByText, queryByTestId } = render(testPushParent(parent)); - expect( - getByText('76ee1827c820f34b3b595f887f57b4c847316fcc'), - ).toBeInTheDocument(); - expect( - queryByTestId('health-status-76ee1827c820f34b3b595f887f57b4c847316fcc'), - ).not.toBeInTheDocument(); - expect( - await waitForElement(() => getByText('87 items')), - ).toBeInTheDocument(); - }); - - test('should show warning if not exact commit match', async () => { - const parent = getParent( - 123, - '00000827c820f34b3b595f887f57b4c847316fcc', - false, - ); - const { getByText } = render(testPushParent(parent)); - expect( - getByText('Warning: Could not find an exact match parent Push.'), - ).toBeInTheDocument(); - expect(getByText('Closest match:')).toBeInTheDocument(); - expect( - getByText('76ee1827c820f34b3b595f887f57b4c847316fcc'), - ).toBeInTheDocument(); - expect( - getByText('00000827c820f34b3b595f887f57b4c847316fcc'), - ).toBeInTheDocument(); - expect( - await waitForElement(() => getByText('87 items')), - ).toBeInTheDocument(); - }); - - test('should not have parent PushHealthStatus if no push id', async () => { - const parent = getParent( - null, - '00000827c820f34b3b595f887f57b4c847316fcc', - false, - ); - const { getByText, queryByTestId } = render(testPushParent(parent)); - expect( - await waitForElement(() => - getByText('Warning: Could not find an exact match parent Push.'), - ), - ).toBeInTheDocument(); - expect( - queryByTestId('health-status-76ee1827c820f34b3b595f887f57b4c847316fcc'), - ).not.toBeInTheDocument(); - }); -}); diff --git a/treeherder/push_health/compare.py b/treeherder/push_health/compare.py index 70b33386b..24b458335 100644 --- a/treeherder/push_health/compare.py +++ b/treeherder/push_health/compare.py @@ -8,7 +8,7 @@ from treeherder.webapp.api.serializers import RepositorySerializer logger = logging.getLogger(__name__) -def get_response_object(parent_sha, push, repository): +def get_response_object(parent_sha, revisions, revision_count, push, repository): resp = { 'parentSha': parent_sha, 'exactMatch': False, @@ -16,6 +16,8 @@ def get_response_object(parent_sha, push, repository): 'repository': RepositorySerializer(repository).data, 'id': None, 'jobCounts': None, + 'revisions': revisions, + 'revisionCount': revision_count, } if push: resp.update({ @@ -27,49 +29,75 @@ def get_response_object(parent_sha, push, repository): return resp -def get_parent(repository, revision, push): +def commit_to_revision(commit): + return { + 'comments': commit['desc'], + 'author': commit['author'], + 'revision': commit['node'], + } + + +def get_commits(repository, revision): # This gets the list of revisions for the push. Treeherder only holds the the last 20 per push, so we may # not have the oldest one. - commits_url = '{}/json-pushes?version=2&full=1&changeset={}'.format(repository.url, revision) - try: - parent_resp = list(fetch_json(commits_url)["pushes"].values())[0] - eldest_commit = parent_resp['changesets'][0] - parent_sha = eldest_commit['parents'][0] - parent_pushes = Push.objects.filter(revision=parent_sha) - len_parents = len(parent_pushes) - logger.error('len parents {}'.format(len_parents)) + autorel_resp = fetch_json( + 'https://hg.mozilla.org/{}/json-automationrelevance/{}'.format( + repository.name, revision)) - if len_parents == 1: - parent_push = parent_pushes[0] - return get_response_object(parent_sha, parent_push, parent_push.repository) + return list(autorel_resp["changesets"]) + except Exception: + # fallback to using json-pushes - elif len_parents > 1: - mc_pushes = parent_pushes.filter(repository__name='mozilla-central') - if len(mc_pushes): - logger.error('mc_pushes {}'.format(mc_pushes)) - # we have more than one parent push on mozilla-central. Just pick the - # first one. No way to know which one is more correct. - mc_push = mc_pushes[0] - return get_response_object(parent_sha, mc_push, mc_push.repository) + try: + json_pushes_resp = fetch_json( + '{}/json-pushes?version=2&full=1&changeset={}'.format( + repository.url, revision)) + changesets = list(json_pushes_resp["pushes"].values())[0]['changesets'] + changesets.reverse() - # we have more than one push that matches, but not one in m-c, - # so let's see what we have. - for parent in parent_pushes: - logger.error('parent with repo {}'.format(parent.repository.name)) + return changesets + except Exception as json_push_ex: + raise json_push_ex - # This parent doesn't have its own push, so look for it in the commits table - # If there are multiple, we don't have a way to know which is the "right" one, - # so pick the first. If the only one is a commit for the push in question, then - # skip it. - commits = Commit.objects.filter(revision=revision) - for commit in commits: - if commit.push.revision != revision: - return get_response_object(parent_sha, commit.push, commit.push.repository) - # We can't find any mention of this commit, so return what we have. Hope - # for the best that it's in the same repository as the push in question. - return get_response_object(parent_sha, None, repository) +def get_commit_history(repository, revision, push): + commits = get_commits(repository, revision) or [] + revisions = [commit_to_revision(commit) for commit in commits] + revision_count = push.commits.count() + parent_sha = commits[0]['parents'][0] + parent_pushes = Push.objects.filter(revision=parent_sha) + len_parents = len(parent_pushes) - except Exception as e: - logger.exception(e) + if len_parents == 1: + parent_push = parent_pushes[0] + return get_response_object( + parent_sha, revisions, revision_count, parent_push, parent_push.repository + ) + + elif len_parents > 1: + mc_pushes = parent_pushes.filter(repository__name='mozilla-central') + if len(mc_pushes): + # we have more than one parent push on mozilla-central. Just pick the + # first one. No way to know which one is more correct. + mc_push = mc_pushes[0] + return get_response_object( + parent_sha, revisions, revision_count, mc_push, mc_push.repository + ) + + # This parent doesn't have its own push, so look for it in the commits table + # If there are multiple, we don't have a way to know which is the "right" one, + # so pick the first. If the only one is a commit for the push in question, then + # skip it. + commits = Commit.objects.filter(revision=revision) + for commit in commits: + if commit.push.revision != revision: + return get_response_object( + parent_sha, commits, revision_count, commit.push, commit.push.repository + ) + + # We can't find any mention of this commit, so return what we have. Hope + # for the best that it's in the same repository as the push in question. + return get_response_object( + parent_sha, revisions, revision_count, None, repository + ) diff --git a/treeherder/webapp/api/push.py b/treeherder/webapp/api/push.py index 67fa024a6..75123f5ea 100644 --- a/treeherder/webapp/api/push.py +++ b/treeherder/webapp/api/push.py @@ -14,7 +14,7 @@ from treeherder.model.models import (Job, Push, Repository) from treeherder.push_health.builds import get_build_failures -from treeherder.push_health.compare import get_parent +from treeherder.push_health.compare import get_commit_history from treeherder.push_health.linting import get_lint_failures from treeherder.push_health.performance import get_perf_failures from treeherder.push_health.tests import get_test_failures @@ -252,7 +252,8 @@ class PushViewSet(viewsets.ViewSet): # Parent link only supported for Hg at this time. # Bug https://bugzilla.mozilla.org/show_bug.cgi?id=1612645 - parent_details = None if repository.dvcs_type == 'git' else get_parent(repository, revision, push) + commit_history_details = None if repository.dvcs_type == 'git' \ + else get_commit_history(repository, revision, push) build_failures = get_build_failures(push) build_result = 'fail' if len(build_failures) else 'pass' @@ -275,10 +276,10 @@ class PushViewSet(viewsets.ViewSet): 'id': push.id, 'result': push_result, 'metrics': { - 'parent': { - 'name': 'Parent Push', + 'commitHistory': { + 'name': 'Commit History', 'result': 'none', - 'details': parent_details, + 'details': commit_history_details, }, 'linting': { 'name': 'Linting', diff --git a/ui/push-health/CommitHistory.jsx b/ui/push-health/CommitHistory.jsx new file mode 100644 index 000000000..43253e198 --- /dev/null +++ b/ui/push-health/CommitHistory.jsx @@ -0,0 +1,113 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Alert } from 'reactstrap'; + +import PushHealthStatus from '../shared/PushHealthStatus'; +import { RevisionList } from '../shared/RevisionList'; +import { getJobsUrl } from '../helpers/url'; +import RepositoryModel from '../models/repository'; +import Clipboard from '../shared/Clipboard'; + +class CommitHistory extends React.PureComponent { + constructor(props) { + super(props); + + this.state = { + clipboardVisible: false, + }; + } + + showClipboard = show => { + this.setState({ clipboardVisible: show }); + }; + + render() { + const { + history: { + repository, + revision, + jobCounts, + exactMatch, + parentSha, + id, + revisions, + revisionCount, + }, + } = this.props; + const { clipboardVisible } = this.state; + const repoModel = new RepositoryModel(repository); + + return ( + +
Parent Push
+ {!exactMatch && ( +
+
this.showClipboard(true)} + onMouseLeave={() => this.showClipboard(false)} + > + + + {parentSha} + +
+ + Warning: Could not find an exact match parent Push in Treeherder. + + {id &&
Closest match:
} +
+ )} + {id && ( + + )} +
Commit revisions
+ +
+ ); + } +} + +CommitHistory.propTypes = { + history: PropTypes.shape({ + repository: PropTypes.object.isRequired, + revision: PropTypes.string.isRequired, + revisionCount: PropTypes.number.isRequired, + job_counts: PropTypes.shape({ + completed: PropTypes.number.isRequired, + pending: PropTypes.number.isRequired, + running: PropTypes.number.isRequired, + }), + id: PropTypes.number, + }).isRequired, +}; + +export default CommitHistory; diff --git a/ui/push-health/Health.jsx b/ui/push-health/Health.jsx index e89a3dff4..168319634 100644 --- a/ui/push-health/Health.jsx +++ b/ui/push-health/Health.jsx @@ -30,7 +30,7 @@ import Metric from './Metric'; import Navigation from './Navigation'; import TestMetric from './TestMetric'; import JobListMetric from './JobListMetric'; -import ParentPush from './ParentPush'; +import CommitHistory from './CommitHistory'; export default class Health extends React.PureComponent { constructor(props) { @@ -47,7 +47,7 @@ export default class Health extends React.PureComponent { failureMessage: null, notifications: [], progressExpanded: true, - parentPushExpanded: false, + commitHistoryExpanded: false, lintingExpanded: false, buildsExpanded: false, testsExpanded: false, @@ -159,14 +159,14 @@ export default class Health extends React.PureComponent { notifications, status, progressExpanded, - parentPushExpanded, + commitHistoryExpanded, lintingExpanded, buildsExpanded, testsExpanded, performanceExpanded, searchStr, } = this.state; - const { tests, parent, linting, builds, performance } = metrics; + const { tests, commitHistory, linting, builds, performance } = metrics; const { currentRepo } = this.props; const percentComplete = status ? getPercentComplete(status) : 0; const progress = { @@ -190,40 +190,45 @@ export default class Health extends React.PureComponent { {!!tests && (