Skip to content

Commit a284325

Browse files
committed
Fix variable handling
1 parent 4b93797 commit a284325

File tree

5 files changed

+166
-110
lines changed

5 files changed

+166
-110
lines changed

.github/workflows/codedeploy_production.yml

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -203,81 +203,82 @@ jobs:
203203
run: |
204204
# Generate prod.env with secrets from GitHub
205205
# This file is included in the deployment package and copied to the server
206-
# All values are single-quoted to prevent shell interpretation of special characters
206+
# Values are NOT quoted - Docker env_file reads quotes as literal characters
207+
# The CodeDeploy scripts use safe_source_env() to handle special chars in values
207208
{
208209
echo "# Generated by GitHub Actions"
209210
echo "# Commit: ${{ github.sha }}"
210211
echo ""
211212
echo "# ECR Images (pre-built in CI)"
212-
echo "ECR_REGISTRY='$ECR_REGISTRY'"
213-
echo "API_IMAGE='$API_IMAGE'"
213+
echo "ECR_REGISTRY=$ECR_REGISTRY"
214+
echo "API_IMAGE=$API_IMAGE"
214215
echo ""
215216
echo "# Environment"
216-
echo "ENVIRONMENT='production'"
217-
echo "DEBUG='False'"
218-
echo "TESTING='false'"
217+
echo "ENVIRONMENT=production"
218+
echo "DEBUG=False"
219+
echo "TESTING=false"
219220
echo ""
220221
echo "# Flask/API Configuration"
221-
echo "SECRET_KEY='$SECRET_KEY'"
222-
echo "JWT_SECRET_KEY='$JWT_SECRET_KEY'"
223-
echo "API_ENVIRONMENT_USER='$API_ENVIRONMENT_USER'"
224-
echo "API_ENVIRONMENT_USER_PASSWORD='$API_ENVIRONMENT_USER_PASSWORD'"
222+
echo "SECRET_KEY=$SECRET_KEY"
223+
echo "JWT_SECRET_KEY=$JWT_SECRET_KEY"
224+
echo "API_ENVIRONMENT_USER=$API_ENVIRONMENT_USER"
225+
echo "API_ENVIRONMENT_USER_PASSWORD=$API_ENVIRONMENT_USER_PASSWORD"
225226
echo ""
226227
echo "# Database Configuration"
227-
echo "DATABASE_URL='$DATABASE_URL'"
228+
echo "DATABASE_URL=$DATABASE_URL"
228229
echo ""
229230
echo "# Redis Configuration (uses stack Redis service)"
230-
echo "REDIS_URL='redis://redis:6379/0'"
231+
echo "REDIS_URL=redis://redis:6379/0"
231232
echo ""
232233
echo "# Rate Limiting"
233-
echo "RATE_LIMITING_ENABLED='$RATE_LIMITING_ENABLED'"
234-
echo "RATE_LIMIT_STORAGE_URI='redis://redis:6379/1'"
235-
echo "DEFAULT_LIMITS='$RATE_LIMIT_DEFAULT_LIMITS'"
236-
echo "API_LIMITS='$RATE_LIMIT_API_LIMITS'"
237-
echo "AUTH_LIMITS='$RATE_LIMIT_AUTH_LIMITS'"
238-
echo "PASSWORD_RESET_LIMITS='$RATE_LIMIT_PASSWORD_RESET_LIMITS'"
239-
echo "USER_CREATION_LIMITS='$RATE_LIMIT_USER_CREATION_LIMITS'"
240-
echo "EXECUTION_RUN_LIMITS='$RATE_LIMIT_EXECUTION_RUN_LIMITS'"
241-
echo "TRUSTED_PROXY_COUNT='$RATE_LIMIT_TRUSTED_PROXY_COUNT'"
242-
echo "INTERNAL_NETWORKS='$RATE_LIMIT_INTERNAL_NETWORKS'"
234+
echo "RATE_LIMITING_ENABLED=$RATE_LIMITING_ENABLED"
235+
echo "RATE_LIMIT_STORAGE_URI=redis://redis:6379/1"
236+
echo "DEFAULT_LIMITS=$RATE_LIMIT_DEFAULT_LIMITS"
237+
echo "API_LIMITS=$RATE_LIMIT_API_LIMITS"
238+
echo "AUTH_LIMITS=$RATE_LIMIT_AUTH_LIMITS"
239+
echo "PASSWORD_RESET_LIMITS=$RATE_LIMIT_PASSWORD_RESET_LIMITS"
240+
echo "USER_CREATION_LIMITS=$RATE_LIMIT_USER_CREATION_LIMITS"
241+
echo "EXECUTION_RUN_LIMITS=$RATE_LIMIT_EXECUTION_RUN_LIMITS"
242+
echo "TRUSTED_PROXY_COUNT=$RATE_LIMIT_TRUSTED_PROXY_COUNT"
243+
echo "INTERNAL_NETWORKS=$RATE_LIMIT_INTERNAL_NETWORKS"
243244
echo ""
244245
echo "# Google Earth Engine"
245-
echo "EE_SERVICE_ACCOUNT_JSON='$EE_SERVICE_ACCOUNT_JSON'"
246-
echo "GOOGLE_PROJECT_ID='$GOOGLE_PROJECT_ID'"
247-
echo "GEE_ENDPOINT='$GEE_ENDPOINT'"
248-
echo "GOOGLE_OAUTH_CLIENT_ID='$GOOGLE_OAUTH_CLIENT_ID'"
249-
echo "GOOGLE_OAUTH_CLIENT_SECRET='$GOOGLE_OAUTH_CLIENT_SECRET'"
250-
echo "GOOGLE_OAUTH_REDIRECT_URI='$GOOGLE_OAUTH_REDIRECT_URI'"
246+
echo "EE_SERVICE_ACCOUNT_JSON=$EE_SERVICE_ACCOUNT_JSON"
247+
echo "GOOGLE_PROJECT_ID=$GOOGLE_PROJECT_ID"
248+
echo "GEE_ENDPOINT=$GEE_ENDPOINT"
249+
echo "GOOGLE_OAUTH_CLIENT_ID=$GOOGLE_OAUTH_CLIENT_ID"
250+
echo "GOOGLE_OAUTH_CLIENT_SECRET=$GOOGLE_OAUTH_CLIENT_SECRET"
251+
echo "GOOGLE_OAUTH_REDIRECT_URI=$GOOGLE_OAUTH_REDIRECT_URI"
251252
echo ""
252253
echo "# Rollbar Error Tracking"
253-
echo "ROLLBAR_SCRIPT_TOKEN='$ROLLBAR_SCRIPT_TOKEN'"
254-
echo "ROLLBAR_SERVER_TOKEN='$ROLLBAR_SERVER_TOKEN'"
254+
echo "ROLLBAR_SCRIPT_TOKEN=$ROLLBAR_SCRIPT_TOKEN"
255+
echo "ROLLBAR_SERVER_TOKEN=$ROLLBAR_SERVER_TOKEN"
255256
echo ""
256257
echo "# API URLs"
257-
echo "API_PUBLIC_URL='$API_PUBLIC_URL'"
258-
echo "API_INTERNAL_URL='http://api:3000'"
258+
echo "API_PUBLIC_URL=$API_PUBLIC_URL"
259+
echo "API_INTERNAL_URL=http://api:3000"
259260
echo ""
260261
echo "# S3 Configuration (uses EC2 instance role for credentials)"
261-
echo "SCRIPTS_S3_BUCKET='$SCRIPTS_S3_BUCKET'"
262-
echo "SCRIPTS_S3_PREFIX='$SCRIPTS_S3_PREFIX'"
263-
echo "PARAMS_S3_BUCKET='$PARAMS_S3_BUCKET'"
264-
echo "PARAMS_S3_PREFIX='$PARAMS_S3_PREFIX'"
262+
echo "SCRIPTS_S3_BUCKET=$SCRIPTS_S3_BUCKET"
263+
echo "SCRIPTS_S3_PREFIX=$SCRIPTS_S3_PREFIX"
264+
echo "PARAMS_S3_BUCKET=$PARAMS_S3_BUCKET"
265+
echo "PARAMS_S3_PREFIX=$PARAMS_S3_PREFIX"
265266
echo ""
266267
echo "# Docker Configuration"
267-
echo "REGISTRY_URL='$REGISTRY_URL'"
268-
echo "DOCKER_SUBNET='$DOCKER_SUBNET'"
269-
echo "EXECUTION_SUBNET='$EXECUTION_SUBNET'"
268+
echo "REGISTRY_URL=$REGISTRY_URL"
269+
echo "DOCKER_SUBNET=$DOCKER_SUBNET"
270+
echo "EXECUTION_SUBNET=$EXECUTION_SUBNET"
270271
echo ""
271272
echo "# Email Configuration (SparkPost)"
272-
echo "SPARKPOST_API_KEY='$SPARKPOST_API_KEY'"
273+
echo "SPARKPOST_API_KEY=$SPARKPOST_API_KEY"
273274
echo ""
274275
echo "# CORS Configuration"
275-
echo "CORS_ORIGINS='$CORS_ORIGINS'"
276+
echo "CORS_ORIGINS=$CORS_ORIGINS"
276277
echo ""
277278
echo "# Deployment info"
278-
echo "GIT_REVISION='${{ github.sha }}'"
279-
echo "GIT_BRANCH='${{ github.ref_name }}'"
280-
echo "DEPLOYMENT_ENVIRONMENT='production'"
279+
echo "GIT_REVISION=${{ github.sha }}"
280+
echo "GIT_BRANCH=${{ github.ref_name }}"
281+
echo "DEPLOYMENT_ENVIRONMENT=production"
281282
} > prod.env
282283
echo "✅ Created prod.env with $(wc -l < prod.env) lines"
283284

.github/workflows/codedeploy_staging.yml

Lines changed: 52 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -213,92 +213,93 @@ jobs:
213213
run: |
214214
# Generate staging.env with secrets from GitHub
215215
# This file is included in the deployment package and copied to the server
216-
# All values are single-quoted to prevent shell interpretation of special characters
216+
# Values are NOT quoted - Docker env_file reads quotes as literal characters
217+
# The CodeDeploy scripts use safe_source_env() to handle special chars in values
217218
{
218219
echo "# Generated by GitHub Actions"
219220
echo "# Commit: ${{ github.sha }}"
220221
echo ""
221222
echo "# ECR Images (pre-built in CI)"
222-
echo "ECR_REGISTRY='$ECR_REGISTRY'"
223-
echo "API_IMAGE='$API_IMAGE'"
223+
echo "ECR_REGISTRY=$ECR_REGISTRY"
224+
echo "API_IMAGE=$API_IMAGE"
224225
echo ""
225226
echo "# Environment"
226-
echo "ENVIRONMENT='staging'"
227-
echo "DEBUG='False'"
228-
echo "TESTING='false'"
227+
echo "ENVIRONMENT=staging"
228+
echo "DEBUG=False"
229+
echo "TESTING=false"
229230
echo ""
230231
echo "# Flask/API Configuration"
231-
echo "SECRET_KEY='$SECRET_KEY'"
232-
echo "JWT_SECRET_KEY='$JWT_SECRET_KEY'"
233-
echo "API_ENVIRONMENT_USER='$API_ENVIRONMENT_USER'"
234-
echo "API_ENVIRONMENT_USER_PASSWORD='$API_ENVIRONMENT_USER_PASSWORD'"
232+
echo "SECRET_KEY=$SECRET_KEY"
233+
echo "JWT_SECRET_KEY=$JWT_SECRET_KEY"
234+
echo "API_ENVIRONMENT_USER=$API_ENVIRONMENT_USER"
235+
echo "API_ENVIRONMENT_USER_PASSWORD=$API_ENVIRONMENT_USER_PASSWORD"
235236
echo ""
236237
echo "# Database Configuration"
237-
echo "DATABASE_URL='$DATABASE_URL'"
238+
echo "DATABASE_URL=$DATABASE_URL"
238239
echo ""
239240
echo "# Redis Configuration (uses stack Redis service)"
240-
echo "REDIS_URL='redis://redis:6379/0'"
241+
echo "REDIS_URL=redis://redis:6379/0"
241242
echo ""
242243
echo "# Rate Limiting"
243-
echo "RATE_LIMITING_ENABLED='$RATE_LIMITING_ENABLED'"
244-
echo "RATE_LIMIT_STORAGE_URI='redis://redis:6379/1'"
245-
echo "DEFAULT_LIMITS='$RATE_LIMIT_DEFAULT_LIMITS'"
246-
echo "API_LIMITS='$RATE_LIMIT_API_LIMITS'"
247-
echo "AUTH_LIMITS='$RATE_LIMIT_AUTH_LIMITS'"
248-
echo "PASSWORD_RESET_LIMITS='$RATE_LIMIT_PASSWORD_RESET_LIMITS'"
249-
echo "USER_CREATION_LIMITS='$RATE_LIMIT_USER_CREATION_LIMITS'"
250-
echo "EXECUTION_RUN_LIMITS='$RATE_LIMIT_EXECUTION_RUN_LIMITS'"
251-
echo "TRUSTED_PROXY_COUNT='$RATE_LIMIT_TRUSTED_PROXY_COUNT'"
252-
echo "INTERNAL_NETWORKS='$RATE_LIMIT_INTERNAL_NETWORKS'"
244+
echo "RATE_LIMITING_ENABLED=$RATE_LIMITING_ENABLED"
245+
echo "RATE_LIMIT_STORAGE_URI=redis://redis:6379/1"
246+
echo "DEFAULT_LIMITS=$RATE_LIMIT_DEFAULT_LIMITS"
247+
echo "API_LIMITS=$RATE_LIMIT_API_LIMITS"
248+
echo "AUTH_LIMITS=$RATE_LIMIT_AUTH_LIMITS"
249+
echo "PASSWORD_RESET_LIMITS=$RATE_LIMIT_PASSWORD_RESET_LIMITS"
250+
echo "USER_CREATION_LIMITS=$RATE_LIMIT_USER_CREATION_LIMITS"
251+
echo "EXECUTION_RUN_LIMITS=$RATE_LIMIT_EXECUTION_RUN_LIMITS"
252+
echo "TRUSTED_PROXY_COUNT=$RATE_LIMIT_TRUSTED_PROXY_COUNT"
253+
echo "INTERNAL_NETWORKS=$RATE_LIMIT_INTERNAL_NETWORKS"
253254
echo ""
254255
echo "# Google Earth Engine"
255-
echo "EE_SERVICE_ACCOUNT_JSON='$EE_SERVICE_ACCOUNT_JSON'"
256-
echo "GOOGLE_PROJECT_ID='$GOOGLE_PROJECT_ID'"
257-
echo "GEE_ENDPOINT='$GEE_ENDPOINT'"
258-
echo "GOOGLE_OAUTH_CLIENT_ID='$GOOGLE_OAUTH_CLIENT_ID'"
259-
echo "GOOGLE_OAUTH_CLIENT_SECRET='$GOOGLE_OAUTH_CLIENT_SECRET'"
260-
echo "GOOGLE_OAUTH_REDIRECT_URI='$GOOGLE_OAUTH_REDIRECT_URI'"
256+
echo "EE_SERVICE_ACCOUNT_JSON=$EE_SERVICE_ACCOUNT_JSON"
257+
echo "GOOGLE_PROJECT_ID=$GOOGLE_PROJECT_ID"
258+
echo "GEE_ENDPOINT=$GEE_ENDPOINT"
259+
echo "GOOGLE_OAUTH_CLIENT_ID=$GOOGLE_OAUTH_CLIENT_ID"
260+
echo "GOOGLE_OAUTH_CLIENT_SECRET=$GOOGLE_OAUTH_CLIENT_SECRET"
261+
echo "GOOGLE_OAUTH_REDIRECT_URI=$GOOGLE_OAUTH_REDIRECT_URI"
261262
echo ""
262263
echo "# Rollbar Error Tracking"
263-
echo "ROLLBAR_SCRIPT_TOKEN='$ROLLBAR_SCRIPT_TOKEN'"
264-
echo "ROLLBAR_SERVER_TOKEN='$ROLLBAR_SERVER_TOKEN'"
264+
echo "ROLLBAR_SCRIPT_TOKEN=$ROLLBAR_SCRIPT_TOKEN"
265+
echo "ROLLBAR_SERVER_TOKEN=$ROLLBAR_SERVER_TOKEN"
265266
echo ""
266267
echo "# API URLs"
267-
echo "API_PUBLIC_URL='$API_PUBLIC_URL'"
268-
echo "API_INTERNAL_URL='http://api:3000'"
268+
echo "API_PUBLIC_URL=$API_PUBLIC_URL"
269+
echo "API_INTERNAL_URL=http://api:3000"
269270
echo ""
270271
echo "# S3 Configuration (uses EC2 instance role for credentials)"
271-
echo "SCRIPTS_S3_BUCKET='$SCRIPTS_S3_BUCKET'"
272-
echo "SCRIPTS_S3_PREFIX='$SCRIPTS_S3_PREFIX'"
273-
echo "PARAMS_S3_BUCKET='$PARAMS_S3_BUCKET'"
274-
echo "PARAMS_S3_PREFIX='$PARAMS_S3_PREFIX'"
272+
echo "SCRIPTS_S3_BUCKET=$SCRIPTS_S3_BUCKET"
273+
echo "SCRIPTS_S3_PREFIX=$SCRIPTS_S3_PREFIX"
274+
echo "PARAMS_S3_BUCKET=$PARAMS_S3_BUCKET"
275+
echo "PARAMS_S3_PREFIX=$PARAMS_S3_PREFIX"
275276
echo ""
276277
echo "# Docker Configuration"
277-
echo "REGISTRY_URL='$REGISTRY_URL'"
278-
echo "DOCKER_SUBNET='$DOCKER_SUBNET'"
279-
echo "EXECUTION_SUBNET='$EXECUTION_SUBNET'"
278+
echo "REGISTRY_URL=$REGISTRY_URL"
279+
echo "DOCKER_SUBNET=$DOCKER_SUBNET"
280+
echo "EXECUTION_SUBNET=$EXECUTION_SUBNET"
280281
echo ""
281282
echo "# Email Configuration (SparkPost)"
282-
echo "SPARKPOST_API_KEY='$SPARKPOST_API_KEY'"
283+
echo "SPARKPOST_API_KEY=$SPARKPOST_API_KEY"
283284
echo ""
284285
echo "# CORS Configuration"
285-
echo "CORS_ORIGINS='$CORS_ORIGINS'"
286+
echo "CORS_ORIGINS=$CORS_ORIGINS"
286287
echo ""
287288
echo "# Staging Database Setup (for migrate service)"
288289
echo "# Production database URL for copying scripts/data to staging"
289-
echo "PRODUCTION_DATABASE_URL='$PRODUCTION_DATABASE_URL'"
290+
echo "PRODUCTION_DATABASE_URL=$PRODUCTION_DATABASE_URL"
290291
echo "# Test user credentials"
291-
echo "TEST_SUPERADMIN_EMAIL='$TEST_SUPERADMIN_EMAIL'"
292-
echo "TEST_SUPERADMIN_PASSWORD='$TEST_SUPERADMIN_PASSWORD'"
293-
echo "TEST_ADMIN_EMAIL='$TEST_ADMIN_EMAIL'"
294-
echo "TEST_ADMIN_PASSWORD='$TEST_ADMIN_PASSWORD'"
295-
echo "TEST_USER_EMAIL='$TEST_USER_EMAIL'"
296-
echo "TEST_USER_PASSWORD='$TEST_USER_PASSWORD'"
292+
echo "TEST_SUPERADMIN_EMAIL=$TEST_SUPERADMIN_EMAIL"
293+
echo "TEST_SUPERADMIN_PASSWORD=$TEST_SUPERADMIN_PASSWORD"
294+
echo "TEST_ADMIN_EMAIL=$TEST_ADMIN_EMAIL"
295+
echo "TEST_ADMIN_PASSWORD=$TEST_ADMIN_PASSWORD"
296+
echo "TEST_USER_EMAIL=$TEST_USER_EMAIL"
297+
echo "TEST_USER_PASSWORD=$TEST_USER_PASSWORD"
297298
echo ""
298299
echo "# Deployment info"
299-
echo "GIT_REVISION='${{ github.sha }}'"
300-
echo "GIT_BRANCH='${{ github.ref_name }}'"
301-
echo "DEPLOYMENT_ENVIRONMENT='staging'"
300+
echo "GIT_REVISION=${{ github.sha }}"
301+
echo "GIT_BRANCH=${{ github.ref_name }}"
302+
echo "DEPLOYMENT_ENVIRONMENT=staging"
302303
} > staging.env
303304
echo "✅ Created staging.env with $(wc -l < staging.env) lines"
304305

scripts/codedeploy/after-install.sh

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,11 @@ cd "$APP_DIR"
2929
# ============================================================================
3030

3131
ENV_FILE=$(get_env_file "$ENVIRONMENT")
32-
if [ -f "$ENV_FILE" ]; then
33-
log_info "Loading environment variables from $ENV_FILE"
34-
set -a
35-
source "$ENV_FILE"
36-
set +a
37-
else
38-
log_error "Environment file not found: $ENV_FILE"
32+
log_info "Loading environment variables from $ENV_FILE"
33+
# Use safe_source_env to handle special characters (# & etc) in values
34+
# This reads line-by-line instead of bash 'source' which interprets special chars
35+
if ! safe_source_env "$ENV_FILE"; then
36+
log_error "Failed to load environment file: $ENV_FILE"
3937
exit 1
4038
fi
4139

scripts/codedeploy/application-start.sh

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,33 @@ log_info "Compose file: $COMPOSE_FILE"
3636
# ============================================================================
3737

3838
ENV_FILE=$(get_env_file "$ENVIRONMENT")
39-
if [ -f "$ENV_FILE" ]; then
40-
log_info "Loading environment variables from $ENV_FILE"
41-
set -a
42-
source "$ENV_FILE"
43-
set +a
44-
else
45-
log_error "Environment file not found: $ENV_FILE"
39+
log_info "Loading environment variables from $ENV_FILE"
40+
# Use safe_source_env to handle special characters (# & etc) in values
41+
# This reads line-by-line instead of bash 'source' which interprets special chars
42+
if ! safe_source_env "$ENV_FILE"; then
43+
log_error "Failed to load environment file: $ENV_FILE"
4644
exit 1
4745
fi
4846

4947
# Export Docker registry for compose
5048
export DOCKER_REGISTRY="$ECR_REGISTRY"
5149

50+
# ============================================================================
51+
# Login to ECR (refresh credentials before stack deploy)
52+
# ============================================================================
53+
# ECR tokens expire after 12 hours. We need fresh credentials on the node
54+
# running docker stack deploy so --with-registry-auth can pass them to workers.
55+
56+
if [ -n "$ECR_REGISTRY" ]; then
57+
log_info "Refreshing ECR credentials before stack deploy..."
58+
ecr_login "$ECR_REGISTRY" || {
59+
log_error "Failed to refresh ECR credentials"
60+
exit 1
61+
}
62+
else
63+
log_warning "ECR_REGISTRY not set, skipping ECR login"
64+
fi
65+
5266
# ============================================================================
5367
# Verify Compose File
5468
# ============================================================================

scripts/codedeploy/common.sh

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,48 @@ get_env_file() {
117117
fi
118118
}
119119

120+
# Safely source an environment file without bash interpretation of special chars
121+
# This reads line-by-line and exports variables, handling # and & in values correctly
122+
# Docker env_file format: VAR=value (no quotes needed)
123+
# This function is necessary because 'source file.env' interprets special chars
124+
safe_source_env() {
125+
local file="$1"
126+
127+
if [ ! -f "$file" ]; then
128+
log_error "Environment file not found: $file"
129+
return 1
130+
fi
131+
132+
while IFS= read -r line || [[ -n "$line" ]]; do
133+
# Skip empty lines and comments
134+
[[ -z "$line" ]] && continue
135+
[[ "$line" =~ ^[[:space:]]*# ]] && continue
136+
137+
# Skip lines without =
138+
[[ "$line" != *"="* ]] && continue
139+
140+
# Extract key and value (split on first = only)
141+
local key="${line%%=*}"
142+
local value="${line#*=}"
143+
144+
# Skip if key is empty
145+
[[ -z "$key" ]] && continue
146+
147+
# Strip surrounding quotes if present (for backwards compatibility)
148+
# This handles both 'value' and "value" formats
149+
if [[ "$value" =~ ^\'(.*)\'$ ]]; then
150+
value="${BASH_REMATCH[1]}"
151+
elif [[ "$value" =~ ^\"(.*)\"$ ]]; then
152+
value="${BASH_REMATCH[1]}"
153+
fi
154+
155+
# Export the variable
156+
export "$key=$value"
157+
done < "$file"
158+
159+
return 0
160+
}
161+
120162
# Wait for a service to be healthy
121163
wait_for_service() {
122164
local service_url="$1"
@@ -217,4 +259,4 @@ check_swarm_leader_or_skip() {
217259
export -f log_info log_success log_warning log_error
218260
export -f detect_environment get_app_directory get_compose_file get_env_file
219261
export -f get_stack_name get_api_port wait_for_service get_aws_region ecr_login
220-
export -f is_swarm_leader check_swarm_leader_or_skip
262+
export -f is_swarm_leader check_swarm_leader_or_skip safe_source_env

0 commit comments

Comments
 (0)