Visitar URL original
Add a self-hosted image server for CML reports by shcheklein · Pull Request #1499 · iterative/cml · GitHub
Skip to content

Add a self-hosted image server for CML reports - #1499

Open
shcheklein wants to merge 1 commit into
mainfrom
image-server
Open

shcheklein wants to merge 1 commit into
mainfrom
image-server

Conversation

@shcheklein

Copy link
Copy Markdown
Member

asset.cml.dev no longer accepts uploads. Reports that embed local images now need either --publish-native (GitLab and Bitbucket) or an image server of their own, configured with --publish-url / CML_COMMENT_PUBLISH_URL. This PR adds a reference server that people can deploy in a few commands. It replaces the old minroud-s3 reference, which hasn't been updated since 2022.

What's in image-server/

  • template.yml: a CloudFormation template that creates a private S3 bucket and a Lambda function URL. The Python handler is inline in the template.
    • POST /?token=… stores the body under the SHA-256 of its contents and returns the image URL.
    • GET /<sha256> serves the image publicly.
    • Uploads without the right token get an empty 403, which CML reports as Empty response from asset backend with status code 403.
    • The token goes in the URL because CML can't send custom headers.
  • README.md: deploy, CI setup, token rotation, limits, cost and cleanup.
  • test_template.py: tests the inline handler against moto-mocked S3.

The root README's "Images" section now links to it and to https://cml.dev/doc/image-hosting, which is added in iterative/cml.dev#541.

Testing

  • cfn-lint template.yml passes, and the 12 tests in test_template.py pass.
  • End to end with CML 0.20.6: I ran the inline handler behind a local server that builds Lambda function URL events, with S3 mocked.
    • cml asset publish via CML_ASSET_URL and cml comment create via CML_COMMENT_PUBLISH_URL both upload to it.
    • The returned URL serves byte-identical content with the right Content-Type.
  • Not tested: the template hasn't been deployed to a real AWS account yet.
  • Permissions: it adds both lambda:InvokeFunctionUrl and lambda:InvokeFunction (with InvokedViaFunctionUrl), which public function URLs have required since October 2025.

🤖 Generated with Claude Code

asset.cml.dev no longer accepts uploads, so reports that embed local images
need their own server for --publish-url / CML_COMMENT_PUBLISH_URL.

image-server/ contains a CloudFormation template (private S3 bucket +
Lambda function URL, inline Python handler) that stores uploads under the
SHA-256 of their contents, requires a token in the publish URL, and serves
images publicly by hash. The README covers deploy, CI setup, token
rotation, limits and cleanup; test_template.py exercises the handler
against a mocked S3 bucket.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

1 participant