Martin Blanchard pushed to branch laurence/update-policies at BuildGrid / buildgrid
Commits:
- 
6ca668f8
by Martin Blanchard at 2018-11-12T09:12:58Z
- 
3512e0bb
by Martin Blanchard at 2018-11-12T09:13:08Z
- 
1763e4ee
by Laurence Urhegyi at 2018-11-22T18:09:15Z
- 
f5f9b4f7
by Laurence Urhegyi at 2018-11-22T18:09:15Z
- 
1796fb0d
by Laurence Urhegyi at 2018-11-22T18:09:15Z
5 changed files:
- + COMMITTERS.md
- CONTRIBUTING.rst
- − MAINTAINERS
- buildgrid/client/cas.py
- + tests/cas/data/hello/hello.sh
Changes:
| 1 | +## COMMITTERS
 | |
| 2 | + | |
| 3 | +| Name | Email |  
 | |
| 4 | +| -------- | -------- | 
 | |
| 5 | +|  Carter Sande  | <carter.sande@duodecima.technology> | 
 | |
| 6 | +|  Ed Baunton  | <edbaunton gmail com> |
 | |
| 7 | +|  Laurence Urhegyi  | <laurence urhegyi codethink co uk> | 
 | |
| 8 | +|  Finn Ball  | <finn ball codethink co uk> |
 | |
| 9 | +|  Paul Sherwood  | <paul sherwood codethink co uk> | 
 | |
| 10 | +|  James Ennis  | <james ennis codethink com> |
 | |
| 11 | +|  Jim MacArthur  | <jim macarthur codethink co uk> | 
 | |
| 12 | +|  Juerg Billeter  | <juerg billeter codethink co uk> |
 | |
| 13 | +|  Martin Blanchard  | <martin blanchard codethink co uk> | 
 | |
| 14 | +|  Marios Hadjimichael  | <mhadjimichae bloomberg net> |
 | |
| 15 | +|  Raoul Hidalgo Charman  | <raoul hidalgocharman codethink co uk> | 
 | |
| 16 | +|  Rohit Kothur  |  <rkothur bloomberg net> | | 
| ... | ... | @@ -32,40 +32,31 @@ side effects and quirks the feature may have introduced. More on this below in | 
| 32 | 32 |  | 
| 33 | 33 |  .. _BuildGrid mailing list: https://lists.buildgrid.build/cgi-bin/mailman/listinfo/buildgrid
 | 
| 34 | 34 |  | 
| 35 | - | |
| 36 | 35 |  .. _patch-submissions:
 | 
| 37 | 36 |  | 
| 38 | 37 |  Patch submissions
 | 
| 39 | 38 |  -----------------
 | 
| 40 | 39 |  | 
| 41 | -We are running `trunk based development`_. The idea behind this is that merge
 | |
| 42 | -requests to the trunk will be small and made often, thus making the review and
 | |
| 43 | -merge process as fast as possible. We do not want to end up with a huge backlog
 | |
| 44 | -of outstanding merge requests. If possible, it is preferred that merge requests
 | |
| 45 | -address specific points and clearly outline what problem they are solving.
 | |
| 46 | - | |
| 47 | -Branches must be submitted as merge requests (MR) on GitLab and should be
 | |
| 48 | -associated with an issue, whenever possible. If it's a small change, we'll
 | |
| 49 | -accept an MR without it being associated to an issue, but generally we prefer an
 | |
| 50 | -issue to be raised in advance. This is so that we can track the work that is
 | |
| 40 | +Branches must be submitted as merge requests (MR) on GitLab and should have a 
 | |
| 41 | +corresponding issue raised in advance (whenever possible). If it's a small change, 
 | |
| 42 | +an MR without it being associated to an issue is okay, but generally we prefer an
 | |
| 43 | +issue to be raised in advance so that we can track the work that is
 | |
| 51 | 44 |  currently in progress on the project.
 | 
| 52 | 45 |  | 
| 46 | +When submitting a merge request, please obtain a review from another committer 
 | |
| 47 | +who is familiar with the area of the code base which the branch effects. An 
 | |
| 48 | +approval from another committer who is not the patch author will be needed 
 | |
| 49 | +before any merge (we use Gitlab's 'approval' feature for this).
 | |
| 50 | + | |
| 53 | 51 |  Below is a list of good patch submission good practice:
 | 
| 54 | 52 |  | 
| 55 | 53 |  - Each commit should address a specific issue number in the commit message. This
 | 
| 56 | 54 |    is really important for provenance reasons.
 | 
| 57 | -- Merge requests that are not yet ready for review must be prefixed with the
 | |
| 58 | -  ``WIP:`` identifier, but if we stick to trunk based development then the
 | |
| 59 | -  ``WIP:`` identifier will not stay around for very long on a merge request.
 | |
| 60 | -- When a merge request is ready for review, please find someone willing to do
 | |
| 61 | -  the review (ideally a maintainer) and assign them the MR, leaving a comment
 | |
| 62 | -  asking for their review.
 | |
| 55 | +- Merge requests that are not yet ready for review should be prefixed with the
 | |
| 56 | +  ``WIP:`` identifier.
 | |
| 63 | 57 |  - Submitted branches should not contain a history of work done.
 | 
| 64 | 58 |  - Unit tests should be a separate commit.
 | 
| 65 | 59 |  | 
| 66 | -.. _trunk based development: https://trunkbaseddevelopment.com
 | |
| 67 | - | |
| 68 | - | |
| 69 | 60 |  Commit messages
 | 
| 70 | 61 |  ~~~~~~~~~~~~~~~
 | 
| 71 | 62 |  | 
| ... | ... | @@ -89,6 +80,57 @@ For more tips, please read `The seven rules of a great Git commit message`_. | 
| 89 | 80 |  | 
| 90 | 81 |  .. _The seven rules of a great Git commit message: https://chris.beams.io/posts/git-commit/#seven-rules
 | 
| 91 | 82 |  | 
| 83 | +.. _committer-access:
 | |
| 84 | + | |
| 85 | +Committer access
 | |
| 86 | +----------------
 | |
| 87 | + | |
| 88 | +Committers in the BuildGrid project are those folks to whom the right to 
 | |
| 89 | +directly commit changes to our version controlled resources has been granted. 
 | |
| 90 | +While every contribution is 
 | |
| 91 | +valued regardless of its source, not every person who contributes code to the 
 | |
| 92 | +project will earn commit access. The `COMMITTERS`_ file lists all committers.
 | |
| 93 | + | |
| 94 | +.. _COMMITTERS: https://gitlab.com/BuildGrid/buildgrid/blob/master/COMMITTERS.md
 | |
| 95 | +.. _Subversion: http://subversion.apache.org/docs/community-guide/roles.html#committers
 | |
| 96 | + | |
| 97 | + | |
| 98 | +How commit access is granted
 | |
| 99 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 100 | + | |
| 101 | +After someone has successfully contributed a few non-trivial patches, some full 
 | |
| 102 | +committer, usually whoever has reviewed and applied the most patches from that 
 | |
| 103 | +contributor, proposes them for commit access. This proposal is sent only to the 
 | |
| 104 | +other full committers -- the ensuing discussion is private, so that everyone can 
 | |
| 105 | +feel comfortable speaking their minds. Assuming there are no objections, the 
 | |
| 106 | +contributor is granted commit access. The decision is made by consensus; there 
 | |
| 107 | +are no formal rules governing the procedure, though generally if someone strongly 
 | |
| 108 | +objects the access is not offered, or is offered on a provisional basis.
 | |
| 109 | + | |
| 110 | +This of course relies on contributors being responsive and showing willingness 
 | |
| 111 | +to address any problems that may arise after landing patches. However, the primary 
 | |
| 112 | +criterion for commit access is good judgment.
 | |
| 113 | + | |
| 114 | +You do not have to be a technical wizard, or demonstrate deep knowledge of the 
 | |
| 115 | +entire codebase to become a committer. You just need to know what you don't 
 | |
| 116 | +know. If your patches adhere to the guidelines in this file, adhere to all the usual 
 | |
| 117 | +unquantifiable rules of coding (code should be readable, robust, maintainable, etc.), 
 | |
| 118 | +and respect the Hippocratic Principle of "first, do no harm", then you will probably 
 | |
| 119 | +get commit access pretty quickly. The size, complexity, and quantity of your patches 
 | |
| 120 | +do not matter as much as the degree of care you show in avoiding bugs and minimizing 
 | |
| 121 | +unnecessary impact on the rest of the code. Many full committers are people who have 
 | |
| 122 | +not made major code contributions, but rather lots of small, clean fixes, each of 
 | |
| 123 | +which was an unambiguous improvement to the code. (Of course, this does not mean the 
 | |
| 124 | +project needs a bunch of very trivial patches whose only purpose is to gain commit 
 | |
| 125 | +access; knowing what's worth a patch post and what's not is part of showing good 
 | |
| 126 | +judgement.)
 | |
| 127 | + | |
| 128 | +When submitting a merge request, please obtain a review from another committer 
 | |
| 129 | +who is familiar with the area of the code base which the branch effects. Asking on 
 | |
| 130 | +slack is probably the best way to go about this. An approval from a committer 
 | |
| 131 | +who is not the patch author will be needed before any merge (we use Gitlab's 'approval' 
 | |
| 132 | +feature for this).
 | |
| 133 | + | |
| 92 | 134 |  | 
| 93 | 135 |  .. _coding-style:
 | 
| 94 | 136 |  | 
| ... | ... | @@ -198,35 +240,6 @@ trunk. | 
| 198 | 240 |  | 
| 199 | 241 |  .. _coverage report: https://buildgrid.gitlab.io/buildgrid/coverage/
 | 
| 200 | 242 |  | 
| 201 | - | |
| 202 | -.. _committer-access:
 | |
| 203 | - | |
| 204 | -Committer access
 | |
| 205 | -----------------
 | |
| 206 | - | |
| 207 | -We'll hand out commit access to anyone who has successfully landed a single
 | |
| 208 | -patch to the code base. Please request this via Slack or the mailing list.
 | |
| 209 | - | |
| 210 | -This of course relies on contributors being responsive and showing willingness 
 | |
| 211 | -to address any problems that may arise after landing branches.
 | |
| 212 | - | |
| 213 | -When submitting a merge request, please obtain a review from another committer 
 | |
| 214 | -who is familiar with the area of the code base which the branch effects. An 
 | |
| 215 | -approval from another committer who is not the patch author will be needed 
 | |
| 216 | -before any merge (we use gitlab's 'approval' feature for this).
 | |
| 217 | - | |
| 218 | -What we are expecting of committers here in general is basically to escalate the
 | |
| 219 | -review in cases of uncertainty.
 | |
| 220 | - | |
| 221 | -.. note::
 | |
| 222 | - | |
| 223 | -   We don't have any detailed policy for "bad actors", but will of course handle
 | |
| 224 | -   things on a case by case basis - commit access should not result in commit
 | |
| 225 | -   wars or be used as a tool to subvert the project when disagreements arise.
 | |
| 226 | -   Such incidents (if any) would surely lead to temporary suspension of commit
 | |
| 227 | -   rights.
 | |
| 228 | - | |
| 229 | - | |
| 230 | 243 |  .. _gitlab-features:
 | 
| 231 | 244 |  | 
| 232 | 245 |  GitLab features
 | 
| 1 | -Finn Ball
 | |
| 2 | -E-mail: finn ball codethink co uk
 | |
| 3 | -Userid: finnball | 
| ... | ... | @@ -171,7 +171,7 @@ class Downloader: | 
| 171 | 171 |  | 
| 172 | 172 |          return messages
 | 
| 173 | 173 |  | 
| 174 | -    def download_file(self, digest, file_path, queue=True):
 | |
| 174 | +    def download_file(self, digest, file_path, is_executable=False, queue=True):
 | |
| 175 | 175 |          """Retrieves a file from the remote CAS server.
 | 
| 176 | 176 |  | 
| 177 | 177 |          If queuing is allowed (`queue=True`), the download request **may** be
 | 
| ... | ... | @@ -181,6 +181,7 @@ class Downloader: | 
| 181 | 181 |          Args:
 | 
| 182 | 182 |              digest (:obj:`Digest`): the file's digest to fetch.
 | 
| 183 | 183 |              file_path (str): absolute or relative path to the local file to write.
 | 
| 184 | +            is_executable (bool): whether the file is executable or not.
 | |
| 184 | 185 |              queue (bool, optional): whether or not the download request may be
 | 
| 185 | 186 |                  queued and submitted as part of a batch upload request. Defaults
 | 
| 186 | 187 |                  to True.
 | 
| ... | ... | @@ -193,9 +194,9 @@ class Downloader: | 
| 193 | 194 |              file_path = os.path.abspath(file_path)
 | 
| 194 | 195 |  | 
| 195 | 196 |          if not queue or digest.size_bytes > FILE_SIZE_THRESHOLD:
 | 
| 196 | -            self._fetch_file(digest, file_path)
 | |
| 197 | +            self._fetch_file(digest, file_path, is_executable=is_executable)
 | |
| 197 | 198 |          else:
 | 
| 198 | -            self._queue_file(digest, file_path)
 | |
| 199 | +            self._queue_file(digest, file_path, is_executable=is_executable)
 | |
| 199 | 200 |  | 
| 200 | 201 |      def download_directory(self, digest, directory_path):
 | 
| 201 | 202 |          """Retrieves a :obj:`Directory` from the remote CAS server.
 | 
| ... | ... | @@ -311,7 +312,7 @@ class Downloader: | 
| 311 | 312 |  | 
| 312 | 313 |          return read_blobs
 | 
| 313 | 314 |  | 
| 314 | -    def _fetch_file(self, digest, file_path):
 | |
| 315 | +    def _fetch_file(self, digest, file_path, is_executable=False):
 | |
| 315 | 316 |          """Fetches a file using ByteStream.Read()"""
 | 
| 316 | 317 |          if self.instance_name:
 | 
| 317 | 318 |              resource_name = '/'.join([self.instance_name, 'blobs',
 | 
| ... | ... | @@ -332,7 +333,10 @@ class Downloader: | 
| 332 | 333 |  | 
| 333 | 334 |              assert byte_file.tell() == digest.size_bytes
 | 
| 334 | 335 |  | 
| 335 | -    def _queue_file(self, digest, file_path):
 | |
| 336 | +        if is_executable:
 | |
| 337 | +            os.chmod(file_path, 0o755)  # rwxr-xr-x / 755
 | |
| 338 | + | |
| 339 | +    def _queue_file(self, digest, file_path, is_executable=False):
 | |
| 336 | 340 |          """Queues a file for later batch download"""
 | 
| 337 | 341 |          if self.__file_request_size + digest.ByteSize() > MAX_REQUEST_SIZE:
 | 
| 338 | 342 |              self.flush()
 | 
| ... | ... | @@ -341,22 +345,25 @@ class Downloader: | 
| 341 | 345 |          elif self.__file_request_count >= MAX_REQUEST_COUNT:
 | 
| 342 | 346 |              self.flush()
 | 
| 343 | 347 |  | 
| 344 | -        self.__file_requests[digest.hash] = (digest, file_path)
 | |
| 348 | +        self.__file_requests[digest.hash] = (digest, file_path, is_executable)
 | |
| 345 | 349 |          self.__file_request_count += 1
 | 
| 346 | 350 |          self.__file_request_size += digest.ByteSize()
 | 
| 347 | 351 |          self.__file_response_size += digest.size_bytes
 | 
| 348 | 352 |  | 
| 349 | 353 |      def _fetch_file_batch(self, batch):
 | 
| 350 | 354 |          """Sends queued data using ContentAddressableStorage.BatchReadBlobs()"""
 | 
| 351 | -        batch_digests = [digest for digest, _ in batch.values()]
 | |
| 355 | +        batch_digests = [digest for digest, _, _ in batch.values()]
 | |
| 352 | 356 |          batch_blobs = self._fetch_blob_batch(batch_digests)
 | 
| 353 | 357 |  | 
| 354 | -        for (_, file_path), file_blob in zip(batch.values(), batch_blobs):
 | |
| 358 | +        for (_, file_path, is_executable), file_blob in zip(batch.values(), batch_blobs):
 | |
| 355 | 359 |              os.makedirs(os.path.dirname(file_path), exist_ok=True)
 | 
| 356 | 360 |  | 
| 357 | 361 |              with open(file_path, 'wb') as byte_file:
 | 
| 358 | 362 |                  byte_file.write(file_blob)
 | 
| 359 | 363 |  | 
| 364 | +            if is_executable:
 | |
| 365 | +                os.chmod(file_path, 0o755)  # rwxr-xr-x / 755
 | |
| 366 | + | |
| 360 | 367 |      def _fetch_directory(self, digest, directory_path):
 | 
| 361 | 368 |          """Fetches a file using ByteStream.GetTree()"""
 | 
| 362 | 369 |          # Better fail early if the local root path cannot be created:
 | 
| ... | ... | @@ -414,7 +421,7 @@ class Downloader: | 
| 414 | 421 |          for file_node in root_directory.files:
 | 
| 415 | 422 |              file_path = os.path.join(root_path, file_node.name)
 | 
| 416 | 423 |  | 
| 417 | -            self._queue_file(file_node.digest, file_path)
 | |
| 424 | +            self._queue_file(file_node.digest, file_path, is_executable=file_node.is_executable)
 | |
| 418 | 425 |  | 
| 419 | 426 |          for directory_node in root_directory.directories:
 | 
| 420 | 427 |              directory_path = os.path.join(root_path, directory_node.name)
 | 
| 1 | +#!/bin/bash
 | |
| 2 | + | |
| 3 | +echo "Hello, World!" | 
