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

Pull request remediations engine + codeQL + dependabot remediations #1200

Merged
merged 6 commits into from
Oct 16, 2023

Conversation

jhrozek
Copy link
Contributor

@jhrozek jhrozek commented Oct 13, 2023

This PR adds a new remediations engine that is able to open pull requests.
At the moment, the only way the remediator can open PRs is to replace a file,
in subsequent PRs we might want to add patches (e.g. to support two dependabot
configurations, each for a different ecosystem), but the API support for that
should be there.

The PR is opened if no other PR with the same content hash exists. We might want
to revisit that to store the PR in the database instead to save API calls, but
this way was quiet straightforward and works fine.

The PR also amends the CodeQL and dependabot rule_types with remediations.

Fixes: #1064
Fixes: #1077
Fixes: #1078

@jhrozek
Copy link
Contributor Author

jhrozek commented Oct 13, 2023

I will add some comments to explain my thinking behind the PR.

// the file to patch
string path = 1;
// how to patch the file. For now, only replace is supported
string action = 2;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The idea here is to add several more actions. I think both JSON merge patch and JSON patch would be useful here, the former to patch YAML/JSON files to include some content in general and the latter to add an item to a JSON/YAML array which you can't do with a merge patch AFAIK.

The other attribute I think we should use would be a "condition" which might be a JQ condition that must pass in order for the action to be performed. We can have something like:

content:
 - path: .github/dependabot.yaml
    action: replace
    condition: <if-empty>
 - path. .github/dependabot.yaml
    action: mergePatch
    condition: <if-already-some-contents-but-not-this-ecosystem>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

tracked with #1210 for a future PR

// the GIT mode of the file. Not UNIX mode! String because the GH API also uses strings
// the usual modes are: 100644 for regular files, 100755 for executable files and
// 040000 for submodules (which we don't use but now you know the meaning of the 1 in 100644)
string mode = 3;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The default is 10644 which translates to "a file with 0644 UNIX permissions" and it's handled in the code. Hmm maybe I should have made the mode optional?

Copy link
Contributor

Choose a reason for hiding this comment

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

Optional would be better, yeah. Let's just try to have easy to use defaults

Copy link
Contributor Author

Choose a reason for hiding this comment

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

made optional

// if no mode is specified, create a regular file with 0644 UNIX permissions
ghModeNonExecFile = "100644"
dflBranchBaseName = "mediator"
dflBranchFrom = "main"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These should be ultimately configurable in the rule_types and the remediator, but since the rule_types don't allow to configure the branches either, I was thinking of doing a follow-up.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

filed #1205 for future reference

@@ -64,7 +64,7 @@ func NewOAuthConfig(provider string, cli bool) (*oauth2.Config, error) {
if provider == Google {
return []string{"profile", "email"}
}
return []string{"user:email", "repo", "read:packages", "write:packages", "read:org"}
return []string{"user:email", "repo", "read:packages", "write:packages", "workflow", "read:org"}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. the workflow permission is needed in order to write under ~/.github/workflows
  2. should we change repo for public_repo ?

Copy link
Contributor

Choose a reason for hiding this comment

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

What does changing to public_repo gives us?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

not being allowed to touch private repos (I know we can't register them as of now..and don't process them with web hooks at the moment).

Copy link
Contributor

Choose a reason for hiding this comment

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

No strong opinion on this

@jhrozek
Copy link
Contributor Author

jhrozek commented Oct 15, 2023

rebased atop Radoslav's recent alerting work

We'll need to use several methods from the GH API in order to open pull
requests. This patch adds them to the provider interface we use.
Adds a new protobuf message that represents the pull request
remediation.
Adds a new remediator whose job it is to open pull requests. Currently,
the pull requests are only opened unless another PR with exactly the
same contents exists.
In order to propose PRs that include files under the .github/workflows
subtree, we need to grant Mediator the workflows scope as well.
Adds two usages of PR remediations, for dependabot and codeQL.
@jhrozek
Copy link
Contributor Author

jhrozek commented Oct 15, 2023

rebased on current master & addressed the comments (which was really just making that one protobuf field optional).
btw there are no tests at all. I think we should add some if for nothing else than to check that the templates are expanding correctly, but I wanted to get some review pass first - the tests would probably be mocking the API and would depend on the structure of the remediator quite a bit so I'd like to write them when other developers agree that this code is acceptable.

@JAORMX
Copy link
Contributor

JAORMX commented Oct 16, 2023

The test makes sense to me, let's get some tests

@jhrozek
Copy link
Contributor Author

jhrozek commented Oct 16, 2023

The test makes sense to me, let's get some tests

thanks for the review, test added

@jhrozek jhrozek merged commit 5ecac19 into stacklok:main Oct 16, 2023
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a Dependabot remediation Add a CodeQL remediation Implement pull request remediator
2 participants