-
Notifications
You must be signed in to change notification settings - Fork 5
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
Initial code commit #1
Conversation
|
||
|
||
def _task_name_from_pull_request(pull_request: PullRequest) -> str: | ||
return "#{} - {}".format(pull_request.number(), pull_request.title()) |
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.
Can we use f-strings everywhere we need to do string formatting?
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.
If we use temporary variables instead of expressions in f-strings, then I would agree. Embedding code in f-string {} blocks is generally bad for readability/maintainability, IMO :)
e.g.
def _task_name_from_pull_request(pull_request: PullRequest) -> str:
pr_number = pull_request.number()
pr_title = pull_request.title()
return f"#{pr_number} - {pr_title}"
rather than
def _task_name_from_pull_request(pull_request: PullRequest) -> str:
return f"#{pull_request.number()} - {pull_request.title()}"
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.
Yeah I think I agree with this ^^ and that it's not worth splitting into 3 lines for that reason
return _wrap_in_tag("body")( | ||
_wrap_in_tag("em")( | ||
"This is a one-way sync from GitHub to Asana. Do not edit this task or comment on it!" | ||
) | ||
+ f"\n\n\uD83D\uDD17 {url}" | ||
+ "\n✍️ " | ||
+ asana_author_url | ||
+ _wrap_in_tag("strong")("\n\nDescription:\n") | ||
+ escape(pull_request.body()) | ||
) |
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.
Somewhere in here we would need the task status text right? Task is closed/not closed because...
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.
Yeah, maybe I'll just add a task for tracking that - I took it out explicitly because it just seemed like noise but maybe it's useful for some people
@@ -0,0 +1,47 @@ | |||
from typing import Tuple | |||
from sgqlc.endpoint.http import HTTPEndpoint |
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 was looking into this GraphQL client - and I think we should be able to do something along the lines of this to ensure that we can do away with our schema file, and be able to write this
query {
repository(owner: "profusion", name: "sgqlc") {
issues(first: 100) {
nodes {
number
title
}
}
}
}
as
op = Operation(Query)
issues = op.repository(owner=owner, name=name).issues(first=100)
They have an example of how to use their code generator that can output a schema file which we can directly query against in python code. (We would merge this in its current form and then I could work on changing how we use GraphQL)
if len(maybe_multi_assignees) == 1: | ||
return maybe_multi_assignees[0] | ||
elif len(maybe_multi_assignees) == 0: | ||
logger.info("GitHub PR has no assignees. Choosing author as assignee") |
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 text is also currently something that is part of the task description
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 didn't feel the need - but can add a task for it
logger.info( | ||
"GitHub PR has multiple assignees: {} Choosing first one in alphabetical order as as assignee: {}".format( | ||
maybe_multi_assignees, assignee | ||
) | ||
) |
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.
Same with this text - we would need some way to make sure the _task_description_from_pull_request
method gets this message - the current Clojure code returns an object of the form
{
assignee: ...
warning: ...
}
and displays these warnings if present
src/github/utils.py
Outdated
@@ -0,0 +1,7 @@ | |||
from datetime import datetime |
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 file isn't related to github, so we could move it to the top level directory.
src/asana/client.py
Outdated
client.tasks.add_followers(task_id, {"followers": followers}) | ||
|
||
|
||
def add_comment(task_id: str, comment_body: str): |
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: str return type
"completed": _task_completion_from_pull_request(pull_request), | ||
"followers": _task_followers_from_pull_request(pull_request), | ||
} | ||
|
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'm open to working on splitting out some of the functions in this file into a couple different files (one for creating asana comment from git comment, another for task from pr, etc.) and doing some general cleanup! I feel like not all of this logic should be just in a helpers 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.
LGTM!
I believe there might be a major piece of functionality missing, i.e. adding newly created SGTM tasks to a pre-configured / pre-created project. This should probably be addressed prior to using SGTM in Asana, but does not need to be addressed in this PR. I added an Asana task for this.
None of my other review comments need immediate action, and I am happy to do them all myself in subsequent PRs, assuming that you agree with them.
provider "aws" { | ||
region = "us-east-1" | ||
shared_credentials_file = "/Users/gregeinfrank/.aws/credentials" | ||
profile = "sgtm" | ||
} |
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 believe that this information should be specified via Terraform variables, rather than hardcoded in the script
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.
Yeah - this was for my testing because I wanted to override the profile to sgtm (pointing to my personal AWS account) -- I'll leave out of this PR
# The filebase64sha256() function is available in Terraform 0.11.12 and later | ||
# For Terraform 0.11.11 and earlier, use the base64sha256() function and the file() function: | ||
# source_code_hash = "${base64sha256(file("lambda_function_payload.zip"))}" | ||
source_code_hash = "${filebase64sha256("../function.zip")}" |
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 feel that this should not require the user to edit the source code to achieve the correct result. A few possible solutions to this could include:
-
only supporting Terraform 0.11.12 and later
-
using the interpolation syntax, possibly along with templates, to achieve the desired version specific results.
-
providing different versions of the .tf files for different versions of Terraform, and using a shell script to determine the Terraform version and use the appropriate files
-
using the approach we use in Asana with .yaml.py files, e.g. main.tf.py is a python script that outputs main.tf, using whatever means it finds appropriate to create the file, such as using the Python template system, or python string-replace on well-known-strings. A runner script of some sort would handle this transformation phase.
For example:
`
template = """
...
handler = "src.handler.handler"
source_code_hash = "@@SOURCE_CODE_HASH@@"
...
"""
if terraform_11_12_or_later:
output = template.replace("@@SOURCE_CODE_HASH@@", "${filebase64sha256("../function.zip")}")
else:
output = template.replace("@@SOURCE_CODE_HASH@@", """${base64sha256(file("lambda_function_payload.zip"))}""")
print(output)
`
} | ||
|
||
resource "aws_lambda_function" "sgtm" { | ||
filename = "../function.zip" |
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'm assume at this point that I will see later in the review that this zip file is the output of some command executed on the command line. This command should be documented somewhere, e.g. in a README.md file. An alternative would be to use a scripts directory, as mentioned elsewhere in this review.
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.
Actually, I don't see anything in the project that makes it obvious what the functions.zip file should contain precisely, and how it should be created. I'd guess that zipping the src directory, with path info included, would do the trick, but this should be documented.
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.
Yeah - on the TODO list for deployment strategy. I've done this manually so far in testing but will add a script and deployment instructions
|
||
runtime = "python3.7" | ||
|
||
timeout = 30 |
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 believe that this should be a Terraform variable
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.
sur
} | ||
} | ||
|
||
resource "aws_api_gateway_resource" "sgtm_resource" { |
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 single-line(or so) comment for each resource, explaining what it is in plain english, would be great for readability.
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.
Cool - i'll add a task for that
src/github/logic.py
Outdated
reviews = [ | ||
review | ||
for review in pull_request.reviews() | ||
if review.is_approval_or_changes_requested() | ||
and review.submitted_at() < merged_at | ||
] | ||
if reviews: | ||
latest_review = sorted(reviews, key=lambda r: r.submitted_at())[-1] | ||
return latest_review.is_approval() |
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 feel that reviews would be better named premerge_reviews for clarity.
src/github/logic.py
Outdated
comments = [ | ||
comment | ||
for comment in pull_request.comments() | ||
if comment.published_at() > merged_at | ||
] | ||
reviews = [ |
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.
likewise, I'd suggest using the terms postmerge_comments and postmerge_reviews here for increased clarity.
@@ -0,0 +1,132 @@ | |||
from uuid import uuid4 |
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 seems to me from the contents of this file that it could be named request_builders.py, which would be an improvement over the generic "helpers" name.
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 request_builders doesn't seem right because I don't think it's really building "requests" - how about github/stub_builders.py?
test/mock_test_case.py
Outdated
@@ -0,0 +1,45 @@ | |||
""" |
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 file should probably be renamed something like mock_dynamobdb_test_case
test/mock_test_case.py
Outdated
|
||
|
||
@mock_dynamodb2 | ||
class MockTestCase(TestCase): |
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.
and likewise, the test case should be named something like MockDynamoDbTestCase, as the name implies that this is more generic than it actually is.
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.
Yeah I think my original plan was to build on this and add more default mocks, but since that didn't happen - that sounds reasonable
Thanks for the comments - I tried to address everything or open a task for it. I'm going to merge so people can start opening up branches |
This is a WIP PR while I work through tests and TODOs