feat: enhance Telegram bot with search improvements, Docker support and CI#195
feat: enhance Telegram bot with search improvements, Docker support and CI#195aiastia wants to merge 2 commits into
Conversation
…nd CI - Add GitHub Actions workflow for multi-arch Docker build (amd64/arm64) - Add Dockerfile with cross-compilation, non-root user, and layer caching - Add docker-compose.yml with data persistence - Support --all flag in /search to search all public memos - Add clickable memo links in search results (HTML parse mode) - Wrap search result content in <code> tag for easy copy - Default memo visibility to PUBLIC - Add normalizeBaseURL() for valid HTML memo links - Degrade to plain HTML on UID extraction failure - Copy /etc/group alongside /etc/passwd for user resolution - Use static:latest instead of static:latest-glibc - Align README Docker Compose docs with actual docker-compose.yml - Document /search --all command in README
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThis PR extends the memogram Telegram bot with containerization, deployment infrastructure, and an enhanced search feature. It adds a GitHub Actions workflow for multi-platform Docker builds, updates the Dockerfile for cross-compilation and rootless execution, introduces docker-compose configuration, documents data persistence, implements a ChangesContainer and Deployment Infrastructure
Search Enhancement Feature
Result Rendering, Visibility, and URL Normalization
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (4)
.github/workflows/build.yml (1)
45-54: ⚡ Quick winConsider adding vulnerability scanning and provenance attestation.
The build step successfully creates and pushes multi-architecture images, but consider enhancing the pipeline with:
- Image vulnerability scanning (e.g., using Trivy action) to catch security issues before publishing
- SBOM generation and provenance attestation for supply chain security
These additions would improve the security posture of published images.
🔒 Example: Add Trivy scanning
Add this step after the build step:
- name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest format: 'sarif' output: 'trivy-results.sarif' - name: Upload Trivy results to GitHub Security uses: github/codeql-action/upload-sarif@v3 if: always() with: sarif_file: 'trivy-results.sarif'For provenance attestation, add to the build-push-action:
provenance: true sbom: true🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/build.yml around lines 45 - 54, Update the "Build and push" workflow step (the job using docker/build-push-action@v6) to emit provenance and SBOM by enabling the provenance and sbom options on the build-push action and add a follow-up vulnerability scan step using the aquasecurity/trivy-action (e.g., a new job/step named "Run Trivy vulnerability scanner") that scans the pushed image (use the same image ref pattern as used for tags) and outputs SARIF; also add an "Upload Trivy results to GitHub Security" step (using github/codeql-action/upload-sarif@v3) that always runs to upload the SARIF file.Dockerfile (1)
20-20: 💤 Low valueAddress the Trivy warning about placeholder secrets.
The static analysis tool flags
BOT_TOKENas a potential secret exposure. While this is a false positive (it's clearly a placeholder that will be overridden at runtime), you can eliminate the warning by removing the default value entirely, since BOT_TOKEN must be provided by the user anyway.♻️ Proposed fix
-ENV BOT_TOKEN=your_telegram_bot_token +# BOT_TOKEN must be set via docker run -e or docker-compose environment🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Dockerfile` at line 20, Remove the placeholder default value for BOT_TOKEN to avoid Trivy false positives: locate the ENV declaration for BOT_TOKEN (the line with "ENV BOT_TOKEN=your_telegram_bot_token") and either delete the line entirely or change it to an empty ENV declaration (e.g., "ENV BOT_TOKEN") so that BOT_TOKEN must be supplied at runtime rather than baked into the image.memogram.go (2)
302-305: ⚡ Quick winConsider extracting base URL resolution logic.
The pattern of checking
instanceProfile.InstanceUrland falling back toconfig.ServerAddris repeated in three locations (memo save, callback handler, search handler). Extracting this to a helper method would improve maintainability.♻️ Suggested refactor
Add a helper method:
func (s *Service) getBaseURL() string { baseURL := normalizeBaseURL(s.config.ServerAddr) if s.instanceProfile != nil && s.instanceProfile.InstanceUrl != "" { baseURL = normalizeBaseURL(s.instanceProfile.InstanceUrl) } return baseURL }Then replace all three occurrences with:
- baseURL := normalizeBaseURL(s.config.ServerAddr) - if s.instanceProfile != nil && s.instanceProfile.InstanceUrl != "" { - baseURL = normalizeBaseURL(s.instanceProfile.InstanceUrl) - } + baseURL := s.getBaseURL()Also applies to: 458-461, 532-535
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@memogram.go` around lines 302 - 305, Extract the repeated base URL resolution into a helper on Service: create a method (e.g., func (s *Service) getBaseURL() string) that calls normalizeBaseURL(s.config.ServerAddr) and returns normalizeBaseURL(s.instanceProfile.InstanceUrl) when s.instanceProfile != nil && s.instanceProfile.InstanceUrl != "" ; then replace the three inline blocks that set baseURL (the ones using normalizeBaseURL(s.config.ServerAddr) and checking s.instanceProfile.InstanceUrl) with a call to s.getBaseURL() in the memo save, callback handler, and search handler locations to centralize the logic and avoid duplication.
562-566: ⚡ Quick winThe filter syntax is correct, but consider extracting the visibility string to a constant.
The
visibility == "PUBLIC"filter syntax matches the Memos API specification. However, to improve maintainability and prevent typos, consider defining a constant:const visibilityPublicFilter = "PUBLIC"Then use it in the filter expression:
return fmt.Sprintf("%s && visibility == %q", filter, visibilityPublicFilter)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@memogram.go` around lines 562 - 566, Extract the literal "PUBLIC" used in the filter inside buildMemoSearchFilter into a named constant (e.g., visibilityPublicFilter = "PUBLIC") and use that constant when composing the filter string so the visibility token is centralized and less error-prone; update buildMemoSearchFilter to reference visibilityPublicFilter when building the "%s && visibility == %q" expression.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docker-compose.yml`:
- Line 11: The SERVER_ADDR default of "dns:localhost:5230" is incorrect for
containers and will point to the container's own localhost; update the
docker-compose environment handling so SERVER_ADDR no longer defaults to
dns:localhost:5230 (remove the default or change it to a clearly invalid
placeholder) and document required values (e.g., host.docker.internal:5230 for
host, dns:memos:5230 for another container service, or the remote hostname) so
callers must explicitly set SERVER_ADDR (refer to the SERVER_ADDR variable and
the .env usage) and update the README to emphasize setting SERVER_ADDR in the
.env before running.
In `@Dockerfile`:
- Line 19: The Dockerfile currently sets a non-functional default ENV
SERVER_ADDR=dns:localhost:5230 which breaks containerized deployments; change
this so the image requires explicit configuration by replacing that default with
a clear placeholder (e.g., set ENV SERVER_ADDR=REQUIRED_SET_THIS_VALUE) or
remove the ENV assignment entirely so users must supply SERVER_ADDR at runtime,
and update any README/docs to mention that SERVER_ADDR must be provided; target
the ENV SERVER_ADDR entry in the Dockerfile to make this change.
- Line 13: The Dockerfile uses Alpine-specific "adduser -D -u 1000 memogram"
which is incompatible with the Wolfi-based Chainguard image; replace that RUN
instruction with the standard useradd invocation (create the home directory and
set the UID) by using useradd with -u 1000 and -m for memogram so the user is
created correctly on Wolfi.
In `@memogram.go`:
- Around line 543-552: The anchor branch for tgMessage constructs HTML without
escaping memo.Name and memoUID, risking XSS; update the successful-path
construction (where memoUID is set from ExtractMemoUIDFromName and tgMessage is
assigned) to HTML-escape both memo.Name and memoUID (e.g., via
html.EscapeString) before interpolating them into the href and link text so the
anchor uses the escaped memoUID and escaped memo.Name; keep the existing
escapedContent usage and preserve the error-path behavior that already escapes
memo.Name.
---
Nitpick comments:
In @.github/workflows/build.yml:
- Around line 45-54: Update the "Build and push" workflow step (the job using
docker/build-push-action@v6) to emit provenance and SBOM by enabling the
provenance and sbom options on the build-push action and add a follow-up
vulnerability scan step using the aquasecurity/trivy-action (e.g., a new
job/step named "Run Trivy vulnerability scanner") that scans the pushed image
(use the same image ref pattern as used for tags) and outputs SARIF; also add an
"Upload Trivy results to GitHub Security" step (using
github/codeql-action/upload-sarif@v3) that always runs to upload the SARIF file.
In `@Dockerfile`:
- Line 20: Remove the placeholder default value for BOT_TOKEN to avoid Trivy
false positives: locate the ENV declaration for BOT_TOKEN (the line with "ENV
BOT_TOKEN=your_telegram_bot_token") and either delete the line entirely or
change it to an empty ENV declaration (e.g., "ENV BOT_TOKEN") so that BOT_TOKEN
must be supplied at runtime rather than baked into the image.
In `@memogram.go`:
- Around line 302-305: Extract the repeated base URL resolution into a helper on
Service: create a method (e.g., func (s *Service) getBaseURL() string) that
calls normalizeBaseURL(s.config.ServerAddr) and returns
normalizeBaseURL(s.instanceProfile.InstanceUrl) when s.instanceProfile != nil &&
s.instanceProfile.InstanceUrl != "" ; then replace the three inline blocks that
set baseURL (the ones using normalizeBaseURL(s.config.ServerAddr) and checking
s.instanceProfile.InstanceUrl) with a call to s.getBaseURL() in the memo save,
callback handler, and search handler locations to centralize the logic and avoid
duplication.
- Around line 562-566: Extract the literal "PUBLIC" used in the filter inside
buildMemoSearchFilter into a named constant (e.g., visibilityPublicFilter =
"PUBLIC") and use that constant when composing the filter string so the
visibility token is centralized and less error-prone; update
buildMemoSearchFilter to reference visibilityPublicFilter when building the "%s
&& visibility == %q" expression.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3c3b5c06-493e-40f8-a05d-197c10030c02
📒 Files selected for processing (6)
.github/workflows/build.ymlDockerfileREADME.mddocker-compose.ymlmemogram.gomemogram_search_filter_test.go
Changes
--allflag in/searchto search all public memos<code>tag for easy copynormalizeBaseURL()for valid HTML memo links/etc/groupalongside/etc/passwdfor user resolutionstatic:latestinstead ofstatic:latest-glibc/search --allcommand in README