diff --git a/.zuul.yaml b/.zuul.yaml index fd65092f1b..1642e25c7d 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -1007,6 +1007,32 @@ - playbooks/roles/zuul-preview/ - testinfra/test_zuul_preview.py +- job: + name: system-config-run-review-dev + parent: system-config-run + description: | + Run the playbook for gerrit (in a container). + nodeset: + nodes: + - name: bridge.openstack.org + label: ubuntu-bionic + - name: review-dev01.openstack.org + label: ubuntu-bionic + vars: + run_playbooks: + - playbooks/service-review-dev.yaml + host-vars: + review-dev01.openstack.org: + host_copy_output: + '/home/gerrit2/review_site/etc': logs + '/home/gerrit2/review_site/logs': logs + files: + - playbooks/group_vars/review-dev.yaml + - ^playbooks/host_vars/review-dev\d+.opendev.org.yaml + - playbooks/zuul/templates/group_vars/review.yaml.j2 + - playbooks/roles/gerrit/ + - testinfra/test_gerrit.py + - job: name: infra-prod-playbook description: | @@ -1064,6 +1090,7 @@ soft: true - name: system-config-build-image-haproxy-statsd soft: true + - system-config-run-review-dev - system-config-run-zuul-preview - system-config-run-letsencrypt - system-config-build-image-bazel @@ -1123,6 +1150,7 @@ soft: true - name: system-config-upload-image-haproxy-statsd soft: true + - system-config-run-review-dev - system-config-run-zuul-preview - system-config-run-letsencrypt - system-config-upload-image-bazel diff --git a/modules/openstack_project/files/gerrit/web_server.py b/modules/openstack_project/files/gerrit/web_server.py deleted file mode 100755 index 8c61a122b6..0000000000 --- a/modules/openstack_project/files/gerrit/web_server.py +++ /dev/null @@ -1,178 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2015 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -This is a simple test server that serves up the web content locally -as if it was a working remote server. It also proxies all the live -date/*.json files into the local test server, so that the Ajax async -loading works without hitting Cross Site Scripting violations. -""" - -import argparse -import BaseHTTPServer -import os.path -import urllib2 - -import requests - -# Values for these set via cli defaults -GERRIT_UPSTREAM = "" -ZUUL_UPSTREAM = "" - - -def replace_urls(line, port): - line = line.replace( - GERRIT_UPSTREAM, - "http://localhost:%s" % port) - line = line.replace( - ZUUL_UPSTREAM, - "http://localhost:%s" % port) - return line - - -class GerritHandler(BaseHTTPServer.BaseHTTPRequestHandler): - """A request handler to create a magic local Gerrit server""" - - def do_POST(self): - data = self.rfile.read(int(self.headers['content-length'])) - headers = {} - # we need to trim some of the local headers in order for this - # request to remain valid. - for header in self.headers: - if header not in ("host", "origin", "connection"): - headers[header] = self.headers[header] - resp = requests.post("%s%s" % - (GERRIT_UPSTREAM, self.path), - headers=headers, - data=data) - - # Process request back to client - self.send_response(resp.status_code) - for header in resp.headers: - # Requests has now decoded the response so it's no longer - # a gzip stream, which also means content-length is - # wrong. So we remove content-encoding, then drop - # content-length because if provided Gerrit strictly uses - # it for reads. We also drop all the keep-alive related - # headers, our server doesn't do that. - if header not in ("connection", "content-length", - "keep-alive", "content-encoding"): - self.send_header(header, resp.headers[header]) - self.end_headers() - self.wfile.write(resp.text) - - def do_GET(self): - # possible local file path - local_path = self.path.replace('/static/', '').split('?')[0] - - # if the file exists locally, we'll serve it up directly - if os.path.isfile(local_path): - self.send_response(200, "Success") - self.end_headers() - with open(local_path) as f: - for line in f.readlines(): - line = replace_urls(line, self.server.server_port) - self.wfile.write(line) - print "Loaded from local override" - return - - # First we'll look for a zuul status call, /status doesn't map - # to gerrit so we can overload the localhost server for this. - if self.path.startswith("/status"): - try: - zuul_url = "%s%s" % (ZUUL_UPSTREAM, self.path) - # BUG(sdague): for some reason SSL connections to zuul - # from python 2.7 blow up with an SSL exception - zuul_url = zuul_url.replace('https', 'http') - response = urllib2.urlopen(zuul_url) - self.send_response(200, "Success") - for header in response.info(): - # need to reset content-length otherwise jquery complains - if header not in ("connection", "content-length", - "keep-alive", "content-encoding"): - self.send_header(header, response.info()[header]) - self.end_headers() - - for line in response.readlines(): - line = replace_urls(line, self.server.server_port) - self.wfile.write(line) - return - except urllib2.HTTPError as e: - self.send_response(e.code) - self.end_headers() - self.wfile.write(e.read()) - return - except urllib2.URLError as e: - print "URLError on %s" % (zuul_url) - print e - - # If you've not built local data to test with, instead grab - # the data off the production server on the fly and serve it - # up from our server. - try: - response = urllib2.urlopen("%s%s" % - (GERRIT_UPSTREAM, self.path)) - self.send_response(200, "Success") - for header in response.info(): - self.send_header(header, response.info()[header]) - self.end_headers() - - for line in response.readlines(): - line = replace_urls(line, self.server.server_port) - self.wfile.write(line) - except urllib2.HTTPError as e: - self.send_response(e.code) - self.end_headers() - self.wfile.write(e.read()) - - -def parse_opts(): - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument('-p', '--port', - help='port to bind to [default: 8001]', - type=int, - default=8001) - parser.add_argument('-z', '--zuul-url', - help='url for zuul server', - default="https://zuul.openstack.org") - parser.add_argument('-g', '--gerrit-url', - help='url for gerrit server', - default="https://review.opendev.org") - return parser.parse_args() - - -def main(): - global ZUUL_UPSTREAM - global GERRIT_UPSTREAM - opts = parse_opts() - ZUUL_UPSTREAM = opts.zuul_url - GERRIT_UPSTREAM = opts.gerrit_url - server_address = ('', opts.port) - httpd = BaseHTTPServer.HTTPServer(server_address, GerritHandler) - - print "Test Server is running at http://localhost:%s" % opts.port - print "Ctrl-C to exit" - print - - while True: - httpd.handle_request() - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - print "\n" - print "Thanks for testing! Please come again." diff --git a/playbooks/roles/gerrit/README.rst b/playbooks/roles/gerrit/README.rst new file mode 100644 index 0000000000..984e3c5c95 --- /dev/null +++ b/playbooks/roles/gerrit/README.rst @@ -0,0 +1 @@ +Run Gerrit. diff --git a/playbooks/roles/gerrit/defaults/main.yaml b/playbooks/roles/gerrit/defaults/main.yaml new file mode 100644 index 0000000000..2136969cf7 --- /dev/null +++ b/playbooks/roles/gerrit/defaults/main.yaml @@ -0,0 +1,5 @@ +gerrit_id: 3000 +gerrit_user_name: gerrit2 +gerrit_home_dir: /home/gerrit2 +gerrit_site_dir: "{{ gerrit_home_dir }}/review_site" +gerrit_run_init: false diff --git a/playbooks/roles/gerrit/files/cla.html b/playbooks/roles/gerrit/files/cla.html new file mode 100644 index 0000000000..83f8688a7a --- /dev/null +++ b/playbooks/roles/gerrit/files/cla.html @@ -0,0 +1,259 @@ +
+ +

+OpenStack Project Individual Contributor License Agreement +

+ + + +

+In order to clarify the intellectual property license granted with +Contributions from any person or entity, the OpenStack Project (the "Project") +must have a Contributor License Agreement ("Agreement") on file that has been +signed by each Contributor, indicating agreement to the license terms below. +This license is for your protection as a Contributor as well as the protection +of OpenStack Foundation as Project manager (the "Project Manager") and the +Project users; it does not change your rights to use your own Contributions for +any other purpose. +

+ +

+You accept and agree to the following terms and conditions for Your present and +future Contributions submitted to the Project Manager. In return, the Project +Manager shall not use Your Contributions in a way that is contrary to the +public benefit or inconsistent with its nonprofit status and bylaws in effect +at the time of the Contribution. Except for the license granted herein to the +Project Manager and recipients of software distributed by the Project Manager, +You reserve all right, title, and interest in and to Your Contributions. +

+ +
    + +
  1. +Definitions. + +"You" (or "Your") shall mean the copyright owner or legal entity authorized by +the copyright owner that is making this Agreement with the Project Manager. For +legal entities, the entity making a Contribution and all other entities that +control, are controlled by, or are under common control with that entity are +considered to be a single Contributor. For the purposes of this definition, +"control" means (i) the power, direct or indirect, to cause the direction or +management of such entity, whether by contract or otherwise, or (ii) ownership +of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial +ownership of such entity. "Contribution" shall mean any original work of +authorship, including any modifications or additions to an existing work, that +is intentionally submitted by You to the Project Manager for inclusion in, or +documentation of, any of the projects owned or managed by the Project Manager +(the "Work"). For the purposes of this definition, "submitted" means any form of +electronic, verbal, or written communication sent to the Project Manager or its +representatives, including but not limited to communication on electronic +mailing lists, source code control systems, and issue tracking systems that are +managed by, or on behalf of, the Project Manager for the purpose of discussing +and improving the Work, but excluding communication that is conspicuously marked +or otherwise designated in writing by You as "Not a Contribution." +

  2. + +
  3. +Grant of Copyright License. + +Subject to the terms and conditions of this Agreement, You hereby grant to the +Project Manager and to recipients of software distributed by the Project +Manager a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare derivative works of, +publicly display, publicly perform, sublicense, and distribute Your +Contributions and such derivative works. +

  4. + +
  5. +Grant of Patent License. + +Subject to the terms and conditions of this Agreement, You hereby grant to the +Project Manager and to recipients of software distributed by the Project +Manager a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by You that are +necessarily infringed by Your Contribution(s) alone or by combination of Your +Contribution(s) with the Work to which such Contribution(s) was submitted. If +any entity institutes patent litigation against You or any other entity +(including a cross-claim or counterclaim in a lawsuit) alleging that Your +Contribution, or the Work to which You have contributed, constitutes direct or +contributory patent infringement, then any patent licenses granted to that +entity under this Agreement for that Contribution or Work shall terminate as of +the date such litigation is filed. +

  6. + +
  7. +You represent that you are legally entitled to grant the above license. If your +employer(s) has rights to intellectual property that you create that includes +your Contributions, You represent that you have received permission to make +Contributions on behalf of that employer, that your employer has waived such +rights for your Contributions to the Project Manager, or that your employer has +executed a separate Corporate Contributor License Agreement with the Project +Manager. +

  8. + +
  9. +You represent that each of Your Contributions is Your original creation (see +Section 7 for submissions on behalf of others). You represent that Your +Contribution submissions include complete details of any third-party license or +other restriction (including, but not limited to, related patents and +trademarks) of which you are personally aware and which are associated with any +part of Your Contributions. +

  10. + +
  11. +You are not expected to provide support for Your Contributions, except to the +extent You desire to provide support. You may provide support for free, for a +fee, or not at all. Unless required by applicable law or agreed to in writing, +You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied, including, without +limitation, any warranties or conditions of TITLE, NONINFRINGEMENT, +MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. +

  12. + +
  13. +Should You wish to submit work that is not Your original creation, You may +submit it to the Project Manager separately from any Contribution, identifying +the complete details of its source and of any license or other restriction +(including, but not limited to, related patents, trademarks, and license +agreements) of which you are personally aware, and conspicuously marking the +work as "Submitted on behalf of a third-party: [named here]". +

  14. + +
  15. +You agree to notify the Project Manager of any facts or circumstances of which +you become aware that would make these representations inaccurate in any +respect. +

  16. + +
  17. +In addition, if you have provided a Contribution (as defined in the LLC +Contribution License Agreement below) to the Project under the Contribution +License Agreement to OpenStack, LLC ("LLC Contribution Agreement"), you agree +that OpenStack, LLC may assign the LLC Contribution Agreement along with all +its rights and obligations under the LLC Contribution License Agreement to the +Project Manager. +

  18. + +
+ +
+

In order to clarify the intellectual property license granted with +Contributions from any person or entity, the OpenStack Project (the "Project") +must have a Contributor License Agreement ("Agreement") on file that has been +signed by each Contributor, indicating agreement to the license terms below. +This license is for your protection as a Contributor as well as the protection +of OpenStack, LLC as Project manager (the "Project Manager") and the Project +users; it does not change your rights to use your own Contributions for any +other purpose. If you have not already done so, please complete and sign this +Individual License Agreement by following the instructions embedded below. +After you fill in the required information and apply your digital signature to +the Agreement, the signature service will generate an email to you. You must +confirm your digital signature as instructed in this email to complete the +signing process. The signature service will then send you a signed copy of this +Agreement for your records.

+ +

You accept and agree to the following terms and conditions for Your +present and future Contributions submitted to the Project Manager. Except for +the license granted herein to the Project Manager and recipients of software +distributed by the Project Manager, You reserve all right, title, and interest +in and to Your Contributions.

+ +
    + +
  1. Definitions"You" (or "Your") shall mean the copyright +owner or legal entity authorized by the copyright owner that is making this +Agreement with the Project Manager. For legal entities, the entity making a +Contribution and all other entities that control, are controlled by, or are +under common control with that entity are considered to be a single +Contributor. For the purposes of this definition, "control" means (i) the +power, direct or indirect, to cause the direction or management of such entity, +whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or +more of the outstanding shares, or (iii) beneficial ownership of such +entity. "Contribution" shall mean any original work of authorship, including +any modifications or additions to an existing work, that is intentionally +submitted by You to the Project Manager for inclusion in, or documentation of, +any of the projects owned or managed by the Project Manager (the "Work"). For +the purposes of this definition, "submitted" means any form of electronic, +verbal, or written communication sent to the Project Manager or its +representatives, including but not limited to communication on electronic +mailing lists, source code control systems, and issue tracking systems that are +managed by, or on behalf of, the Project Manager for the purpose of discussing +and improving the Work, but excluding communication that is conspicuously +marked or otherwise designated in writing by You as "Not a +Contribution."

  2. + +
  3. Grant of Copyright License. Subject to the terms and +conditions of this Agreement, You hereby grant to the Project Manager and to +recipients of software distributed by the Project Manager a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright +license to reproduce, prepare derivative works of, publicly display, publicly +perform, sublicense, and distribute Your Contributions and such derivative +works.

  4. + +
  5. Grant of Patent License. Subject to the terms and +conditions of this Agreement, You hereby grant to the Project Manager and to +recipients of software distributed by the Project Manager a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as +stated in this section) patent license to make, have made, use, offer to sell, +sell, import, and otherwise transfer the Work, where such license applies only +to those patent claims licensable by You that are necessarily infringed by Your +Contribution(s) alone or by combination of Your Contribution(s) with the Work +to which such Contribution(s) was submitted. If any entity institutes patent +litigation against You or any other entity (including a cross-claim or +counterclaim in a lawsuit) alleging that Your Contribution, or the Work to +which You have contributed, constitutes direct or contributory patent +infringement, then any patent licenses granted to that entity under this +Agreement for that Contribution or Work shall terminate as of the date such +litigation is filed.

  6. + +
  7. You represent that you are legally entitled to grant the above license. +If your employer(s) has rights to intellectual property that you create that +includes your Contributions, You represent that you have received permission to +make Contributions on behalf of that employer, that your employer has waived +such rights for your Contributions to the Project Manager, or that your +employer has executed a separate Corporate Contributor License Agreement with +the Project Manager.

  8. + +
  9. You represent that each of Your Contributions is Your original creation +(see Section 7 for submissions on behalf other others). You represent that Your +Contribution submissions include complete details of any third-party license or +other restriction (including, but not limited to, related patents and +trademarks) of which you are personally aware and which are associated with any +part of Your Contributions.

  10. + +
  11. You are not expected to provide support for Your Contributions, except +to the extent You desire to provide support. You may provide support for free, +for a fee, or not at all. Unless required by applicable law or agreed to in +writing, You provide Your Contributions on as "AS IS" BASIS, WITHOUT WARRANTIES +OR CONDITIONS OR ANY KIND, either express or implied, including, without +limitation, any warranties or conditions of TITLE, NONINFRINGEMENT, +MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.

  12. + +
  13. Should You wish to submit work that is not Your original creation, You +may submit it to the Project Manager separately from any Contribution, +identifying the complete details of its source and of any license or other +restriction (including, but not limited to, related patents, trademarks, and +license agreements) of which you are personally aware, and conspicuously +marking the work as "Submitted on behalf of a third-party: [named +here]".

  14. + +
  15. You agree to notify the Project Manager of any facts or circumstances of +which you become aware that would make these representations inaccurate in any +respect.

  16. + +
+ +
+ +
diff --git a/playbooks/roles/gerrit/files/etc/GerritSite.css b/playbooks/roles/gerrit/files/etc/GerritSite.css new file mode 100644 index 0000000000..c1c9d47575 --- /dev/null +++ b/playbooks/roles/gerrit/files/etc/GerritSite.css @@ -0,0 +1,179 @@ +body {color: #000 !important;} +a,a:visited {color: #264D69 !important; text-decoration: none;} +a:hover {color: #000 !important; text-decoration: underline} + +a.gwt-InlineHyperlink {background: none !important} + +#openstack-logo img { height: 40px; } +#openstack-logo h1 { margin: 20px; } +#gerrit_header #openstack-logo h1 { margin: 20px 0 0 0; } + +#gerrit_header {display: block !important; position: relative; top: -60px; margin-bottom: -60px; width: 200px; padding-left: 17px} +#gerrit_header h1 {font-family: 'PT Sans', sans-serif; font-weight: normal; letter-spacing: -1px} + +#gerrit_topmenu {background: none; position:relative; top: 0px; left: 220px; margin-right: 220px} + +#gerrit_topmenu tbody tr td table {border: 0} + +#gerrit_topmenu tbody tr td table.gwt-TabBar {color: #353535; border-bottom: 1px solid #C5E2EA;} +#gerrit_topmenu .gwt-Button {padding: 3px 6px} +.gwt-TabBarItem-selected {color: #CF2F19 !important; border-bottom: 3px solid #CF2F19;} +.gwt-TabBarItem {color: #353535; border-right: 0 !important} +.gwt-TabBar .gwt-TabBarItem, .gwt-TabBar .gwt-TabBarRest, .gwt-TabPanelBottom {background: 0 !important;} + +#gerrit_topmenu .searchTextBox {width: 250px} + +#change_infoTable { + border-collapse: collapse; +} + +#change_infoTable th { + padding: 2px 4px 2px 6px; + background-color: #eef3f5; + font-style: italic; + text-align: left; +} + +#change_infoTable td { + padding: 2px 4px 2px 6px; + border-bottom: 1px solid #eef3f5; + border-right: 1px solid #eef3f5; +} + +#change_infoTable tr:last-child td { + border: none; +} + +.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 { + padding-left: 10px; + padding-right: 10px; +} + +/* Section headers */ +.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 + .com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-headerLine, +.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 + .com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-sectionHeader { + margin-top: 10px !important; + margin-bottom: 10px !important; +} + +/* Commit message */ +.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 + .com-google-gerrit-client-change-CommitBox_BinderImpl_GenCss_style-text::first-line { + font-weight: bold !important; +} + +/* Commit metadata */ +.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 + .com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-commitColumn + .com-google-gerrit-client-change-CommitBox_BinderImpl_GenCss_style-header th { + padding: 2px 4px 2px 6px; + background-color: #eef3f5; + font-style: italic; + text-align: left; +} + +.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 + .com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-commitColumn + .com-google-gerrit-client-change-CommitBox_BinderImpl_GenCss_style-header td { + border-bottom: 1px solid #eef3f5; + padding: 2px 4px 2px 6px; +} + +.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 + .com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-commitColumn + .com-google-gerrit-client-change-CommitBox_BinderImpl_GenCss_style-header td:last-child { + border-right: 1px solid #eef3f5; +} + +/* increase the middle info column to fill empty space (for wide +monitors), but ensure there is a sufficient lower bound to kick in +horiz scroll bar. This will relieve the preasure on the hideci test +results. */ +.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-infoColumn { + width: 100% !important; + min-width: 400px; +} + +/* Review history */ +.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 + .com-google-gerrit-client-change-Message_BinderImpl_GenCss_style-name { + font-weight: bold !important; +} +.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 + .com-google-gerrit-client-change-Message_BinderImpl_GenCss_style-messageBox { + width: inherit; + max-width: 1168px; +} + +.comment_test_name { + display: inline-block; + *display: inline; + *zoom: 1; + width: auto !important; + width: 25em; + min-width: 20em; + padding-bottom: 2pt; +} + +.comment_test_result { +} + +.result_SUCCESS { + color: #007f00; +} +.result_FAILURE, .result_POST_FAILURE, .result_TIMED_OUT, .result_RETRY_LIMIT, .result_DISK_FULL { + color: #cf2f19; +} +.result_UNSTABLE, .result_WARNING { + color: #e39f00; +} +.result_LOST { + color: #e39f00; +} +li.comment_test {list-style-type: none; } + +/* this is for support of 'Display Person Name In Review Category' */ +.cAPPROVAL { + max-width: 100px; + overflow: hidden; +} +/* fixes to make this like old gerrit */ +.changeTable td.dataCell { + height: 1em; +} + +/* don't make the non voting stand out more than the voting */ +table.infoTable td.notVotable, +.changeTable td.dataCell.labelNotApplicable { + background: inherit; +} + +.test_result_table { + border-collapse: collapse; +} + +.test_result_table tr { + border-left: 1px solid #eef3f5; + border-right: 1px solid #eef3f5; +} + +.test_result_table td.header { + background-color: #eef3f5; +} + +.test_result_table td { + padding: 2px 4px 2px 6px; + border: 1px solid #eef3f5; +} + +.addMemberTextBox { + width: 20em; +} + +/* css attribute selector to make -1s show up red in new screen */ +[title="Doesn't seem to work"], +[title="This patch needs further work before it can be merged"] { + color: red; +} diff --git a/playbooks/roles/gerrit/files/etc/GerritSiteHeader.html b/playbooks/roles/gerrit/files/etc/GerritSiteHeader.html new file mode 100644 index 0000000000..0e2f060fa8 --- /dev/null +++ b/playbooks/roles/gerrit/files/etc/GerritSiteHeader.html @@ -0,0 +1,6 @@ +