github.com/googleapis/api-linter@v1.65.2/docs/contributing.md (about) 1 --- 2 --- 3 4 # Contributing 5 6 We are thrilled that you are interested in contributing to the API linter. This 7 software is fully open-sourced, licensed under the Apache license, and we do 8 accept contributions. 9 10 The most common way to contribute is by writing a new linter rule. 11 12 ## Setup 13 14 The API linter is written in [Go][], so you will need the Go language 15 installed. The version of Go you need is officially documented in our 16 [`go.mod`][] file. Most of the time, we will most likely support the most 17 recent two versions. 18 19 Once you have Go installed, you can clone the repository the usual way, and 20 then follow up by running the tests: 21 22 ```bash 23 $ git clone https://github.com/googleapis/api-linter 24 $ cd api-linter 25 $ go test ./... 26 ``` 27 28 **Note:** Unless you have commit bit, you will likely need to make your own 29 fork in GitHub in order to send us pull requests (in which case you clone your 30 fork instead). 31 32 ## Writing rules 33 34 One of the best ways to contribute is by writing a new lint rule. Rules are 35 located in the `rules/` directory. Rules are grouped into packages based on the 36 [AIP][] that mandates the behavior. 37 38 **Important:** **All** linter rules **must** have a corresponding AIP that 39 mandates the behavior. There are no exceptions to this. 40 41 Additionally, we observe the following guidelines around rules: 42 43 - One rule per file. 44 - The filename **must** correspond to the last segment of the rule name (with 45 hyphens converted to underscores). 46 - The rule must have a corresponding test (or tests). Each rule package 47 **must** maintain 100% coverage of statements. 48 - All rules **must** have a three part name. The first part is the "rule group" 49 (such as `core`), the second part is the AIP number, zero-padded, and the 50 third part is a unique name for the rule. The name only has to be unique 51 within the scope of the AIP. 52 - If word separation is needed, `kebab-case` **must** be used. 53 - Every rule **must** have corresponding documentation. Documentation lives in 54 the `docs/` directory, and powers this documentation site using GitHub Pages. 55 56 We have a CI lint to remind you to do so. 57 58 Writing a rule is straightforward: the linter employs a [visitor pattern][] 59 that goes to every descriptor in the proto file and runs each lint rule against 60 it. Most rules are run against only a certain _type_ of descriptor (for 61 example, a "message rule" is run against all of the message descriptors, but 62 not services or fields). 63 64 Consider a bare-bones message rule: 65 66 ```go 67 var myRule = &lint.MessageRule{ 68 Name: lint.NewRuleName(0, "my-rule"), 69 LintMessage: func(m *desc.MessageDescriptor) []lint.Problem { 70 // This lint rule does nothing and always passes. 71 return nil 72 }, 73 } 74 ``` 75 76 The actual lint function takes a [protoreflect][] descriptor. Beyond this, the 77 function is free-form; the developer can check anything desired and return a 78 slice of [`Problem`][] objects. 79 80 ## Registering rules 81 82 Once a rule is written, it must be _registered_ with the rule registry, which 83 is defined in [`rules.go`][]. 84 85 There are two steps: 86 87 1. In the registry in `rules.go`, ensure that the corresponding AIP package is 88 imported, and that its `AddRules` function is called. 89 2. In the AIP package, ensure that the new rule is included in the `AddRules` 90 function. 91 92 We have a CI lint to remind you to do so. 93 94 ## Documentation 95 96 Rule documentation is the primary purpose of this site, and it is important 97 that all rules are documented. This documentation is written in Markdown, and 98 goes in the `docs/rules/` directory. The naming convention is 99 `{aip}-{rule_name}.md`: 100 101 - `{aip}` is the _four-digit_ AIP number (zero-padded if needed!) 102 - `{rule_name}` is the final component of the rule name in the rule itself. 103 104 The actual Markdown document is fairly boilerplate, and copy and paste from 105 another file is reasonable. 106 107 The top of the file **must** include the proper "front matter" for GitHub 108 Pages. The format is: 109 110 --- 111 rule: 112 aip: 0 113 name: [core, '0000', my-rule] 114 --- 115 116 - The AIP number **must** be included as an integer, and **must** be set as a 117 string in the `name` array (quotes are required to keep the YAML parser from 118 interpreting it as an integer and dropping leading zeroes). 119 - The `name` field **must** be the name of the rule (as passed to 120 `lint.NewRuleName` in array form). 121 122 In addition to that, when providing protobuf examples, it is often useful to 123 mark one as being explicitly "incorrect" (or "correct"). Do this by beginning 124 the code block with a special comment: 125 126 ``` 127 // Incorrect. 128 message BadThing { 129 // ... 130 } 131 ``` 132 133 If a proto block _begins with_ a comment that says only `Incorrect.` or 134 `Correct.`, it picks up different styling when viewing in GitHub Pages. 135 136 ## Releases 137 138 Releases are handled automatically by [release-please][] by sending PRs 139 after changes starting with `fix:` or `feat:` have been merged. 140 [example release pr][]. 141 142 If a manual release is desired, simply open a pull request with an empty commit 143 and the proper conventional commit message for the desired semver bump. For example: 144 145 ```sh 146 # releasing a minor version 147 git commit --allow-empty -m 'feat: new minor release' 148 149 # releasing a patch version 150 git commit --allow-empty -m 'fix: new patch release' 151 ``` 152 153 <!-- prettier-ignore-start --> 154 [aip]: https://aip.dev/ 155 [go]: https://golang.org/ 156 [`go.mod`]: https://github.com/googleapis/api-linter/blob/main/go.mod 157 [`problem`]: https://godoc.org/github.com/googleapis/api-linter/lint#Problem 158 [protoreflect]: https://godoc.org/github.com/jhump/protoreflect 159 [`rules.go`]: https://github.com/googleapis/api-linter/blob/main/rules/rules.go 160 [visitor pattern]: https://en.wikipedia.org/wiki/Visitor_pattern 161 [release-please]: https://github.com/googleapis/release-please 162 [example release pr]: https://github.com/googleapis/api-linter/pull/1290 163 <!-- prettier-ignore-end -->