github.com/abayer/test-infra@v0.0.5/prow/cmd/branchprotector/README.md (about)

     1  # Branch Protection Documentation
     2  
     3  branchprotector configures [github branch protection] according to a specified
     4  policy.
     5  
     6  ## Policy configuration
     7  
     8  Extend the primary prow [`config.yaml`] document to include a top-level
     9  `branch-protection` key that looks like the following:
    10  
    11  ```yaml
    12  
    13  branch-protection:
    14    orgs:
    15      kubernetes:
    16        repos:
    17          test-infra:
    18            # Protect all branches in kubernetes/test-infra
    19            protect: true
    20            # Always allow the org's oncall-team to push
    21            restrictions:
    22              teams: ["oncall-team"]
    23            # Ensure that the extra-process-followed github status context passes.
    24            # In addition, adds any required prow jobs (aka always_run: true)
    25            required_status_checks:
    26              contexts: ["extra-process-followed"]
    27  
    28  presubmits:
    29    kubernetes/test-infra:
    30    - name: fancy-job-name
    31      context: fancy-job-name
    32      always_run: true
    33      spec:  # podspec that runs job
    34  ```
    35  
    36  This config will:
    37    * Enable protection for every branch in the `kubernetes/test-infra`
    38  repo.
    39    * Require `extra-process-followed` and `fancy-job-name` [status contexts] to pass
    40      before allowing a merge
    41      - Although it will always allow `oncall-team` to merge, even if required
    42        contexts fail.
    43      - Note that `fancy-job-name` is pulled in automatically from the
    44        `presubmits` config for the repo, if one exists.
    45  
    46  ### Updating
    47  
    48  * Send PR with `config.yaml` changes
    49  * Merge PR
    50  * Done!
    51  
    52  Make changes to the policy by modifying [`config.yaml`] in your favorite text
    53  editor and then send out a PR. When the PR merges prow pushes the updated config
    54  . The branchprotector applies the new policies the next time it runs (within
    55  24hrs).
    56  
    57  ### Advanced configuration
    58  
    59  
    60  #### Fields
    61  
    62  See [`branch_protection.go`] and Github's [protection api] for a complete list of fields allowed
    63  inside `branch-protection` and their meanings. The format is:
    64  
    65  ```yaml
    66  branch-protection:
    67    # default policy here
    68    orgs:
    69      foo:
    70        # this is the foo org policy
    71        protect: true  # enable protection
    72        enforce_admins: true  # rules apply to admins
    73        required_pull_request_reviews:
    74          dismiss_stale_reviews: false # automatically dismiss old reviews
    75          dismissal_restrictions: # allow review dismissals
    76            users:
    77            - her
    78            - him
    79            teams:
    80            - them
    81            - those
    82          require_code_owner_reviews: true  # require a code owner approval
    83          required_approving_review_count: 1 # number of approvals
    84        required_status_checks:
    85          strict: false # require pr branch to be up to date
    86          contexts: # checks which must be green to merge
    87          - foo
    88          - bar
    89        restrictions: # restrict who can push to the repo
    90          users:
    91          - her
    92          - him
    93          teams:
    94          - them
    95          - those
    96  ```
    97  
    98  
    99  
   100  #### Scope
   101  
   102  
   103  It is possible to define a policy at the
   104  `branch-protection`, `org`, `repo` or `branch` level. For example:
   105  
   106  ```yaml
   107  branch-protection:
   108    # Protect unless overridden
   109    protect: true
   110    # If protected, always require the cla status context
   111    required_status_checks:
   112      contexts: ["cla"]
   113    orgs:
   114      unprotected-org:
   115        # Disable protection unless overridden (overrides parent setting of true)
   116        protect: false
   117        repos:
   118          protected-repo:
   119            # Inherit protect-by-default config from parent
   120            # If protected, always require the tested status context
   121            required_status_checks:
   122              contexts: ["tested"]
   123            branches:
   124              secure:
   125                # Protect the secure branch (overrides inhereted parent setting of false)
   126                protect: true
   127                # Require the foo status context
   128                required_status_checks:
   129                  contexts: ["foo"]
   130      different-org:
   131        # Inherits protect-by-default: true setting from above
   132  ```
   133  
   134  The general rule for how to compute child values is:
   135    * If the child value is `null` or missing, inherit the parent value.
   136    * Otherwise:
   137      -   List values (like `contexts`), create a union of the parent and child lists.
   138      -   For bool/int values (like `protect`), the child value replaces the parent value.
   139  
   140  So in the example above:
   141    * The `secure` branch in `unprotected-org/protected-repo`
   142      - enables protection (set a branch level)
   143      - requires `foo` `tested` `cla` [status contexts]
   144        (the latter two are appended by ancestors)
   145    * All other branches in `unprotected-org/protected-repo`
   146      - disable protection (inherited from org level)
   147    * All branches in all other repos in `unprotected-org`
   148      - disable protection (set at org level)
   149    * All branches in all repos in `different-org`
   150      - Enable protection (inherited from branch-protection level)
   151      - Require the `cla` context to be green to merge (appended by parent)
   152  
   153  ## Developer docs
   154  
   155  Use [`planter.sh`] if [`bazel`] is not already installed on the machine.
   156  
   157  ### Run unit tests
   158  
   159  `bazel test //prow/cmd/branchprotection:all`
   160  
   161  ### Run locally
   162  
   163  `bazel run //prow/cmd/branchprotection -- --help`, which will tell you about the
   164  current flags.
   165  
   166  Do a dry run (which will not make any changes to github) with
   167  something like the following command:
   168  
   169  ```sh
   170  bazel run //prow/cmd/branchprotection -- \
   171    --config-path=/path/to/config.yaml \
   172    --github-token-path=/path/to/my-github-token
   173  ```
   174  
   175  This will say how the binary will actually change github if you add a
   176  `--confirm` flag.
   177  
   178  ### Deploy local changes to dev cluster
   179  
   180  Run things like the following:
   181  ```sh
   182  # Build and push image, create job
   183  bazel run //prow/cmd/branchprotection:oneshot.create
   184  # Delete finished job
   185  bazel run //prow/cmd/branchprotection:oneshot.delete
   186  # Describe current state of job
   187  bazel run //prow/cmd/branchprotection:oneshot.describe
   188  ```
   189  
   190  This will build an image with your local changes, push it to
   191  `STABLE_DOCKER_REPO` and then deploy to `STABLE_PROW_CLUSTER`.
   192  
   193  See [`print-workspace-status.sh`] for the definition of these variables.
   194  See [`oneshot-job.yaml`] for details on the deployed job resource.
   195  
   196  ### Deploy cronjob to production
   197  
   198  Follow the standard prow deployment process:
   199  
   200  ```sh
   201  # build and push image, update tag used in production
   202  prow/bump.sh branchprotector
   203  # apply changes to production
   204  bazel run //prow/cluster:branchprotector.apply
   205  ```
   206  
   207  See [`prow/bump.sh`] for details on this script.
   208  See [`prow/cluster/branchprotector_cronjob.yaml`] for details on the deployed
   209  job resource.
   210  
   211  
   212  [`bazel`]: https://bazel.build
   213  [`branch_protection.go`]: /prow/config/branch_protection.go
   214  [`config.yaml`]: /prow/config.yaml
   215  [github branch protection]: https://help.github.com/articles/about-protected-branches/
   216  [`oneshot-job.yaml`]: oneshot-job.yaml
   217  [`planter.sh`]: /planter
   218  [`print-workspace-status.sh`]: ../../../hack/print-workspace-status.sh
   219  [`prow/bump.sh`]: /prow/bump.sh
   220  [`prow/cluster/branchprotector_cronjob.yaml`]: /prow/cluster/branchprotector_cronjob.yaml
   221  [status contexts]: https://developer.github.com/v3/repos/statuses/#create-a-status
   222  [protection api]: https://developer.github.com/v3/repos/branches/#update-branch-protection