Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tooling: Add protolock bazel dependency and tests #17375

Closed
wants to merge 1 commit into from

Conversation

YaseenAlk
Copy link
Contributor

Signed-off-by: Yaseen Alkhafaji [email protected]

Commit Message: tooling: Add protolock bazel dependency and protolock tests

Additional Description:

protolock is a tool that enforces backwards compatibility of APIs by detecting breaking changes of .proto files. It does so by parsing .proto files and saving the state of the protobufs in a proto.lock file. Between invocations of protolock, the lock file is compared to the current state, and the diff is evaluated against a set of rules. If any rules are violated, then protolock raises an error.

This PR introduces protolock as an external bazel dependency, and also adds some tests that evaluate protolock against some simple protobuf changes, categorized either as "breaking" (e.g. changes that require incrementing the envoy API version) and "allowed" (e.g. changes that can be introduced in the same API version).

protolock is intended to be run against the protobufs in envoy/api/* to detect breaking API changes. In the coming weeks, I will be:

  • adding tooling to allow protolock to be run arbitrarily
  • extending protolock by adding more envoy-specific rules, for example breaking changes to PGV annotations.

I have been using the backwards compatibility rules in the API_VERSIONING doc as a model for rules to introduce. The rules list is still a WIP, so if there are additional rules that are desired, please do reach out!

Risk Level: Low
Testing: Tests that evaluate protolock against "allowed" and "breaking" protobuf API changes. Currently a few tests are skipped - these tests will be enabled in future PRs as I modify protolock to evaluate PGV and some other rules it does not currently address

References #3368 and maybe #6271

Docs Changes: -
Release Notes: -
Platform Specific Features: -

@repokitteh-read-only
Copy link

Hi @YaseenAlk, welcome and thank you for your contribution.

We will try to review your Pull Request as quickly as possible.

In the meantime, please take a look at the contribution guidelines if you have not done so already.

🐱

Caused by: #17375 was opened by YaseenAlk.

see: more, trace.

@repokitteh-read-only repokitteh-read-only bot added the deps Approval required for changes to Envoy's external dependencies label Jul 16, 2021
@repokitteh-read-only
Copy link

CC @envoyproxy/dependency-shepherds: Your approval is needed for changes made to (bazel/.*repos.*\.bzl)|(bazel/dependency_imports\.bzl)|(api/bazel/.*\.bzl)|(.*/requirements\.txt)|(.*\.patch).

🐱

Caused by: #17375 was opened by YaseenAlk.

see: more, trace.

@YaseenAlk
Copy link
Contributor Author

Not sure if I'm able to add reviewers but I know @adisuissa @akonradi and @htuch are interested

Comment on lines +290 to +300
com_github_nilslice_protolock = dict(
project_name = "protolock",
project_desc = "Track your .proto files and prevent changes to messages and services which impact API compatibility.",
project_url = "https://github.com/nilslice/protolock/",
version = "0.15.2",
sha256 = "26d0b491471866c4959a75a1418a577eab432782b9923fdf022535bb7c322374",
urls = ["https://github.com/nilslice/protolock/archive/refs/tags/v{version}.tar.gz"],
release_date = "2021-02-18",
use_category = ["api"],
strip_prefix = "protolock-{version}",
),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scorecard --repo=https://github.com/nilslice/protolock

RESULTS
-------
Repo: github.com/nilslice/protolock
|--------|------------|-----------------------------|
| STATUS | CONFIDENCE |            NAME             |
|--------|------------|-----------------------------|
| Pass   |         10 | Binary-Artifacts            |
|--------|------------|-----------------------------|
| Pass   |         10 | Code-Review                 |
|--------|------------|-----------------------------|
| Pass   |         10 | Contributors                |
|--------|------------|-----------------------------|
| Pass   |          8 | Pull-Requests               |
|--------|------------|-----------------------------|
| Pass   |         10 | Token-Permissions           |
|--------|------------|-----------------------------|
| Pass   |         10 | Vulnerabilities             |
|--------|------------|-----------------------------|
| Fail   |         10 | Active                      |
|--------|------------|-----------------------------|
| Fail   |          3 | Automatic-Dependency-Update |
|--------|------------|-----------------------------|
| Fail   |          0 | Branch-Protection           |
|--------|------------|-----------------------------|
| Fail   |          5 | CI-Tests                    |
|--------|------------|-----------------------------|
| Fail   |         10 | CII-Best-Practices          |
|--------|------------|-----------------------------|
| Fail   |         10 | Frozen-Deps                 |
|--------|------------|-----------------------------|
| Fail   |         10 | Fuzzing                     |
|--------|------------|-----------------------------|
| Fail   |          0 | Packaging                   |
|--------|------------|-----------------------------|
| Fail   |         10 | SAST                        |
|--------|------------|-----------------------------|
| Fail   |         10 | Security-Policy             |
|--------|------------|-----------------------------|
| Fail   |         10 | Signed-Releases             |
|--------|------------|-----------------------------|
| Fail   |         10 | Signed-Tags                 |
|--------|------------|-----------------------------|

Copy link
Member

@htuch htuch Jul 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is really primarily a test/dev tool I'm willing to give a pass on most of the FAILs I think. @YaseenAlk what do you think of Protolock maintenance story? I'm not seeing a lot of activity in past year+ and CI is broken. Would we consider forking if this isn't actively maintained?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@YaseenAlk also looked at buf which is more actively maintained.
The 2 downsides, IIRC, are that buf also attempts to address more protobuf related operations, and it might require more work to add/modify rules (compared to protolock's plugins).
One thing to note is that buf's breaking changes rules seem to be much more comprehensive than protolock's.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, buf looks a lot more active / maintained. How much harder is it in reality to do stuff in buf?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can get direct help from the buf team if needed. Do you want to talk to them about our needs? I think they would be excited to work with us.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out-of-the-box, buf seems to be targeting many of the issues we would like to guard against.
I guess the open question is how hard will it be to add PGV rules to buf. @YaseenAlk, we can discuss this tomorrow.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We actually have a migration doc concerning protolock https://docs.buf.build/migration-protolock including a pros/cons list. You likely want to use buf. Happy to chat!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow up PR that uses buf instead: #17515

project_name = "proto",
project_desc = "parser for Google ProtocolBuffers definition",
project_url = "https://github.com/emicklei/proto/",
version = "1.7.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +301 to +311
com_github_emicklei_proto = dict(
project_name = "proto",
project_desc = "parser for Google ProtocolBuffers definition",
project_url = "https://github.com/emicklei/proto/",
version = "1.7.0",
sha256 = "e93272fea9e4f993b9d160440bf980d015970147907090834492771bb1c4510c",
urls = ["https://github.com/emicklei/proto/archive/refs/tags/v{version}.tar.gz"],
release_date = "2019-10-05",
use_category = ["api"],
strip_prefix = "proto-{version}",
),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scorecard --repo=https://github.com/emicklei/proto

RESULTS
-------
Repo: github.com/emicklei/proto
|--------|------------|-----------------------------|
| STATUS | CONFIDENCE |            NAME             |
|--------|------------|-----------------------------|
| Pass   |         10 | Binary-Artifacts            |
|--------|------------|-----------------------------|
| Pass   |         10 | CI-Tests                    |
|--------|------------|-----------------------------|
| Pass   |         10 | Code-Review                 |
|--------|------------|-----------------------------|
| Pass   |         10 | Contributors                |
|--------|------------|-----------------------------|
| Pass   |         10 | Frozen-Deps                 |
|--------|------------|-----------------------------|
| Pass   |         10 | Token-Permissions           |
|--------|------------|-----------------------------|
| Pass   |         10 | Vulnerabilities             |
|--------|------------|-----------------------------|
| Fail   |         10 | Active                      |
|--------|------------|-----------------------------|
| Fail   |          3 | Automatic-Dependency-Update |
|--------|------------|-----------------------------|
| Fail   |         10 | Branch-Protection           |
|--------|------------|-----------------------------|
| Fail   |         10 | CII-Best-Practices          |
|--------|------------|-----------------------------|
| Fail   |         10 | Fuzzing                     |
|--------|------------|-----------------------------|
| Fail   |          0 | Packaging                   |
|--------|------------|-----------------------------|
| Fail   |          3 | Pull-Requests               |
|--------|------------|-----------------------------|
| Fail   |         10 | SAST                        |
|--------|------------|-----------------------------|
| Fail   |         10 | Security-Policy             |
|--------|------------|-----------------------------|
| Fail   |          0 | Signed-Releases             |
|--------|------------|-----------------------------|
| Fail   |         10 | Signed-Tags                 |
|--------|------------|-----------------------------|

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we were to fork Protolock, I'd ask "why can't we rely on the standard protoc plugin FileDescriptorProto for the AST parse tree here?".

Copy link
Contributor

@adisuissa adisuissa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this! Looks like a very good start, and I've got a few comments.

I think we should introduce a new python class/script that wraps the call to protolock, which will store the entire logic of calling protolock. The test function will use it to run protolock, and this can be also called by CI later on. By doing so we are making sure that both the test and the non-test uses of protolock have the same behavior.

name = "protolock_test",
srcs = ["protolock_test.py"],
data = [
"//tools/testdata/api_protolock:allowed/test_add_comment_current",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be possible to have this list of testdata files in a build file in the testdata directory, and just reference that.

tools/api_protolock/protolock_test.py Show resolved Hide resolved
tools/api_protolock/protolock_test.py Show resolved Hide resolved
def test_change_field_name(self):
self.run_protolock_test("breaking", self.test_change_field_name.__name__)

@unittest.skip("package name detection not yet added to Protolock (simply requires plugin)")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment with tracking issue link

tools/api_protolock/protolock_test.py Show resolved Hide resolved
tools/api_protolock/protolock_test.py Show resolved Hide resolved
data = [
"//tools/testdata/api_protolock:allowed/test_add_comment_current",
"//tools/testdata/api_protolock:allowed/test_add_comment_next",
"//tools/testdata/api_protolock:allowed/test_add_enum_value_current",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, how come some equivalent of these tests doesn't exist in Protolock upstream? Would these belong there at some point?

@htuch
Copy link
Member

htuch commented Aug 5, 2021

@YaseenAlk should we close this out given the move to buf?
/wait

@YaseenAlk
Copy link
Contributor Author

@YaseenAlk should we close this out given the move to buf?
/wait

Yes, closing in favor of #17515 which uses buf

@YaseenAlk YaseenAlk closed this Aug 5, 2021
htuch pushed a commit that referenced this pull request Aug 19, 2021
Follow-up to #17375 where it was agreed that protolock is not actively maintained enough to depend on. This PR "migrates" the tests from that PR to use buf instead, and also cleans some of the code per a few of the review comments. Still a few outstanding points:

- buf build on the envoy/api folder requires several protobuf dependencies such as udpa to be available to buf to consume. Suggested solution by buf is to point buf's config to necessary BSR modules that the buf team is hosting.
  - These lines are commented out in this PR as I had some trouble automating it for the tests, and it is not necessary for the tests to pass
  - May introduce issues if buf is not pointing to the same version of modules that bazel builds for envoy. May need to introduce some way to couple them, or (ideally) find a way to run the breaking change detector without building the dependencies
- Currently bazel is using a binary release of buf (for linux). Goal is to move to building it from source in the near future
- It may be in our interest to expand the list of API-breaking-change rules (buf provides an extensive list of rules we could adopt)

Risk Level: Low

Testing: Tests that evaluate buf against "allowed" and "breaking" protobuf API changes. Currently 4 tests are skipped - 3 of them are PGV-related (we need to communicate our desired PGV rules to the buf team so they may add them in the near future). The 4th is a test I had originally written to evaluate protolock but may not apply to buf ("forcing" a breaking change) - refer to comments

Docs Changes:
Release Notes:
Platform Specific Features: buf binary imported by bazel is linux-only. Hopefully the ["manual"] tags attribute prevents any issues for non-linux users

Signed-off-by: Yaseen Alkhafaji <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deps Approval required for changes to Envoy's external dependencies waiting
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants