-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Add PullRequestResource functionality for updating labels and comments. #895
Conversation
So there's good news and bad news. 👍 The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so. Everything is all good there. 😕 The bad news is that it appears that one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that here in the pull request. Note to project maintainer: This is a terminal state, meaning the ℹ️ Googlers: Go here for more info. |
/assign @dlorenc |
be0580a
to
53df976
Compare
0ed9abe
to
8f80faf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking great!! I am so excited to have this and be able to start using it for our own CI :D :D :D 🤞
- I love the fake github that you use to test the github image! I'd also like to see some unit test coverage here too if possible (the tests you've currently got are a kind of "integration test" in my opinion since they test the functionality as a whole)
- I think you need to update resource_types.go as well https://github.com/tektoncd/pipeline/blob/ffbb67959dec0abb0f07b1d456398a99531d89f8/pkg/apis/pipeline/v1alpha1/resource_types.go
- I'm a bit confused about why we're including labels - I thought we were going to leave them out of scope for now based on the design doc (and cuz systems like bitbucket don't have them?) - np tho if we decided otherwise, I know folks like @vdemeester have really been wanting some automation around labels in our own workflows, so maybe thats important enough that we included it even if bitbucket doesn't support it?
Before we merge this can you also include:
- Docs on how to use this new resource type https://github.com/tektoncd/pipeline/blob/master/docs/resources.md - one thing im not clear about is how the secrets work exactly, but some usage docs would help with that :D
- An example in the examples dir that uses the PipelineResource
- Maybe an end to end test too in the test dir
- A bit more detail in the commit message about the context 8f80faf (https://github.com/tektoncd/community/blob/master/standards.md#commit-messages)
/meow space
cmd/pullrequest-init/fake_github.go
Outdated
} | ||
|
||
func (g *FakeGitHub) getPullRequest(w http.ResponseWriter, r *http.Request) { | ||
id, err := strconv.ParseInt(mux.Vars(r)["number"], 10, 64) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what mux.Vars
all about? I tried looking at the docs for the function but I still don't quite understand what's happening here :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's how you extract path variables with mux. See https://www.gorillatoolkit.org/pkg/mux
cmd/pullrequest-init/github.go
Outdated
// NewGitHubHandler initializes a new handler for interacting with GitHub | ||
// resources. | ||
func NewGitHubHandler(ctx context.Context, logger *zap.SugaredLogger, rawURL string) (*GitHubHandler, error) { | ||
token := strings.TrimSpace(os.Getenv("GITHUBOAUTHTOKEN")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm where does GITHUBOAUTHTOKEN
come from? maybe it could be mentioned in the README? (what will be setting this?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's passed in as an environment variable from the generated Container spec. Added a note in the README.
Name string `json:"name"` | ||
Type PipelineResourceType `json:"type"` | ||
URL string `json:"url"` | ||
GithubOauthToken string `json:"githubOauthToken"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the plan to support more than just oauth token based auth? (disclaimer: i dont know what im talking about 😅 )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I would like to support GitHub Apps at some point in the future. TBD how we're going to do this (I need to read more about how k8s secret management and access works).
} | ||
|
||
// GetParams returns the resource params | ||
func (s PullRequestResource) GetParams() []Param { return []Param{} } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
im confused about why GetParams
exists when every instance of this interface returns an empty list 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't know the answer to this one. =\
Let's raise an issue to see if there was a reason for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, @wlynch did you create an issue already ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
evs := []corev1.EnvVar{} | ||
for _, sec := range s.Secrets { | ||
switch { | ||
case strings.EqualFold(sec.FieldName, "githubOauthToken"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are secrets only added if they have this particular name? (maybe im misunderstanding!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The thought was to pull the value of the token from any (secret name, secret key). We use the FieldName to denote which secret should be used for this so that you can define your k8s with whatever name/key you want and set it in the ResourceSpec with the specified name.
No idea if this is the right way to go about doing this. If there is a better way somewhere else let me know!
Added this to the documentation.
In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
(p.s. sorry this took me 9 days to get to, should have faster turnaround now :D!) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good, just a few questions
// NewGitHubHandler initializes a new handler for interacting with GitHub | ||
// resources. | ||
func NewGitHubHandler(ctx context.Context, logger *zap.SugaredLogger, rawURL string) (*GitHubHandler, error) { | ||
token := strings.TrimSpace(os.Getenv("GITHUBTOKEN")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be good for a follow-up/enhancement and not as part of this PR but, shouldn't we support using secrets for that instead 👼
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. We're loosely using secrets here, but I'm sure there's better practices that we could be following. If you have any examples I can reference, please send them my way!
cmd/pullrequest-init/github_test.go
Outdated
t.Errorf("Raw PR path: want [%s], got [%s]", rawCommentPath, gotPR.Comments[0].Raw) | ||
} | ||
|
||
// Upload |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I originally wanted to do this, but I found that the easiest way to test Upload was to call Download, modify the result of download, then upload. Since a lot of the setup (i.e. populating the fake GitHub server) ends up being duplicative, it seemed simpler to test them together.
The setup for upload could be "hard-coded" file(s) instead of doing Download right ? (that said it might be as long of a setup as calling Download 😅 )
cmd/pullrequest-init/github_test.go
Outdated
t.Fatal(err) | ||
} | ||
if diff := cmp.Diff(want, got); diff != "" { | ||
t.Errorf("PR Diff: %s", diff) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think we are using -got +wanted: %s
elsewhere
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like it's -want +got
, but done.
|
||
switch *mode { | ||
case "download": | ||
logger.Info("RUNNING DOWNLOAD!") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙀 😝
logger.Fatal(err) | ||
} | ||
case "upload": | ||
logger.Info("RUNNING UPLOAD!") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙀 😜
- A `Task`'s output can be your application container image which can be then | ||
deployed in a cluster. | ||
- A `Task`'s output can be a jar file to be uploaded to a storage bucket. | ||
- A `Task`'s input could be a GitHub source which contains your application |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: extra spaces 😅 (sorry 🙇♂️)
} | ||
|
||
// GetParams returns the resource params | ||
func (s PullRequestResource) GetParams() []Param { return []Param{} } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking great! Looks like from my perspective there are 2 main remaining issues:
- Secrets - @vdemeester has some feedback here and I am just generally confused about when we want to use secrets vs. service accounts but you can probably just ignore me and listen to whatever he has to say
- Unit test coverage for the binary itself. It looks like I cant reply to your original comment @wlynch cuz it was on code that is changed so here are my thoughts:
This brings up the common debate of individual unit vs integration style tests. The argument for the integration style with an in-memory fake is to write tests closer to the perspective of the user.
I think both styles of tests are super useful, but relying only on integration tests for coverage i think loses one of the biggest strengths of unit tests: they force us to design our code well.
when you have to write unit tests for individual functions, you have to think more about the signatures.
if the unit tests you end up writing are ugly and hard to deal with, there's a good chance that there is something that can be improved or cleaned up in the abstraction you've created through the functions themselves
These arguably have the same coverage as individual unit tests, and are less brittle to changes for how we structure Upload/Downloads (e.g. with fine-grained unit tests we will need to modify tests for any refactoring work vs with coarse integration style unit tests we do not so long as the Upload/Download interface does not change).
I actually think having to change the tests when you change the code is an advantage. when code changes but tests dont change its hard to know if the changes are doing what they were intended to: unit tests come as close as you can get to providing a "proof" that your changes are going in as expected.
like you said i think it's valuable to have tests a level or two up (integration and end to end) to give you that reassurance that the user facing functionality is working, so i wouldnt say dont write the integration tests, but i am saying still write the unit tests :D
I am now going to shame{less/ful}ly plug my own talk on this very topic: Testing CRDs <-- high recommend the sources slide, particularly "integrated tests are a scam" :D
/meow
|
||
Adding the Pull Request resource as an output of a Task will update the source | ||
control system with any changes made to the pull request resource during the | ||
pipeline. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aaaamazing 🎉
docs/resources.md
Outdated
control system with any changes made to the pull request resource during the | ||
pipeline. | ||
|
||
See [types.go](cmd/pullrequest-init/types.go) for the full payload spec. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm we usually don't link to source code like this for the spec 🤔 maybe we could link to generated go-docs? (i dont see any other cmd
info at https://godoc.org/github.com/tektoncd/pipeline tho 🤔 )
in most of our other docs we duplicate this information which i personally think is worth it even if it can be out of date, cuz its way easier to read, e.g. https://github.com/tektoncd/pipeline/blob/master/docs/tasks.md#syntax
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replaced with sample payload.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tfw the person goes along with your request and you feel you have maybe gone too far XD
jk jk I think this is probably good to have :D
secrets: | ||
- fieldName: githubToken | ||
secretName: github-secrets | ||
secretKey: token |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm do we have any idea where we draw the line between when we use the service account attached to the task and when we want ppl to specify secrets @vdemeester @wlynch ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is something I want to look into more, particularly when we start looking at GitHub Apps. For now this is probably fine. But a good target for a follow up change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreeing with @wlynch we can do a follow-up 👼
- Manifest indicates that resource should be fetched using a source | ||
manifest file. | ||
- If `artifactType` is set to `Manifest`, `location` should point to a | ||
source manifest file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm was all this whitespace changing intentionally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. The standard Google mdformat did this. =\
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah kk 😅 I'm sure @mattmoor-sockpuppet will have something to say about it XD
URL string `json:"url"` | ||
GithubOauthToken string `json:"githubOauthToken"` | ||
//Secrets holds a struct to indicate a field name and corresponding secret name to populate it | ||
Secrets []SecretParam `json:"secrets"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i have a feeling that Type
is being used to inspect PipelineResources
without having to use introspection to see specifically what type of resource it is (e.g. if you have a list of PipelineResources
) - but looking for usages might help clear that up (unless it isnt used?)
Name i think is the name of the resource, like wizzbang-git
in this example
(or if im totally wrong then i have no idea what they are either)
/meow |
In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
Amaaaazing thanks for trying this out @afrittoli and for the insightful feedback!!! (And the cool demo today!) |
So there's good news and bad news. 👍 The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so. Everything is all good there. 😕 The bad news is that it appears that one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that here in the pull request. Note to project maintainer: This is a terminal state, meaning the ℹ️ Googlers: Go here for more info. |
Missing from this change: * Statuses, since this might involve more discussion on the set of statuses that we want to support. * Updating from changes to the raw payloads. Unclear how we want to handle these at the moment. Punting on this for now. First step for supporting tektoncd#778. Co-authored-by: Dan Lorenc <[email protected]> Co-authored-by: Billy Lynch <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looking great! after the commits get squashed i am happy to approve + merge!
🎉🎉🎉
(and then very excited to start using it... haha :D)
want := []*github.IssueComment{comment2, comment3} | ||
if diff := cmp.Diff(want, got); diff != "" { | ||
t.Errorf("-want +got: %v", diff) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice unit tests!! 😎
A Googler has manually verified that the CLAs look good. (Googler, please make sure the reason for overriding the CLA status is clearly documented in these comments.) ℹ️ Googlers: Go here for more info. |
/approve |
In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: bobcatfish, wlynch The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
wooooot 🎉 |
This adds support for the GitHub Status API (https://developer.github.com/v3/repos/statuses/). This accompanies tektoncd#778 and tektoncd#895 to complete initial Pull Request support support for GitHub OAuth.
This adds support for the GitHub Status API (https://developer.github.com/v3/repos/statuses/). This accompanies tektoncd#778 and tektoncd#895 to complete initial Pull Request support support for GitHub OAuth.
This adds support for the GitHub Status API (https://developer.github.com/v3/repos/statuses/). This accompanies tektoncd#778 and tektoncd#895 to complete initial Pull Request support support for GitHub OAuth.
This adds support for the GitHub Status API (https://developer.github.com/v3/repos/statuses/). This accompanies tektoncd#778 and tektoncd#895 to complete initial Pull Request support support for GitHub OAuth.
This adds support for the GitHub Status API (https://developer.github.com/v3/repos/statuses/). This accompanies tektoncd#778 and tektoncd#895 to complete initial Pull Request support support for GitHub OAuth.
This adds support for the GitHub Status API (https://developer.github.com/v3/repos/statuses/). This accompanies #778 and #895 to complete initial Pull Request support support for GitHub OAuth.
Changes
Add PullRequestResource functionality for updating labels and comments.
Missing from this change:
that we want to support.
handle these at the moment. Punting on this for now.
First step for supporting #778.
This takes over initial work done by @dlorenc in #779
Submitter Checklist
These are the criteria that every PR should meet, please check them off as you
review them:
Release Notes