aws-samples / aws-codecommit-pull-request-aws-codebuild

Validating AWS CodeCommit Pull Requests with AWS CodeBuild and AWS Lambda
MIT No Attribution
46 stars 46 forks source link

Incorrect rendering of CodeBuild badges #3

Open matsev opened 5 years ago

matsev commented 5 years ago

What is the correct way of creating markdown in CodeCommit comments so that CodeBuild badge images are visible inline in CodeCommit? In my projects, I found that the CodeBuild comments containing links to CodeBuild badges are rendered as external links instead of showing the actual badges, e.g.

image

When clicked on, the browser opens a new window / tab with the build badge visible.


The implementation looks correct, in the CodeBuildResultFuction[sic], the link to the failing CodeBuilds evaluates to

![Failing](https://s3-eu-west-1.amazonaws.com/codefactory-eu-west-1-prod-default-build-badges/failing.svg "Failing")

Failing

and the passing CodeBuilds

![Passing](https://s3-eu-west-1.amazonaws.com/codefactory-eu-west-1-prod-default-build-badges/passing.svg "Passing")

Passing

In GitHub markdown (above) and in the blog post, these images are visible inline correctly: image.


Note 1, manual copy / paste of

![Failing](https://s3-eu-west-1.amazonaws.com/codefactory-eu-west-1-prod-default-build-badges/failing.svg "Failing")

into a new CodeCommit comment also renders erroneously as an external link:

image


Note 2, when changing the links to CodeBuild badge urls the images are displayed correctly inline in the comment.

KarstenSiemer commented 4 years ago

Hello @matsev, I am trying to following along the same blog post and have the same problem. What did you do as a substitude? Or rather how do I get to know the badge urls at the moment of creating the pipeline?

matsev commented 4 years ago

I just added a comment to the PR about the build status without images.

You can just copy / paste the static code build image urls from the source code of this project. Just just pass the correct arguments to the format function, follow the links below for details.

There are four CodeBuild Badge Statuses. Apart from failing.svg and passing.svg there is also the unknown.svg. However, it is not in_progess.svg as one would expect.

For eu-west-1 you have:

KarstenSiemer commented 4 years ago

thank you! :+1: Still a bit saddening that it is not possible to just comment a static badge

kolomied commented 4 years ago

I found that even with CodeBuild-generated badge URLs it doesn't work properly - I constantly get "Unknown" badge for PR builds.

As a workaround I utilized emoji unicode symbols in PR comments to achieve the following:

image

Here is the updated lambda code snippet I used to generate this:

import boto3
codecommit_client = boto3.client('codecommit')

def lambda_handler(event, context):
    for item in event['detail']['additional-information']['environment']['environment-variables']:
        if item['name'] == 'pullRequestId': pull_request_id = item['value']
        if item['name'] == 'repositoryName': repository_name = item['value']
        if item['name'] == 'sourceCommit': before_commit_id = item['value']
        if item['name'] == 'destinationCommit': after_commit_id = item['value']

    for phase in event['detail']['additional-information']['phases']:
        if phase.get('phase-status') == 'FAILED':
            content = '''## ❌ Pull request build FAILED
See the [Logs]({0})'''.format(event['detail']['additional-information']['logs']['deep-link'])
            break
        else:
            content = '''## ✔️ Pull request build SUCCEEDED
See the [Logs]({0})'''.format(event['detail']['additional-information']['logs']['deep-link'])

    codecommit_client.post_comment_for_pull_request(
      pullRequestId = pull_request_id,
      repositoryName = repository_name,
      beforeCommitId = before_commit_id,
      afterCommitId = after_commit_id,
      content = content
    )
ryands17 commented 3 years ago

Any idea how can we replicate the way they do in the blog post?

ofbeaton commented 2 years ago

I had this problem as well, and discovered a workaround that should please most people. Use the id based syntax. Use

![text][id]
[id]: url "alt-text"

instead of

![label](url "alt-text")

so for the code example in this project, use:

content = '![Failing][Badge] - See the [Logs]({1})\r\n[Badge]: {0} "Failing"'.format(badge, event['detail']['additional-information']['logs']['deep-link'])

instead, similar for the passing one. Note I used \r\n instead of \n, for some reason I couldn't get regular newline to work. This worked for me. The code already converts the url to the proper region.

I also had trouble with that specific lambda function working in all cases, so I changed the code to a large if statement around elif event['detail']['current-phase'] == 'COMPLETED' and event['detail']['build-status'] == 'SUCCEEDED': which I found worked better for my use case as I also wanted to cover the STOPPED and SUBMITTED (so I could link the build) cases. They don't always have the phases dict key used in the original.

I also reported this issue through aws support, including information on the workaround I found, so hopefully everything can be fixed.

joesome-git commented 2 years ago

I did this as @ofbeaton commented and it worked as expected (source code from the AWS Blog).

    for phase in event['detail']['additional-information']['phases']:
      if phase.get('phase-status') == 'FAILED':
        badge = 'https://s3-eu-west-1.amazonaws.com/codefactory-eu-west-1-prod-default-build-badges/failing.svg'
        content = '![Failing][Badge] \r\n\n See the [Logs]({1})\r\n[Badge]: {0} "Failing"'.format(badge, event['detail']['additional-information']['logs']['deep-link'])
        break
      else:
        badge = 'https://s3-eu-west-1.amazonaws.com/codefactory-eu-west-1-prod-default-build-badges/passing.svg'
        content = '![Passing][Badge] \r\n\n See the [Logs]({1})\r\n[Badge]: {0} "Passing"'.format(badge, event['detail']['additional-information']['logs']['deep-link'])

And the result in CodeCommit comment was:

Screenshot 2022-04-04 at 14 53 10

rarylson commented 1 year ago

My tests show that CodeCommit, likely due to security matters, doesn't support including external images via Markdown (it's true for both README.md and other markdown files, as well as for the comments in pull requests).

The only exception I found was for CodeBuild build badges in the format https://codebuild.{AWS_REGION}.amazonaws.com/badges?uuid=UUID_HERE[&branch=BRANCH][&tag=tag]. These are successfully rendered. It may be other exceptions (like an S3 bucket in the same AWS account - I didn't tested, just one example), but I wasn't able them - only the CodeBuild badge. Please note that the CodeBuild build badges URLs send a 302 redirect to the final URL, which is something like https://s3-{AWS_REGION}.amazonaws.com/codefactory-{AWS_REGION}-prod-default-build-badges/{STATUS}.svg. But CodeCommit doesn't render the image if you use the final URL (you need to use the first one, https://codebuild.{AWS_REGION}.amazonaws.com/badges[...].

If someone thinks it's a good idea then to use these CodeBuild build badge images on pull requests, I don't think so. Because the badge will return the status of the latest build for that branch, and not for the specific commit that triggered the pull request build.

People may also find temporary workarounds (like the tentative of using different Markdown syntax). But I think they are not reliable, as Commit can just stop supporting them (this would be expected, as there is currently no support for images besides maybe the CodeBuild build badge images - with ?uuid and ?branch/tag).

Instead, I decide to just use emoji Unicode symbols (just like people usually do in Slack). In my tests, I'm doing build batches, so I did some adaptations.


Batch build BATCH_BUILD_ID (#BATCH_NUMBER) started.

Build BUILD_ID (#NUMBER) update: ⚪ PENDING

Build BUILD_ID (#NUMBER) update: 🟢 SUCCEEDED


Also be aware that, although not documented, for builds that are started as a child of a batch build, the events of type "detail-type": "CodeBuild Build State Change" may have build-status equal to PENDING instead of IN_PROGRESS.