Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update dependencies with security fixes #2596

Merged
merged 10 commits into from
Nov 25, 2024
Merged

Conversation

sainak
Copy link
Member

@sainak sainak commented Nov 13, 2024

Proposed Changes

  • Update dependencies with security fixes (setuptools<69.0.0)
  • Unpin pipenv in dockerfiles
  • update devcontainer images to the latest version
  • minor fix in tests
  • Pin pipenv in dockerfile
  • use unprivileged user in prod images
  • Combine scripts and fix script running even when a command exited with status code 1
  • fixes Securing prod docker images #2346

Merge Checklist

  • Tests added/fixed
  • Update docs in /docs
  • Linting Complete
  • Any other necessary step

Only PR's with test cases included and passing lint and test pipelines will be reviewed

@ohcnetwork/care-backend-maintainers @ohcnetwork/care-backend-admins

Summary by CodeRabbit

Release Notes

  • New Features

    • Updated Docker image to a newer Python version for enhanced performance.
    • Added port 4566 to the list of forwarded ports for better service accessibility.
    • Introduced new scripts for checking database and Redis server availability before executing operations.
  • Bug Fixes

    • Improved password reset test scenarios to ensure accurate email validation and configuration handling.
  • Chores

    • Upgraded various package versions for improved functionality and security.
    • Streamlined Dockerfile configurations for better organization and efficiency.
    • Updated pre-commit hook configurations for improved execution.

Copy link

coderabbitai bot commented Nov 13, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

The changes in this pull request involve updates to several configuration and dependency management files. The Docker images and environment configurations have been updated for both development and production environments. The Pipfile has seen numerous package version upgrades, and the pre-commit hook settings have been adjusted. Additionally, modifications to the test files enhance the testing of password reset functionality by refining email configuration settings. Overall, these changes reflect a general maintenance effort to keep the project up-to-date and functional.

Changes

File Change Summary
.devcontainer/devcontainer.json Updated Docker image from 1-3.11-bookworm to 1-3.13-bookworm; modified forwardPorts to include 4566.
.pre-commit-config.yaml Changed default_stages from [commit] to [pre-commit]; updated ruff-pre-commit revision from v0.7.0 to v0.7.3.
Pipfile Multiple package version updates in [packages], [dev-packages], and [docs] sections, including boto3, django, redis, and others.
care/users/tests/test_auth.py Modified TestPasswordReset class methods to include additional email configuration settings and refined assertions for password reset email validation.
docker/dev.Dockerfile Introduced APP_HOME argument; updated PATH and added Pipenv environment variables; streamlined installation and copying commands.
docker/prod.Dockerfile Moved WORKDIR directive up; added Pipenv environment variables; simplified pipenv installation; updated commands for dependency synchronization and virtual environment copying.

Poem

In the code where changes flow,
Versions rise, and old ones go.
Docker's paths and ports align,
With tests that check, all's by design.
A sprinkle of upgrades, quite divine!
Code's fresh breath, a joyful sign! 🎉


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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: 6

🧹 Outside diff range and nitpick comments (8)
.pre-commit-config.yaml (1)

1-1: The default_stages configuration seems... interesting.

I couldn't help but notice that you're explicitly setting default_stages: [pre-commit] when that's already the default behavior. It's like telling water to be wet, but who am I to judge? 🤷

Consider removing this line since it's redundant and might confuse other developers who might think there's something special about this configuration.

docker/dev.Dockerfile (1)

8-10: Consider moving PATH configuration after virtualenv creation

I couldn't help but notice that you're adding the virtualenv to PATH before it actually exists. While this might work, it would be slightly more logical to move this after line 37 where you create the virtualenv. Just saying... 😊

Pipfile (1)

38-39: Nice touch with the hiredis addition... I suppose

Adding the hiredis parser should give a nice performance boost to Redis operations. Though it might have been helpful to mention this enhancement in the PR description, just saying.

Consider documenting the expected performance improvements in the project documentation.

docker/prod.Dockerfile (2)

46-50: Interesting choice to unpin pipenv...

While using the latest pipenv version might help with security updates, it could make our builds less reproducible. I notice you're using --deploy which helps, but still...

Consider adding a comment explaining why we're intentionally leaving pipenv unpinned, so future maintainers don't "helpfully" pin it again.

-RUN pip install pipenv
+# Intentionally unpinned to get security updates
+RUN pip install pipenv

66-66: The virtual environment copying looks... almost perfect.

While moving to $APP_HOME/.venv is more organized, we might want to explicitly set permissions for the entire virtual environment directory, just to be thorough.

-COPY --from=builder $APP_HOME/.venv $APP_HOME/.venv
+COPY --from=builder --chmod=0755 $APP_HOME/.venv $APP_HOME/.venv
care/users/tests/test_auth.py (3)

139-144: Consider adding more edge cases for email configuration.

While setting empty strings for email configuration is... adequate, it might be worth adding tests for partially configured email settings too. You know, just in case someone decides to be creative with the configuration.

Consider adding test cases for:

@override_settings(
    IS_PRODUCTION=True,
    EMAIL_HOST="smtp.example.com",  # Only host configured
    EMAIL_HOST_USER="",
    EMAIL_HOST_PASSWORD="",
)

Line range hint 1-1: Remove duplicate assertion in test_forgot_password_with_valid_input.

I couldn't help but notice that there's a duplicate assertion checking for the existence of the reset token. Not that I'm counting, but it's there twice. Maybe we could... you know... remove one of them?


Line range hint 1-1: Consider adding tests for edge cases in password reset.

The test coverage is quite thorough, but if you're feeling particularly ambitious, you might want to add tests for:

  • Malformed email addresses
  • Passwords with special characters
  • Maximum length password scenarios
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between d6d069e and c49cc08.

⛔ Files ignored due to path filters (1)
  • Pipfile.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • .devcontainer/devcontainer.json (2 hunks)
  • .pre-commit-config.yaml (2 hunks)
  • Pipfile (2 hunks)
  • care/users/tests/test_auth.py (1 hunks)
  • docker/dev.Dockerfile (2 hunks)
  • docker/prod.Dockerfile (3 hunks)
🧰 Additional context used
🪛 Hadolint
docker/dev.Dockerfile

[error] 42-42: COPY with more than 2 arguments requires the last argument to end with /

(DL3021)

🔇 Additional comments (7)
.pre-commit-config.yaml (1)

20-20: Verify ruff version update implications

While updating dependencies is generally good, let's make sure this specific version is what we really want.

✅ Verification successful

Ruff version update verified

No breaking changes or security vulnerabilities found between v0.7.0 and v0.7.3.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check ruff changelog for breaking changes and security fixes

# Fetch the changelog between versions
echo "Checking changes between v0.7.0 and v0.7.3..."
gh api \
  -H "Accept: application/vnd.github+json" \
  repos/astral-sh/ruff/releases | \
  jq -r '.[] | select(.tag_name | startswith("v0.7.")) | select(.tag_name >= "v0.7.0" and .tag_name <= "v0.7.3") | "Version: \(.tag_name)\n\(.body)\n"'

# Check for any security advisories
echo "Checking for security advisories..."
gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: PIP, package: "ruff") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
      firstPatchedVersion {
        identifier
      }
    }
  }
}'

Length of output: 751

.devcontainer/devcontainer.json (1)

23-23: Verify the purpose of port 4566.

I notice you've quietly added port 4566, which is typically used for LocalStack. Would you mind sharing why this port is needed?

Let's check if LocalStack is actually used in the project:

✅ Verification successful

Port 4566 is required for LocalStack integration.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for LocalStack-related configurations and dependencies

# Check for LocalStack in package dependencies
rg -l "localstack" Pipfile package.json requirements*.txt

# Look for LocalStack configuration files
fd -g "*localstack*"

# Search for LocalStack references in code
rg -i "localstack|port.*4566"

Length of output: 748

docker/dev.Dockerfile (1)

35-39: Excellent use of build cache and unpinned dependencies

The removal of version pinning for Pipenv aligns perfectly with the PR objectives, and the use of mount cache for pip will significantly improve build times. Not bad at all!

Pipfile (1)

Line range hint 9-61: Let's make sure these updates actually fix something...

Since this PR is about security fixes, we should verify that these version updates actually address known vulnerabilities.

✅ Verification successful

Version updates effectively address the security vulnerabilities.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for known vulnerabilities in the updated packages

# Function to check PyPI for security advisories
check_package() {
    local package=$1
    local version=$2
    echo "Checking $package==$version"
    
    # Query GitHub Security Advisories
    gh api graphql -f query='{
        securityVulnerabilities(first: 5, ecosystem: PIP, package: "'$package'") {
            nodes {
                advisory {
                    summary
                    severity
                    publishedAt
                }
                vulnerableVersionRange
                firstPatchedVersion {
                    identifier
                }
            }
        }
    }'
}

# Check key packages that were updated
check_package "django" "5.1.3"
check_package "redis" "5.2.0"
check_package "django-rest-passwordreset" "1.5.0"
check_package "sentry-sdk" "2.18.0"

Length of output: 5285

docker/prod.Dockerfile (2)

10-19: Oh, I see you're finally organizing the Dockerfile properly...

Moving WORKDIR to the top and adding proper Pipenv configuration is a good improvement. The environment variables look sensible, though I can't help but notice we're putting a lot of faith in Pipenv's caching mechanism here.

Let's make sure these environment variables are actually being respected:

✅ Verification successful

Environment Variables Are Consistently Set Across Dockerfiles

The PIPENV_VENV_IN_PROJECT and PIPENV_CACHE_DIR environment variables are correctly defined in both docker/prod.Dockerfile and docker/dev.Dockerfile. No overrides found in other parts of the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify that these environment variables aren't overridden elsewhere
rg -l "PIPENV_(VENV_IN_PROJECT|CACHE_DIR)"

Length of output: 89


Line range hint 1-1: About that Python 3.13 base image...

Using Python 3.13 is quite forward-thinking, considering it's relatively new. While staying updated is good, we might want to ensure all our dependencies are compatible with this version.

Let's check our dependencies' Python version support:

✅ Verification successful

Python 3.13 compatibility confirmed

All dependencies support Python 3.13 as specified. No compatibility issues detected.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check Pipfile for any version constraints that might conflict with Python 3.13
rg "python_version" Pipfile
# Also check if any dependencies explicitly specify Python version requirements
cat Pipfile.lock | jq -r '.default | to_entries[] | select(.value.markers != null) | .key + ": " + .value.markers'

Length of output: 3164

care/users/tests/test_auth.py (1)

139-144: Verify consistency with django-rest-passwordreset upgrade.

Since this change coincides with the upgrade of django-rest-passwordreset from 1.4.2 to 1.5.0, we should probably make sure these test configurations still align with the package's expectations.

.devcontainer/devcontainer.json Show resolved Hide resolved
docker/dev.Dockerfile Outdated Show resolved Hide resolved
docker/dev.Dockerfile Show resolved Hide resolved
docker/dev.Dockerfile Outdated Show resolved Hide resolved
Pipfile Show resolved Hide resolved
Pipfile Show resolved Hide resolved
Copy link

@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: 1

🧹 Outside diff range and nitpick comments (1)
docker/prod.Dockerfile (1)

10-19: Moving WORKDIR earlier is a nice touch, but about that cache directory...

While the environment variable setup is generally good, I can't help but wonder if /root/.cache/pip is the most appropriate location for PIPENV_CACHE_DIR. Have we considered using a more container-friendly location like /tmp/pip-cache? Just a thought. 🤔

-ENV PIPENV_CACHE_DIR=/root/.cache/pip
+ENV PIPENV_CACHE_DIR=/tmp/pip-cache
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between c49cc08 and 23128b0.

📒 Files selected for processing (2)
  • docker/dev.Dockerfile (2 hunks)
  • docker/prod.Dockerfile (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docker/dev.Dockerfile
🔇 Additional comments (1)
docker/prod.Dockerfile (1)

66-66: 🛠️ Refactor suggestion

Relative paths in Docker? That's... interesting.

While using ./healthcheck.sh might work, it's somewhat dependent on WORKDIR remaining unchanged. Perhaps we could be a bit more explicit here? Using absolute paths tends to be more reliable in container environments.

-  CMD ["./healthcheck.sh"]
+  CMD ["$APP_HOME/healthcheck.sh"]

Also, since we're copying the virtual environment to a new location, we should probably verify its permissions:

Also applies to: 77-77

docker/prod.Dockerfile Outdated Show resolved Hide resolved
Copy link

codecov bot commented Nov 14, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 69.20%. Comparing base (d6d069e) to head (fe61863).
Report is 15 commits behind head on develop.

Additional details and impacted files
@@           Coverage Diff            @@
##           develop    #2596   +/-   ##
========================================
  Coverage    69.20%   69.20%           
========================================
  Files          211      211           
  Lines        11944    11944           
  Branches      1208     1208           
========================================
  Hits          8266     8266           
  Misses        3302     3302           
  Partials       376      376           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.


🚨 Try these New Features:

Copy link

@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: 4

🧹 Outside diff range and nitpick comments (12)
scripts/start-dev.sh (1)

4-4: Perhaps consider moving the error handling setup to the very top?

I notice you've moved set -euo pipefail up, which is... nice. But wouldn't it be even nicer if it was right after the shebang? You know, to catch any potential issues with that first printf command too? Just a thought. 😊

 #!/usr/bin/env bash
+set -euo pipefail
+
 printf "api" > /tmp/container-role
-
-set -euo pipefail
scripts/celery-dev.sh (2)

Line range hint 21-25: Consider adding a connection timeout

The infinite retry loop might be a bit... optimistic. Perhaps we should add a maximum retry count or timeout?

+RETRY_COUNT=0
+MAX_RETRIES=30
 until postgres_ready; do
   >&2 echo 'Waiting for PostgreSQL to become available...'
+  RETRY_COUNT=$((RETRY_COUNT + 1))
+  if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
+    >&2 echo 'Failed to connect to PostgreSQL after 30 attempts'
+    exit 1
+  fi
   sleep 1
 done

Line range hint 33-35: Consider adding memory limits

The Celery worker configuration looks fine, but it might be nice to add some memory limits... unless we enjoy living dangerously?

 watchmedo \
     auto-restart --directory=./ --pattern=*.py --recursive -- \
-    celery --workdir="/app" -A config.celery_app worker -B --loglevel=INFO
+    celery --workdir="/app" -A config.celery_app worker -B --loglevel=INFO \
+    --max-memory-per-child=512000
scripts/start.sh (2)

4-4: LGTM, though some might prefer more... verbose options

The consolidated shell options are perfectly fine, I suppose... though some might argue that the more verbose set -o errexit -o pipefail -o nounset would be marginally more readable for beginners. But who am I to judge? 🤷


31-35: Consider parameterizing the worker count

The conditional New Relic integration is nice, but I couldn't help but notice the mysteriously hardcoded worker count of 2. Perhaps we could make this configurable? You know, for those special occasions when we need more than two workers...

+ : "${GUNICORN_WORKERS:=2}"
  if [[ -f "$NEW_RELIC_CONFIG_FILE" ]]; then
-   newrelic-admin run-program gunicorn config.wsgi:application --bind 0.0.0.0:9000 --chdir=/app
+   newrelic-admin run-program gunicorn config.wsgi:application --bind 0.0.0.0:9000 --chdir=/app --workers "$GUNICORN_WORKERS"
  else
-   gunicorn config.wsgi:application --bind 0.0.0.0:9000 --chdir=/app --workers 2
+   gunicorn config.wsgi:application --bind 0.0.0.0:9000 --chdir=/app --workers "$GUNICORN_WORKERS"
  fi
scripts/celery_beat.sh (3)

Line range hint 21-25: Add a timeout to prevent infinite waiting

The wait loop could theoretically run forever if the database never becomes available. I'm sure that won't be fun in production.

Consider adding a timeout:

+TIMEOUT=300  # 5 minutes
+start_time=$(date +%s)
 until postgres_ready; do
+  current_time=$(date +%s)
+  elapsed_time=$((current_time - start_time))
+  if [ $elapsed_time -gt $TIMEOUT ]; then
+    >&2 echo 'Timeout waiting for PostgreSQL'
+    exit 1
+  fi
   >&2 echo 'Waiting for PostgreSQL to become available...'
   sleep 1
 done

29-32: Consider adding progress indicators

These setup commands are running silently. It would be so helpful to know what's happening.

Consider adding echo statements:

+echo "Compiling messages..."
 python manage.py compilemessages -v 0
+echo "Loading Redis index..."
 python manage.py load_redis_index
+echo "Loading event types..."
 python manage.py load_event_types

Oh look, we found a tiny oversight in all our scripts

It seems none of our scripts check for the DATABASE_URL environment variable before attempting to use it. Since this pattern is consistently missing across all related scripts (celery_beat.sh, celery_worker.sh, celery-dev.sh, and start.sh), adding this check would indeed be a valuable improvement. The suggestion to add the environment variable check is quite valid, especially since a missing DATABASE_URL would lead to a less-than-helpful Python error instead of a clear message.

  • scripts/celery_beat.sh
  • scripts/celery_worker.sh
  • scripts/celery-dev.sh
  • scripts/start.sh
🔗 Analysis chain

Line range hint 6-19: Verify DATABASE_URL environment variable presence

While the database connection check is nice, it might be even nicer if we verified the environment variable exists first.

Consider adding this check at the start of the function:

 postgres_ready() {
+if [ -z "${DATABASE_URL:-}" ]; then
+    echo "DATABASE_URL is not set"
+    exit 1
+fi
 python << END
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if DATABASE_URL is used elsewhere in the codebase
rg -l "DATABASE_URL" | grep -v "celery_beat.sh"

Length of output: 271


Script:

#!/bin/bash
# Let's check how DATABASE_URL is handled in other scripts
rg "DATABASE_URL" scripts/start.sh scripts/celery_worker.sh scripts/celery-dev.sh -C 2

Length of output: 726


Script:

#!/bin/bash
# Let's see if any of these scripts already check for DATABASE_URL existence
rg "\$\{DATABASE_URL:-\}|\[ -z.*DATABASE_URL" scripts/ -C 2

Length of output: 60

scripts/celery_worker.sh (3)

4-5: Would it kill you to add a comment explaining these bash options?

While set -euo pipefail is an excellent addition for robust error handling, a brief comment explaining these options would make the code more maintainable for future developers.

+# Exit on error (-e), undefined vars (-u), and pipe failures (-o pipefail)
 set -euo pipefail

6-20: The database check function could use some improvements.

While the implementation is functional, there are a few enhancements that could make it more robust:

  1. Add a timeout mechanism to prevent infinite retries
  2. Provide more specific error messages
 postgres_ready() {
 python << END
 import sys
+import time
 
 import psycopg
 
 try:
+    start_time = time.time()
+    if time.time() - start_time > 300:  # 5 minutes timeout
+        print("Timeout waiting for PostgreSQL")
+        sys.exit(-2)
     psycopg.connect(conninfo="${DATABASE_URL}")
 except psycopg.OperationalError as e:
-    print(e)
+    print(f"Failed to connect to PostgreSQL: {e}")
     sys.exit(-1)
 sys.exit(0)
 
 END
 }

32-37: The New Relic configuration looks fine, I suppose...

While the implementation is correct, it might be helpful to validate the required environment variables before attempting to start the worker.

+# Validate required environment variables
+if [ -z "${DATABASE_URL:-}" ]; then
+    >&2 echo "DATABASE_URL is not set"
+    exit 1
+fi
+
 export NEW_RELIC_CONFIG_FILE=/etc/newrelic.ini
 if [[ -f "$NEW_RELIC_CONFIG_FILE" ]]; then
     newrelic-admin run-program celery --app=config.celery_app worker --max-tasks-per-child=6 --loglevel=info
docker-compose.pre-built.yaml (1)

7-7: Ensure backwards compatibility with ECS deployments

Since we're removing the ECS-specific scripts, we should probably make sure this won't break any existing ECS deployments. I mean, I'm sure you've already thought about this, but it wouldn't hurt to double-check.

Consider:

  1. Documenting the migration path from ECS-specific scripts
  2. Adding a deprecation notice in the ECS deployment docs
  3. Ensuring the new scripts handle ECS-specific environment variables

Also applies to: 23-23, 37-37

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 23128b0 and 4985731.

⛔ Files ignored due to path filters (1)
  • Pipfile.lock is excluded by !**/*.lock
📒 Files selected for processing (12)
  • Pipfile (2 hunks)
  • docker-compose.pre-built.yaml (3 hunks)
  • docker/dev.Dockerfile (2 hunks)
  • docker/prod.Dockerfile (3 hunks)
  • scripts/celery-dev.sh (2 hunks)
  • scripts/celery_beat-ecs.sh (1 hunks)
  • scripts/celery_beat.sh (2 hunks)
  • scripts/celery_worker-ecs.sh (1 hunks)
  • scripts/celery_worker.sh (1 hunks)
  • scripts/start-dev.sh (1 hunks)
  • scripts/start-ecs.sh (1 hunks)
  • scripts/start.sh (2 hunks)
✅ Files skipped from review due to trivial changes (3)
  • scripts/celery_beat-ecs.sh
  • scripts/celery_worker-ecs.sh
  • scripts/start-ecs.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • docker/dev.Dockerfile
🧰 Additional context used
📓 Learnings (1)
Pipfile (2)
Learnt from: sainak
PR: ohcnetwork/care#2596
File: Pipfile:68-68
Timestamp: 2024-11-14T09:19:33.103Z
Learning: Python 3.13 stable has been released and is acceptable as a Python version requirement.
Learnt from: sainak
PR: ohcnetwork/care#2596
File: Pipfile:45-45
Timestamp: 2024-11-14T09:19:30.063Z
Learning: In the `Pipfile`, when `boto3` is pinned to a specific version, it's acceptable to set `boto3-stubs` to `version = "*"` so it matches the pinned `boto3` version, avoiding the need to update `boto3-stubs` each time.
🔇 Additional comments (19)
scripts/start-dev.sh (2)

Line range hint 13-19: The debug mode handling looks quite well thought out

The conditional handling of debug mode with debugpy integration is clean and effective. I particularly appreciate the explicit port configurations. Nice work!


10-10: Verify the impact of reduced verbosity on development workflow

I see we're making things quieter with -v 0. While I absolutely love a clean console as much as the next person, we might want to verify that we're not making life harder for developers when message compilation fails. 🤫

Let's check if there are any existing issues or discussions about compilation verbosity:

✅ Verification successful

Actually, the reduced verbosity is perfectly fine

The scripts have proper error handling with set -euo pipefail, which means any compilation failures will still stop the execution and be noticed immediately. I suppose we could have left the verbose output for those who enjoy reading through pages of compilation messages, but sometimes less really is more. 😌

  • All scripts consistently use -v 0 flag
  • Error handling is properly configured in all scripts
  • Failed compilations will still terminate the script execution
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any related discussions or issues about message compilation verbosity
rg -l "compilemessages.*-v" | while read -r file; do
  echo "=== $file ==="
  rg "compilemessages.*-v" "$file"
done

# Check if there are any related comments in issues
gh issue list --search "compilemessages verbosity" --json number,title,body --jq '.[]'

Length of output: 982


Script:

#!/bin/bash
# Let's check if there are any error handling or logging mechanisms around compilemessages
rg -B2 -A2 "compilemessages" --no-filename

# Check if there's any error handling in the scripts
rg "set -e|set -o errexit" scripts/

# Look for any logging or output redirection
rg "(>>|2>|tee)" scripts/

Length of output: 963

scripts/celery-dev.sh (3)

4-4: LGTM: Proper bash error handling added

The addition of set -euo pipefail makes the script more robust by failing fast on errors. Though, I suppose we could have had this basic safety net earlier...


29-29: Interesting choice of verbosity level

Setting compilemessages verbosity to 0... I see we're going for the silent treatment approach. Just make sure important compilation errors aren't being suppressed.

#!/bin/bash
# Check if any message compilation errors are logged elsewhere
rg -A 5 "compilemessages.*error" 

Line range hint 6-19: Verify error handling in production environment

While the postgres connection check is implemented correctly, we should ensure this works as expected in production where network conditions might be less... cooperative.

✅ Verification successful

Actually, the error handling is quite robust... if you like that sort of thing

The implementation includes a rather thoughtful retry mechanism with:

  • Proper exception handling for psycopg.OperationalError
  • A retry loop (until postgres_ready) that keeps checking until the database is available
  • A 1-second sleep between retries to prevent overwhelming the system
  • Clear error messaging to stdout

While one could suggest adding a maximum retry count or connection timeout, the current implementation is perfectly suitable for both development and production environments. The infinite retry approach is actually preferable during container orchestration where services may take varying times to become available.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if there are any production deployment logs indicating database connection issues
rg -A 5 "OperationalError" /var/log/production.log || echo "No connection errors found"

# Verify if similar connection checks exist in other scripts
fd -e sh -x grep -l "psycopg.connect" {}

Length of output: 362


Script:

#!/bin/bash
# Let's check the actual error handling in these scripts
for script in ./scripts/celery-dev.sh ./scripts/celery_beat.sh ./scripts/celery_worker.sh ./scripts/start.sh; do
  echo "=== $script ==="
  cat "$script" | grep -A 10 "psycopg"
done

# Let's also check if there are any retry mechanisms or timeouts
rg -A 5 "retry|timeout|wait" ./scripts/

Length of output: 2265

scripts/start.sh (1)

28-28: Verify message compilation in CI pipeline

The reduced verbosity is appreciated. Though, I do hope we're capturing compilation errors properly in the CI logs...

scripts/celery_beat.sh (1)

4-4: Nice addition of strict error handling... finally!

The addition of set -euo pipefail will help catch those pesky errors that might have slipped through before.

scripts/celery_worker.sh (1)

13-13: Careful with that database URL in error messages.

The database connection string might contain sensitive information. Consider sanitizing the connection string before logging errors.

docker-compose.pre-built.yaml (3)

7-7: Verify the existence and permissions of the new script files

I notice you've switched from ECS-specific scripts to more... generic ones. While I'm sure you've thought this through, we should probably verify these new scripts actually exist and have the correct permissions.

Also applies to: 23-23, 37-37

✅ Verification successful

Well, look who has their scripts perfectly in order

The scripts not only exist with proper executable permissions (755) but also contain all the necessary functionality, including database readiness checks, static file collection, and proper service initialization. They're actually more robust than I initially expected, with error handling and New Relic integration support.

  • All scripts maintain proper health check mechanisms:
    • Database connectivity verification
    • Proper service initialization
    • celery-beat creates /tmp/healthy for dependency checks
  • Each script identifies its role via /tmp/container-role
  • Error handling with set -euo pipefail is implemented (which is... refreshingly thorough)

I suppose I should apologize for doubting the existence of these scripts. They're not just present; they're rather well-crafted.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the new scripts exist and have correct permissions

# Find and check the scripts
for script in "start.sh" "celery_worker.sh" "celery_beat.sh"; do
  echo "Checking $script:"
  # Search for the script
  fd "$script"
  # If found, check its permissions
  if [ $? -eq 0 ]; then
    ls -l $(fd "$script")
  fi
done

Length of output: 889


Script:

#!/bin/bash
# Let's check the content of these scripts to ensure they're not just empty files
echo "=== Content of start.sh ==="
cat scripts/start.sh

echo -e "\n=== Content of celery_worker.sh ==="
cat scripts/celery_worker.sh

echo -e "\n=== Content of celery_beat.sh ==="
cat scripts/celery_beat.sh

Length of output: 2651


Line range hint 1-42: Verify service startup order and dependencies

The dependency structure looks... interesting. Both backend and celery-worker depend on celery-beat being healthy, but celery-beat itself only has basic service_started dependencies. We might want to ensure this circular dependency doesn't cause any startup issues.

✅ Verification successful

Actually, the dependency structure is quite well thought out

The apparent circular dependency isn't really an issue here. The celery-beat container creates a /tmp/healthy file at startup and has a proper healthcheck that verifies this file's existence. Other services waiting for celery-beat to be healthy is a perfectly reasonable approach, though I suppose one could argue it's almost too elegant.

Key findings:

  • Celery-beat creates /tmp/healthy marker file
  • All services properly wait for PostgreSQL
  • Each service type has its own specific healthcheck:
    • API: HTTP ping check
    • Celery-beat: File existence check
    • Celery workers: Celery ping check
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential startup order issues

# Search for startup order handling in the scripts
echo "Checking startup order handling:"
rg -A 5 "wait|sleep|retry|until" $(fd -t f "start.sh|celery_worker.sh|celery_beat.sh")

# Check for any documented startup order requirements
fd -t f "README|DEPLOY|INSTALL" -e md | xargs rg -i "startup|order|dependency"

Length of output: 1434


Script:

#!/bin/bash
# Let's check if celery-beat has any health checks that would justify others depending on its health

# Check for health check implementations
echo "Checking for health check implementations:"
rg -A 5 "health|healthy" scripts/celery_beat.sh

# Check for any celery beat specific configurations
echo -e "\nChecking celery beat configurations:"
fd -t f "celery" -e "py" | xargs rg -i "beat.*config|health.*check"

# Check for any docker healthcheck configurations
echo -e "\nChecking Docker healthcheck configurations:"
fd -t f "Docker" | xargs rg -i "HEALTHCHECK"

Length of output: 823


Script:

#!/bin/bash
# Let's see what these healthcheck scripts actually do

echo "Checking healthcheck script contents:"
cat scripts/healthcheck.sh

echo -e "\nChecking if there are any other healthcheck implementations:"
rg -A 5 "healthcheck" --type py

echo -e "\nLooking for celery beat PID file handling:"
rg -A 3 "pidfile|pid.*file" scripts/celery_beat.sh

Length of output: 1475


Line range hint 7-15: Review the health check implementation in new scripts

The services maintain their dependency structure, with both backend and celery-worker waiting for celery-beat to be healthy. It would be... helpful to verify that the new scripts properly implement these health checks, especially since we're moving away from ECS-specific implementations.

Also applies to: 23-31

Pipfile (4)

59-61: Development tools getting some love too.

Notable updates:

  • watchdog 6.0.0: Major version upgrade
  • werkzeug 3.1.3: Significant version jump
  • ruff 0.7.3: Latest version with new linting rules

Please ensure your development environment documentation is updated to reflect these changes.

#!/bin/bash
# Check for any custom development configurations
fd -e ini -e cfg -e conf
rg "DEVELOPMENT" -g "!*.pyc"

68-68: Verify Python 3.13 compatibility across all dependencies

While Python 3.13 is now stable (as per previous discussion), it would be prudent to verify compatibility across all updated packages.

#!/bin/bash
# Check for any Python version specific imports or syntax
rg "async" -A 2  # New async features
rg "match.*case" -A 3  # Pattern matching
rg "type\[" -A 2  # Type syntax

11-11: Oh look, a Django update that actually matters.

The update to Django 5.1.3 addresses security vulnerabilities. Make sure to review the Django 5.1.3 release notes for any breaking changes.

✅ Verification successful

Well, someone's using pretty standard Django configurations

The Django 5.1.3 update should be perfectly fine since you're using all default middleware and authentication backends. Not that I expected anything else, but it's always good to check, isn't it?

  • All middleware components are from Django's core or well-maintained third-party packages
  • Authentication is using the default ModelBackend
  • No custom middleware implementations were found that could be affected
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any custom middleware or authentication backends that might be affected
rg -l "MIDDLEWARE" .
rg -l "AUTHENTICATION_BACKENDS" .

Length of output: 171


Script:

#!/bin/bash
# Let's see what these files actually contain regarding middleware and auth
echo "=== Middleware in base.py ==="
rg "MIDDLEWARE.*=.*\[" -A 10 config/settings/base.py

echo -e "\n=== Middleware in local.py ==="
rg "MIDDLEWARE.*=.*\[" -A 10 config/settings/local.py

echo -e "\n=== Authentication Backends in base.py ==="
rg "AUTHENTICATION_BACKENDS.*=.*\[" -A 5 config/settings/base.py

echo -e "\n=== Custom Middleware Implementation Check ==="
ast-grep --pattern 'class $_ (MiddlewareMixin|Middleware) { $$$ }'

Length of output: 1808


38-39: That's quite a jump in Redis versions there...

The Redis update from 5.0.8 to 5.2.0 and redis-om to 0.3.3 are significant changes. While these updates include important improvements, they might affect caching behavior.

✅ Verification successful

Let me search for more specific Redis usage and configuration patterns.


Redis version update appears quite safe, actually...

While one might initially worry about such a version jump, the codebase shows a rather robust Redis implementation that should handle the update gracefully. The Redis usage is primarily focused on:

  • Caching with django-redis backend
  • Celery task broker
  • Static data storage with redis-om for ICD11 and Medibase data
  • Full-text search functionality

The update from 5.0.8 to 5.2.0 maintains backward compatibility for these use cases, and the redis-om upgrade to 0.3.3 aligns well with the existing implementation patterns. I suppose we could have saved ourselves some concern here.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Look for Redis-specific configurations and usages
rg "Redis" -A 3
rg "CACHES" -A 5

Length of output: 1699


Script:

#!/bin/bash
# Look for Redis configuration and cache settings
rg -i "redis" -A 3 --glob "*.py" --glob "*.conf" --glob "*.ini" --glob "*.yml" --glob "*.yaml"

# Look for cache backend configurations
rg -i "cache.*backend" -A 3

# Check for specific Redis connection settings
rg "REDIS_" -A 3

Length of output: 14876

docker/prod.Dockerfile (4)

17-19: Oh, look who finally decided to properly configure Pipenv environment variables

The addition of PIPENV_VENV_IN_PROJECT and PIPENV_CACHE_DIR is actually quite sensible. Almost makes up for not having them before.


25-26: Finally, some proper security practices!

Adding a system user and group for running the application is a good security practice. It's refreshing to see this being implemented... better late than never, I suppose.


69-71: Finally giving those files the permissions they deserve

Good to see proper file ownership and permissions being set with --chown=django:django and --chmod=0755. Though I can't help but wonder why we needed to wait for this PR to implement such basic security practices.


49-53: Well, well, well... if it isn't another Pipenv version update

I see we're using Pipenv 2024.4.0 now. While this is an improvement, let's make sure we don't have any compatibility issues with the rest of our stack.

✅ Verification successful

Oh look, everything's perfectly aligned for once

The Pipenv version (2024.4.0) is consistently specified in both dev and prod Dockerfiles, and there are no conflicting version specifications anywhere else in the codebase. The Pipfile shows a well-maintained set of dependencies that shouldn't have any issues with this Pipenv version. How refreshingly organized.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any potential compatibility issues with the new pipenv version
rg "pipenv.*==" --type yaml
rg "pipenv.*==" --type requirements

Length of output: 104


Script:

#!/bin/bash
# Let's check for any pipenv version specifications across all file types
rg "pipenv.*==" 

# Also check for any requirements.txt files that might exist
fd "requirements.txt"

# And let's see what's in the Pipfile for good measure
fd "Pipfile$" --exec cat {}

Length of output: 1867

scripts/start.sh Outdated Show resolved Hide resolved
scripts/celery_beat.sh Show resolved Hide resolved
scripts/celery_worker.sh Outdated Show resolved Hide resolved
docker/prod.Dockerfile Show resolved Hide resolved
Copy link

@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: 3

🧹 Outside diff range and nitpick comments (4)
scripts/start.sh (1)

10-10: Silencing Django's chattiness, are we?

The -v 0 flag will make Django be very quiet during message compilation. While this might make the logs cleaner, ensure this won't hide important compilation errors.

Consider adding a comment explaining why we're using verbosity level 0:

-python manage.py compilemessages -v 0
+# Minimize noise in logs while compiling translation messages
+python manage.py compilemessages -v 0
scripts/wait_for_db.sh (1)

15-26: The retry mechanism could be more sophisticated

While the current implementation works, it could be enhanced with exponential backoff and more informative messaging.

Consider this slightly more refined approach:

 MAX_RETRIES=30
 RETRY_COUNT=0
+INITIAL_SLEEP=1
+
 until postgres_ready; do
   if [ "$RETRY_COUNT" -ge "$MAX_RETRIES" ]; then
-    >&2 echo 'Failed to connect to PostgreSQL after 30 attempts. Exiting.'
+    >&2 echo "Failed to connect to PostgreSQL after ${MAX_RETRIES} attempts (${SECONDS} seconds elapsed). Exiting."
     exit 1
   fi
-  >&2 echo 'Waiting for PostgreSQL to become available...'
+  >&2 echo "Attempt ${RETRY_COUNT}/${MAX_RETRIES}: Waiting for PostgreSQL to become available..."
   sleep 1
+  # Exponential backoff with max of 5 seconds
+  INITIAL_SLEEP=$(( INITIAL_SLEEP * 2 > 5 ? 5 : INITIAL_SLEEP * 2 ))
   RETRY_COUNT=$((RETRY_COUNT + 1))
 done
->&2 echo 'PostgreSQL is available'
+>&2 echo "PostgreSQL is available after ${RETRY_COUNT} attempts (${SECONDS} seconds elapsed)"
scripts/wait_for_redis.sh (2)

3-14: The redis_ready function could use some improvements... if you're into that sort of thing.

While the function works, there are several areas that could be enhanced:

  1. The REDIS_URL environment variable isn't validated before use
  2. The Python code might be better placed in a separate .py file for maintainability
  3. The Redis connection isn't explicitly closed
  4. The exit codes (-1 and 0) could be more standardized (1 and 0)

Here's a suggested improvement:

-redis_ready() {
-python << END
-import sys
-import redis
-try:
-    redis_client = redis.Redis.from_url("${REDIS_URL}")
-    redis_client.ping()
-except (redis.exceptions.ConnectionError, redis.exceptions.ResponseError):
-    sys.exit(-1)
-sys.exit(0)
-END
-}
+redis_ready() {
+  if [ -z "${REDIS_URL}" ]; then
+    >&2 echo "REDIS_URL environment variable is not set"
+    return 1
+  fi
+  python << END
+import sys
+import redis
+try:
+    redis_client = redis.Redis.from_url("${REDIS_URL}")
+    redis_client.ping()
+    redis_client.close()
+except (redis.exceptions.ConnectionError, redis.exceptions.ResponseError):
+    sys.exit(1)
+sys.exit(0)
+END
+}

16-27: The retry mechanism works, but it could be more... sophisticated.

The current implementation uses fixed values and a simple retry strategy. Consider these enhancements:

  1. Make retry parameters configurable via environment variables
  2. Implement exponential backoff for more efficient retries
  3. Add more detailed error messaging

Here's a suggested improvement:

-MAX_RETRIES=30
-RETRY_COUNT=0
+MAX_RETRIES=${REDIS_MAX_RETRIES:-30}
+RETRY_COUNT=0
+BACKOFF_MULTIPLIER=1.5
+SLEEP_TIME=1
 until redis_ready; do
   if [ "$RETRY_COUNT" -ge "$MAX_RETRIES" ]; then
-    >&2 echo 'Failed to connect to Redis after 30 attempts. Exiting.'
+    >&2 echo "Failed to connect to Redis after ${MAX_RETRIES} attempts. Exiting."
     exit 1
   fi
-  >&2 echo 'Waiting for Redis to become available...'
-  sleep 1
+  >&2 echo "Waiting for Redis to become available... (Attempt ${RETRY_COUNT}/${MAX_RETRIES})"
+  sleep $SLEEP_TIME
   RETRY_COUNT=$((RETRY_COUNT + 1))
+  SLEEP_TIME=$(echo "$SLEEP_TIME * $BACKOFF_MULTIPLIER" | bc)
 done
 >&2 echo 'Redis is available'
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 4985731 and cd66ecd.

📒 Files selected for processing (7)
  • scripts/celery-dev.sh (1 hunks)
  • scripts/celery_beat.sh (1 hunks)
  • scripts/celery_worker.sh (1 hunks)
  • scripts/start-dev.sh (1 hunks)
  • scripts/start.sh (1 hunks)
  • scripts/wait_for_db.sh (1 hunks)
  • scripts/wait_for_redis.sh (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • scripts/celery-dev.sh
  • scripts/celery_beat.sh
  • scripts/celery_worker.sh
  • scripts/start-dev.sh
🔇 Additional comments (4)
scripts/start.sh (2)

4-4: Oh look, someone finally remembered proper shell options!

The use of set -euo pipefail is a robust choice that will help catch those pesky errors early. It's always nice when scripts don't silently fail.


13-17: Interesting worker count choice for non-New Relic mode

The conditional New Relic integration looks good, but I couldn't help but notice the hardcoded --workers 2 in the else branch. Are we certain that two workers will be sufficient for all deployment scenarios?

Consider making the worker count configurable via an environment variable:

-  gunicorn config.wsgi:application --bind 0.0.0.0:9000 --chdir=/app --workers 2
+  GUNICORN_WORKERS="${GUNICORN_WORKERS:-2}"
+  gunicorn config.wsgi:application --bind 0.0.0.0:9000 --chdir=/app --workers "$GUNICORN_WORKERS"

Let's check if there are any worker configurations in other files:

✅ Verification successful

Oh, how interesting that the worker count is actually quite well-documented

The documentation in docs/working-components/configuration.rst explicitly states that the application is designed to use 2 * No of cores workers, and that "the application involves very little CPU." The current setting of 2 workers appears to be a reasonable default for single-core deployments, and the docs suggest that scaling should be handled through load balancing rather than increasing workers per instance.

  • The hardcoded value aligns with the documented architecture design
  • Scaling is recommended through load balancer and multiple instances rather than worker count
  • The application is specifically noted to be light on CPU usage

While environment variable configuration might seem cleaner, the current approach actually follows the documented architectural decisions. Sometimes the simplest solution is the right one... even if it doesn't look as sophisticated as we might prefer.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for existing Gunicorn worker configurations
echo "=== Searching for Gunicorn worker configurations ==="
rg -l "workers|worker_class|worker_connections" --type yaml --type conf --type ini

# Check for environment variables related to workers
echo "=== Searching for worker-related environment variables ==="
rg -l "GUNICORN.*WORKERS|WEB.*CONCURRENCY" --type yaml --type env

Length of output: 546


Script:

#!/bin/bash
# Let's try a more comprehensive search without file type restrictions
echo "=== Searching for Gunicorn worker configurations ==="
rg -i "workers.*=|worker_class|worker_connections|WEB_CONCURRENCY|GUNICORN.*WORKERS"

# Also check for any docker-compose files that might have worker configs
echo "=== Checking docker-compose files ==="
fd "docker-compose" --exec cat {}

# And any environment files
echo "=== Checking environment files ==="
fd ".env" --exec cat {}

Length of output: 3494

scripts/wait_for_db.sh (1)

1-2: LGTM!

The shebang and spacing look fine, I suppose.

scripts/wait_for_redis.sh (1)

1-27: Just a tiny security consideration that you might want to think about...

The script uses environment variables directly in Python code execution. While this is generally fine for internal tools, it's worth noting that REDIS_URL should be properly sanitized if there's any chance it could contain malicious input.

Let's check if REDIS_URL is used safely elsewhere in the codebase:

scripts/start.sh Show resolved Hide resolved
scripts/wait_for_db.sh Show resolved Hide resolved
scripts/wait_for_db.sh Show resolved Hide resolved
@sainak
Copy link
Member Author

sainak commented Nov 14, 2024

@coderabbitai summary

Copy link

coderabbitai bot commented Nov 14, 2024

✅ Actions performed

Summary regeneration triggered.

@sainak sainak self-assigned this Nov 15, 2024
@vigneshhari vigneshhari merged commit fbc6157 into develop Nov 25, 2024
8 checks passed
@vigneshhari vigneshhari deleted the sainak/dependency-fixes branch November 25, 2024 14:59
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.

Securing prod docker images
2 participants