Compare commits

..

1 Commits

Author SHA1 Message Date
176dc6f479 chore(deps): bump the github-actions-dependencies group with 4 updates
Bumps the github-actions-dependencies group with 4 updates: [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv), [docker/login-action](https://github.com/docker/login-action), [super-linter/super-linter](https://github.com/super-linter/super-linter) and [anthropics/claude-code-action](https://github.com/anthropics/claude-code-action).


Updates `astral-sh/setup-uv` from 7.6.0 to 8.0.0
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/v7.6...cec208311dfd045dd5311c1add060b2062131d57)

Updates `docker/login-action` from 4.0.0 to 4.1.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](b45d80f862...4907a6ddec)

Updates `super-linter/super-linter` from 8.5.0 to 8.6.0
- [Release notes](https://github.com/super-linter/super-linter/releases)
- [Changelog](https://github.com/super-linter/super-linter/blob/main/CHANGELOG.md)
- [Commits](61abc07d75...9e863354e3)

Updates `anthropics/claude-code-action` from 1.0.82 to 1.0.89
- [Release notes](https://github.com/anthropics/claude-code-action/releases)
- [Commits](88c168b39e...6e2bd52842)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions-dependencies
- dependency-name: docker/login-action
  dependency-version: 4.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-dependencies
- dependency-name: super-linter/super-linter
  dependency-version: 8.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-dependencies
- dependency-name: anthropics/claude-code-action
  dependency-version: 1.0.89
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-06 01:22:31 +00:00
11 changed files with 43 additions and 96 deletions

View File

@ -65,7 +65,7 @@ jobs:
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Login to Docker Hub
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
username: ${{ env.DOCKERHUB_USER }}
password: ${{ env.DOCKERHUB_TOKEN }}
@ -130,7 +130,7 @@ jobs:
merge-multiple: true
- name: Login to Docker Hub
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
username: ${{ env.DOCKERHUB_USER }}
password: ${{ env.DOCKERHUB_TOKEN }}

View File

@ -149,7 +149,7 @@ jobs:
.editorconfig
- name: Super-linter
uses: super-linter/super-linter/slim@61abc07d755095a68f4987d1c2c3d1d64408f1f9 # v8.5.0
uses: super-linter/super-linter/slim@9e863354e3ff62e0727d37183162c4a88873df41 # v8.6.0
if: steps.changed-files.outputs.any_changed == 'true'
env:
BASH_SEVERITY: warning

View File

@ -240,7 +240,7 @@ jobs:
- name: Run Claude Code for Translation Sync
if: steps.context.outputs.CHANGED_FILES != ''
uses: anthropics/claude-code-action@88c168b39e7e64da0286d812b6e9fbebb6708185 # v1.0.82
uses: anthropics/claude-code-action@6e2bd52842c65e914eba5c8badd17560bd26b5de # v1.0.89
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -36,7 +36,7 @@ jobs:
remove_tool_cache: true
- name: Setup UV and Python
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
with:
enable-cache: true
python-version: ${{ matrix.python-version }}

View File

@ -1,18 +0,0 @@
# This module provides a lightweight Celery instance for use in Docker health checks.
# Unlike celery_entrypoint.py, this does NOT import app.py and therefore avoids
# initializing all Flask extensions (DB, Redis, storage, blueprints, etc.).
# Using this module keeps the health check fast and low-cost.
from celery import Celery
from configs import dify_config
from extensions.ext_celery import get_celery_broker_transport_options, get_celery_ssl_options
celery = Celery(broker=dify_config.CELERY_BROKER_URL)
broker_transport_options = get_celery_broker_transport_options()
if broker_transport_options:
celery.conf.update(broker_transport_options=broker_transport_options)
ssl_options = get_celery_ssl_options()
if ssl_options:
celery.conf.update(broker_use_ssl=ssl_options)

View File

@ -10,7 +10,7 @@ from configs import dify_config
from dify_app import DifyApp
def get_celery_ssl_options() -> dict[str, Any] | None:
def _get_celery_ssl_options() -> dict[str, Any] | None:
"""Get SSL configuration for Celery broker/backend connections."""
# Only apply SSL if we're using Redis as broker/backend
if not dify_config.BROKER_USE_SSL:
@ -43,19 +43,6 @@ def get_celery_ssl_options() -> dict[str, Any] | None:
return ssl_options
def get_celery_broker_transport_options() -> dict[str, Any]:
"""Get broker transport options (e.g. Redis Sentinel) for Celery connections."""
if dify_config.CELERY_USE_SENTINEL:
return {
"master_name": dify_config.CELERY_SENTINEL_MASTER_NAME,
"sentinel_kwargs": {
"socket_timeout": dify_config.CELERY_SENTINEL_SOCKET_TIMEOUT,
"password": dify_config.CELERY_SENTINEL_PASSWORD,
},
}
return {}
def init_app(app: DifyApp) -> Celery:
class FlaskTask(Task):
def __call__(self, *args: object, **kwargs: object) -> object:
@ -66,7 +53,16 @@ def init_app(app: DifyApp) -> Celery:
init_request_context()
return self.run(*args, **kwargs)
broker_transport_options = get_celery_broker_transport_options()
broker_transport_options = {}
if dify_config.CELERY_USE_SENTINEL:
broker_transport_options = {
"master_name": dify_config.CELERY_SENTINEL_MASTER_NAME,
"sentinel_kwargs": {
"socket_timeout": dify_config.CELERY_SENTINEL_SOCKET_TIMEOUT,
"password": dify_config.CELERY_SENTINEL_PASSWORD,
},
}
celery_app = Celery(
app.name,
@ -93,7 +89,7 @@ def init_app(app: DifyApp) -> Celery:
)
# Apply SSL configuration if enabled
ssl_options = get_celery_ssl_options()
ssl_options = _get_celery_ssl_options()
if ssl_options:
celery_app.conf.update(
broker_use_ssl=ssl_options,

View File

@ -14,9 +14,9 @@ class TestCelerySSLConfiguration:
dify_config = DifyConfig(CELERY_BROKER_URL="redis://localhost:6379/0")
with patch("extensions.ext_celery.dify_config", dify_config):
from extensions.ext_celery import get_celery_ssl_options
from extensions.ext_celery import _get_celery_ssl_options
result = get_celery_ssl_options()
result = _get_celery_ssl_options()
assert result is None
def test_get_celery_ssl_options_when_broker_not_redis(self):
@ -25,9 +25,9 @@ class TestCelerySSLConfiguration:
mock_config.CELERY_BROKER_URL = "amqp://localhost:5672"
with patch("extensions.ext_celery.dify_config", mock_config):
from extensions.ext_celery import get_celery_ssl_options
from extensions.ext_celery import _get_celery_ssl_options
result = get_celery_ssl_options()
result = _get_celery_ssl_options()
assert result is None
def test_get_celery_ssl_options_with_cert_none(self):
@ -40,9 +40,9 @@ class TestCelerySSLConfiguration:
mock_config.REDIS_SSL_KEYFILE = None
with patch("extensions.ext_celery.dify_config", mock_config):
from extensions.ext_celery import get_celery_ssl_options
from extensions.ext_celery import _get_celery_ssl_options
result = get_celery_ssl_options()
result = _get_celery_ssl_options()
assert result is not None
assert result["ssl_cert_reqs"] == ssl.CERT_NONE
assert result["ssl_ca_certs"] is None
@ -59,9 +59,9 @@ class TestCelerySSLConfiguration:
mock_config.REDIS_SSL_KEYFILE = "/path/to/client.key"
with patch("extensions.ext_celery.dify_config", mock_config):
from extensions.ext_celery import get_celery_ssl_options
from extensions.ext_celery import _get_celery_ssl_options
result = get_celery_ssl_options()
result = _get_celery_ssl_options()
assert result is not None
assert result["ssl_cert_reqs"] == ssl.CERT_REQUIRED
assert result["ssl_ca_certs"] == "/path/to/ca.crt"
@ -78,9 +78,9 @@ class TestCelerySSLConfiguration:
mock_config.REDIS_SSL_KEYFILE = None
with patch("extensions.ext_celery.dify_config", mock_config):
from extensions.ext_celery import get_celery_ssl_options
from extensions.ext_celery import _get_celery_ssl_options
result = get_celery_ssl_options()
result = _get_celery_ssl_options()
assert result is not None
assert result["ssl_cert_reqs"] == ssl.CERT_OPTIONAL
assert result["ssl_ca_certs"] == "/path/to/ca.crt"
@ -95,9 +95,9 @@ class TestCelerySSLConfiguration:
mock_config.REDIS_SSL_KEYFILE = None
with patch("extensions.ext_celery.dify_config", mock_config):
from extensions.ext_celery import get_celery_ssl_options
from extensions.ext_celery import _get_celery_ssl_options
result = get_celery_ssl_options()
result = _get_celery_ssl_options()
assert result is not None
assert result["ssl_cert_reqs"] == ssl.CERT_NONE # Should default to CERT_NONE

View File

@ -1358,18 +1358,6 @@ SSRF_POOL_KEEPALIVE_EXPIRY=5.0
# ------------------------------
COMPOSE_PROFILES=${VECTOR_STORE:-weaviate},${DB_TYPE:-postgresql}
# ------------------------------
# Worker health check configuration for worker and worker_beat services.
# Set to false to enable the health check.
# Note: enabling the health check may cause periodic CPU spikes and increased load,
# as it establishes a broker connection and sends a Celery ping on every check interval.
# ------------------------------
COMPOSE_WORKER_HEALTHCHECK_DISABLED=true
# Interval between health checks (e.g. 30s, 1m)
COMPOSE_WORKER_HEALTHCHECK_INTERVAL=30s
# Timeout for each health check (e.g. 30s, 1m)
COMPOSE_WORKER_HEALTHCHECK_TIMEOUT=30s
# ------------------------------
# Docker Compose Service Expose Host Port Configurations
# ------------------------------

View File

@ -102,12 +102,11 @@ services:
# Mount the storage directory to the container, for storing user files.
- ./volumes/app/storage:/app/api/storage
healthcheck:
test: ["CMD-SHELL", "celery -A celery_healthcheck.celery inspect ping"]
interval: ${COMPOSE_WORKER_HEALTHCHECK_INTERVAL:-30s}
timeout: ${COMPOSE_WORKER_HEALTHCHECK_TIMEOUT:-30s}
test: ["CMD-SHELL", "celery -A celery_entrypoint.celery inspect ping"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
disable: ${COMPOSE_WORKER_HEALTHCHECK_DISABLED:-true}
networks:
- ssrf_proxy_network
- default
@ -140,12 +139,11 @@ services:
redis:
condition: service_started
healthcheck:
test: ["CMD-SHELL", "celery -A celery_healthcheck.celery inspect ping"]
interval: ${COMPOSE_WORKER_HEALTHCHECK_INTERVAL:-30s}
timeout: ${COMPOSE_WORKER_HEALTHCHECK_TIMEOUT:-30s}
test: ["CMD-SHELL", "celery -A app.celery inspect ping"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
disable: ${COMPOSE_WORKER_HEALTHCHECK_DISABLED:-true}
networks:
- ssrf_proxy_network
- default

View File

@ -811,12 +811,11 @@ services:
# Mount the storage directory to the container, for storing user files.
- ./volumes/app/storage:/app/api/storage
healthcheck:
test: ["CMD-SHELL", "celery -A celery_healthcheck.celery inspect ping"]
interval: ${COMPOSE_WORKER_HEALTHCHECK_INTERVAL:-30s}
timeout: ${COMPOSE_WORKER_HEALTHCHECK_TIMEOUT:-30s}
test: ["CMD-SHELL", "celery -A celery_entrypoint.celery inspect ping"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
disable: ${COMPOSE_WORKER_HEALTHCHECK_DISABLED:-true}
networks:
- ssrf_proxy_network
- default
@ -849,12 +848,11 @@ services:
redis:
condition: service_started
healthcheck:
test: ["CMD-SHELL", "celery -A celery_healthcheck.celery inspect ping"]
interval: ${COMPOSE_WORKER_HEALTHCHECK_INTERVAL:-30s}
timeout: ${COMPOSE_WORKER_HEALTHCHECK_TIMEOUT:-30s}
test: ["CMD-SHELL", "celery -A app.celery inspect ping"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
disable: ${COMPOSE_WORKER_HEALTHCHECK_DISABLED:-true}
networks:
- ssrf_proxy_network
- default

View File

@ -3,20 +3,6 @@ import os
import re
import sys
# Variables that exist only for Docker Compose orchestration and must NOT be
# injected into containers as environment variables.
SHARED_ENV_EXCLUDE = frozenset(
[
# Docker Compose profile selection
"COMPOSE_PROFILES",
# Worker health check orchestration flags (consumed by docker-compose,
# not by the application running inside the container)
"COMPOSE_WORKER_HEALTHCHECK_DISABLED",
"COMPOSE_WORKER_HEALTHCHECK_INTERVAL",
"COMPOSE_WORKER_HEALTHCHECK_TIMEOUT",
]
)
def parse_env_example(file_path):
"""
@ -51,7 +37,7 @@ def generate_shared_env_block(env_vars, anchor_name="shared-api-worker-env"):
"""
lines = [f"x-shared-env: &{anchor_name}"]
for key, default in env_vars.items():
if key in SHARED_ENV_EXCLUDE:
if key == "COMPOSE_PROFILES":
continue
# If default value is empty, use ${KEY:-}
if default == "":
@ -68,7 +54,6 @@ def insert_shared_env(template_path, output_path, shared_env_block, header_comme
"""
Inserts the shared environment variables block and header comments into the template file,
removing any existing x-shared-env anchors, and generates the final docker-compose.yaml file.
Always writes with LF line endings.
"""
with open(template_path, "r", encoding="utf-8") as f:
template_content = f.read()
@ -84,7 +69,7 @@ def insert_shared_env(template_path, output_path, shared_env_block, header_comme
# Prepare the final content with header comments and shared env block
final_content = f"{header_comments}\n{shared_env_block}\n\n{template_content}"
with open(output_path, "w", encoding="utf-8", newline="\n") as f:
with open(output_path, "w", encoding="utf-8") as f:
f.write(final_content)
print(f"Generated {output_path}")