Skip to content

ADFA-3269 Share nightly release build with private Telegram channel#1073

Merged
hal-eisen-adfa merged 2 commits intostagefrom
ADFA-3269-Share-nightly-release-to-private-Telegram
Mar 13, 2026
Merged

ADFA-3269 Share nightly release build with private Telegram channel#1073
hal-eisen-adfa merged 2 commits intostagefrom
ADFA-3269-Share-nightly-release-to-private-Telegram

Conversation

@hal-eisen-adfa
Copy link
Collaborator

Upload nightly release to Cloudflare R2 and announce to private telegram channel
Remove obsolete Greengeeks ssh setup

…telegram channel; remove obsolete Greengeeks ssh setup
@hal-eisen-adfa hal-eisen-adfa changed the title ADFA-3269 ADFA-3269 Share nightly release build with private Telegram channel Mar 13, 2026
@hal-eisen-adfa hal-eisen-adfa requested a review from a team March 13, 2026 00:07
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 13, 2026

📝 Walkthrough

Release Notes - ADFA-3269

Key Changes

  • Replaced SSH-based artifact upload with Cloudflare R2 storage

    • Removed SSH key setup, configuration, host verification, and cleanup steps
    • Uses S3-compatible API with Cloudflare credentials for secure, cloud-based storage
    • New Python script (scripts/cloudflare-r2-upload.py) handles APK uploads with progress tracking
  • Added nightly release Telegram notifications

    • New "Send Telegram message" step posts APK download link and recent git commits to private early-access Telegram channel
    • Includes 24-hour git log with automatic fallback handling
  • Modernized CI/CD tooling

    • Added uv package manager for Python dependency management (replaces manual setup)
    • Uses boto3 with intelligent retry configuration (up to 10 attempts, 300s read timeout, 60s connect timeout)

Technical Details

  • APK files uploaded to Cloudflare R2 bucket with variant-specific naming (e.g., name-v8.apk)
  • Upload progress reported in 10% increments for CI-friendly logs
  • Telegram messages properly truncated to 4096-character limit per API constraints
  • Proper Content-Type header set for APK files in R2 storage

Risks & Best Practices Notes

⚠️ Credential Exposure Risk: CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_KEY_ID are stored as GitHub variables (not secrets). While these are not private keys, they are identifiable account attributes that could be exposed in workflow logs. Consider whether these should be marked as secrets instead.

⚠️ Input Validation: The Python script does not explicitly validate file existence before attempting upload—relies on os.path.getsize() to throw on missing files. Consider adding explicit pre-flight checks.

⚠️ Git Log Injection Risk: Git commit messages in Telegram notifications are not explicitly sanitized. While jq should handle JSON escaping, untrusted commit messages with special characters could potentially cause issues. Consider adding explicit sanitization if accepting commits from untrusted sources.

Security Improvement: Removing SSH-based uploads in favor of Cloudflare R2 API authentication is a security best practice—eliminates SSH key management burden and reduces attack surface.

Walkthrough

The release workflow replaces SSH-based artifact uploads with Cloudflare R2 uploads via a new Python script, removes SSH key setup logic, and adds Telegram notifications after the upload completes. The workflow maintains existing post-upload messaging while adding new cloud storage and messaging integrations.

Changes

Cohort / File(s) Summary
Release Workflow Updates
.github/workflows/release.yml
Removes SSH key setup, replaces SCP upload with Cloudflare R2 upload step, adds Telegram notification step after artifact upload.
Cloudflare R2 Upload Script
scripts/cloudflare-r2-upload.py
New Python script implementing S3-compatible upload to Cloudflare R2 with progress tracking, environment variable validation, and conditional APK content-type handling.

Sequence Diagram

sequenceDiagram
    participant GA as GitHub Actions
    participant Script as cloudflare-r2-upload.py
    participant R2 as Cloudflare R2
    participant Telegram as Telegram API
    
    GA->>GA: Build APK
    GA->>Script: Execute with file path & variant
    Script->>Script: Validate environment variables
    Script->>Script: Initialize boto3 S3 client
    Script->>R2: Upload APK with progress tracking
    R2-->>Script: Upload complete
    Script->>GA: Print completion status
    GA->>Telegram: Send notification with APK link
    Telegram-->>GA: Message delivered
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly Related PRs

Suggested Reviewers

  • alome007
  • Daniel-ADFA

Poem

🐰 Hopping through clouds with credentials so bright,
We upload to R2, abandoning SSH's plight,
And telegram chirps when the APK takes flight,
No more SSH keys in the dawn's early light!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title directly matches the main objectives: sharing nightly release builds via Telegram channel, which aligns with the primary changes of adding Cloudflare R2 upload and Telegram notifications.
Description check ✅ Passed The description accurately describes the changeset: uploading to Cloudflare R2, announcing via Telegram, and removing SSH setup; all of which are present in the code changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ADFA-3269-Share-nightly-release-to-private-Telegram
📝 Coding Plan
  • Generate coding plan for human review comments

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can enable review details to help with troubleshooting, context usage and more.

Enable the reviews.review_details setting to include review details such as the model used, the time taken for each step and more in the review comments.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
.github/workflows/release.yml (1)

588-594: Consider storing CLOUDFLARE_KEY_ID as a secret rather than a variable.

While the Key ID is less sensitive than the Secret Access Key, it's still part of the credential pair. Storing it as a secret instead of a var would provide additional protection (masked in logs, not visible in repository settings to users with lower permissions).

       env:
         CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}
-        CLOUDFLARE_KEY_ID: ${{ vars.CLOUDFLARE_KEY_ID }}
+        CLOUDFLARE_KEY_ID: ${{ secrets.CLOUDFLARE_KEY_ID }}
         CLOUDFLARE_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_SECRET_ACCESS_KEY }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release.yml around lines 588 - 594, The workflow step
"Upload APK to Cloudflare R2" exposes CLOUDFLARE_KEY_ID as a repo variable;
change the env binding to use a secret (secrets.CLOUDFLARE_KEY_ID) instead of
vars.CLOUDFLARE_KEY_ID and add that Key ID to the repository secrets, leaving
CLOUDFLARE_SECRET_ACCESS_KEY as secrets.CLOUDFLARE_SECRET_ACCESS_KEY; ensure the
step still passes steps.find_apk.outputs.APK_PATH and matrix.variant into
scripts/cloudflare-r2-upload.py unchanged.
scripts/cloudflare-r2-upload.py (1)

73-79: Consider adding error handling around the upload operation.

The s3.upload_file() call can raise various boto3/botocore exceptions (e.g., ClientError, NoCredentialsError, network errors). Currently, failures will produce raw tracebacks. Catching and logging a cleaner error message would improve debuggability in CI logs.

Proposed enhancement
+from botocore.exceptions import ClientError
+
 print(f"Uploading {file_name} ({file_size / (1024*1024):.1f} MB) to R2...", flush=True)
-s3.upload_file(file_path, BUCKET_NAME, file_name, **upload_kwargs)
-print("Upload complete.", flush=True)
+try:
+    s3.upload_file(file_path, BUCKET_NAME, file_name, **upload_kwargs)
+    print("Upload complete.", flush=True)
+except ClientError as e:
+    print(f"ERROR: Upload failed: {e}", file=sys.stderr)
+    sys.exit(1)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/cloudflare-r2-upload.py` around lines 73 - 79, Wrap the
s3.upload_file call in a try/except block to catch boto3/botocore exceptions
(e.g., botocore.exceptions.ClientError, NoCredentialsError,
EndpointConnectionError, and a generic Exception fallback); reference the
existing upload_kwargs, progress_callback, s3.upload_file, BUCKET_NAME,
file_path and file_name to locate the call, log/print a clear error message
including the exception details, and exit with a non-zero status (or re-raise)
so CI sees the failure instead of a raw traceback.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/release.yml:
- Around line 711-713: The Telegram POST currently silences failures (curl -s)
so the workflow continues on HTTP errors; update the step that calls curl (the
command using TELEGRAM_TOKEN, TELEGRAM_EARLY_ACCESS_CHAT_ID, and MESSAGE) to
detect and surface non-2xx responses by either using curl's --fail/-f and -S
flags or capturing the HTTP status and response body and then failing the job
when the status is not 200/201; ensure errors are logged (include response body
or status) and the step exits non-zero so the workflow does not continue
silently on rate limits, invalid tokens, or network issues.

In `@scripts/cloudflare-r2-upload.py`:
- Around line 41-51: Check that the provided file_path exists before calling
os.path.getsize to avoid FileNotFoundError; specifically, after assigning
file_path from sys.argv and before file_size = os.path.getsize(file_path), add a
guard using os.path.exists(file_path) (or os.path.isfile) and if it does not
exist print a clear error to stderr mentioning the missing file_path and exit
with non-zero status so the script fails cleanly; keep the subsequent logic that
computes base_name, name_root, ext, and file_name unchanged.

---

Nitpick comments:
In @.github/workflows/release.yml:
- Around line 588-594: The workflow step "Upload APK to Cloudflare R2" exposes
CLOUDFLARE_KEY_ID as a repo variable; change the env binding to use a secret
(secrets.CLOUDFLARE_KEY_ID) instead of vars.CLOUDFLARE_KEY_ID and add that Key
ID to the repository secrets, leaving CLOUDFLARE_SECRET_ACCESS_KEY as
secrets.CLOUDFLARE_SECRET_ACCESS_KEY; ensure the step still passes
steps.find_apk.outputs.APK_PATH and matrix.variant into
scripts/cloudflare-r2-upload.py unchanged.

In `@scripts/cloudflare-r2-upload.py`:
- Around line 73-79: Wrap the s3.upload_file call in a try/except block to catch
boto3/botocore exceptions (e.g., botocore.exceptions.ClientError,
NoCredentialsError, EndpointConnectionError, and a generic Exception fallback);
reference the existing upload_kwargs, progress_callback, s3.upload_file,
BUCKET_NAME, file_path and file_name to locate the call, log/print a clear error
message including the exception details, and exit with a non-zero status (or
re-raise) so CI sees the failure instead of a raw traceback.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 01f4a27f-5053-4881-8818-44fba31093e4

📥 Commits

Reviewing files that changed from the base of the PR and between 2154fa4 and 0c24fc1.

📒 Files selected for processing (2)
  • .github/workflows/release.yml
  • scripts/cloudflare-r2-upload.py

@hal-eisen-adfa hal-eisen-adfa merged commit 863494d into stage Mar 13, 2026
1 of 2 checks passed
@hal-eisen-adfa hal-eisen-adfa deleted the ADFA-3269-Share-nightly-release-to-private-Telegram branch March 13, 2026 18:40
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.

3 participants