Skip to content

Conversation

@savokr-asana
Copy link
Contributor

@savokr-asana savokr-asana commented Apr 22, 2025

Description
This PR introduces support for adding github attachments to corresponding asana task. Currently, it only happens on PR creation, will be fixed for PR updates as well soon.

Test
Added unit tests are passing together with extract_attachments function tested on real codez PR and video/images attachments.

Pull Request synchronized with Asana task
Pull Request: #208

@savokr-asana
Copy link
Contributor Author

savokr-asana commented Apr 23, 2025

Just found out one thing that attachments copy-pasted from local files are "encoded" as HTML tag even in markdown, so will need to add support for that as well, it will be quite easy and I will try to simplify current logic to rely only on html based text body instead of markdown.

Copy link
Collaborator

@suzyng83209 suzyng83209 left a comment

Choose a reason for hiding this comment

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

Sorry for missing this pull request for a while. All of the code looks good. I do think you need to fix some types but the test failures look transient so a re-run may resolve it.

Let me know when you want to deploy this change!

@asana-sgtm asana-sgtm bot assigned savokr-asana and unassigned suzyng83209 May 14, 2025
@savokr-asana
Copy link
Contributor Author

savokr-asana commented May 15, 2025

@suzyng83209 Thanks for the review! There is one thing still missing in the PR, and it's the update of attachments when a Github description/comment is updated. It's really important since the flow with git pr forces us to add attachments only after the initial PR is created, so in order to actually add them properly in asana, we should support the update of the task as well. To do it properly, you should probably create a dynamodb mapping with github pr -> asana attachment ids, but I was thinking of doing it in simpler way by fetching the current attachments names and comparing old vs new ones. I will try to work on it tomorrow and you can probably re-review the changes and try testing it as well.

Upd: Thought a little more about the "simpler" approach and I don't think it will work that good, so will try to implement a dynamodb thing instead.

Comment on lines +11 to +40
def get_dynamodb_resource():
"""Get the DynamoDB resource, creating it lazily on first access."""
global _dynamodb_resource
if _dynamodb_resource is None:
_dynamodb_resource = boto3.resource("dynamodb", region_name=AWS_REGION)
return _dynamodb_resource


def get_dynamodb_lock_client():
"""Get the DynamoDB lock client, creating it lazily on first access."""
global _dynamodb_lock_client
if _dynamodb_lock_client is None:
_dynamodb_lock_client = DynamoDBLockClient(
get_dynamodb_resource(),
table_name=LOCK_TABLE,
lease_duration=timedelta(seconds=20),
expiry_period=timedelta(
minutes=2
), # The Lambda function has a 120 second timeout by default
)
return _dynamodb_lock_client


# Create a lazy-loading module-level variable
class _LazyLockClient:
def __getattr__(self, name):
return getattr(get_dynamodb_lock_client(), name)


dynamodb_lock_client = _LazyLockClient()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was suggested by cursor, and I decided to leave it. From my understanding it is a best-practice to initialize things like that lazily, so it's a small improvement to current implementation.

Let me know if you think it's better to remove it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Makes sense and looks good to keep - though I don't think it'll be huge improvement since we always need to lock client to be fully set up whenever we access it.

Copy link
Contributor Author

savokr-asana commented Jun 23, 2025

Comment on lines +11 to +40
def get_dynamodb_resource():
"""Get the DynamoDB resource, creating it lazily on first access."""
global _dynamodb_resource
if _dynamodb_resource is None:
_dynamodb_resource = boto3.resource("dynamodb", region_name=AWS_REGION)
return _dynamodb_resource


def get_dynamodb_lock_client():
"""Get the DynamoDB lock client, creating it lazily on first access."""
global _dynamodb_lock_client
if _dynamodb_lock_client is None:
_dynamodb_lock_client = DynamoDBLockClient(
get_dynamodb_resource(),
table_name=LOCK_TABLE,
lease_duration=timedelta(seconds=20),
expiry_period=timedelta(
minutes=2
), # The Lambda function has a 120 second timeout by default
)
return _dynamodb_lock_client


# Create a lazy-loading module-level variable
class _LazyLockClient:
def __getattr__(self, name):
return getattr(get_dynamodb_lock_client(), name)


dynamodb_lock_client = _LazyLockClient()
Copy link
Contributor

Choose a reason for hiding this comment

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

Makes sense and looks good to keep - though I don't think it'll be huge improvement since we always need to lock client to be fully set up whenever we access it.

os.environ.setdefault("AWS_ACCESS_KEY_ID", "foobar_key")
os.environ.setdefault("AWS_SECRET_ACCESS_KEY", "foobar_secret")
# Set ENV to test so the config module provides proper test defaults
os.environ.setdefault("ENV", "test")
Copy link
Contributor

Choose a reason for hiding this comment

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

are we using this env var anywhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, no, forgot to remove these changes after figuring out how to fix CI errors. This file shouldn't have any changes at all, fixed that.

@savokr-asana savokr-asana merged commit b05da05 into master Jun 24, 2025
3 checks passed
@savokr-asana savokr-asana deleted the saveliinovikov-add-media-attachments branch June 24, 2025 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants