Skip to content

Sync Docker Configs #1106

Sync Docker Configs

Sync Docker Configs #1106

Workflow file for this run

name: Sync Docker Configs
on:
schedule:
- cron: '0 */6 * * *' # every 6 hours
workflow_dispatch:
# trigger actions manually
push:
branches:
- main # run on PR merge to main
jobs:
sync-configs:
runs-on:
group: EC2
labels: [self-hosted, deploy]
steps:
- name: Checkout Repository
uses: actions/checkout@v2
# <NEW_CONFIG>
# if adding new config, add step to create file here
# <EXISTING_CONFIG>
# if updating existing config, add new secrets to corresponding config file
- name: Create Bot Config
run: |
mkdir -p configs
cat > configs/bot_env.txt << EOF
DISCORD_TOKEN=${{ secrets.DISCORD_TOKEN }}
SWECC_SERVER=${{ secrets.SWECC_SERVER }}
ADMIN_CHANNEL=${{ secrets.ADMIN_CHANNEL }}
LC_CHANNEL_ID=${{ secrets.LC_CHANNEL_ID }}
TRANSCRIPTS_CHANNEL=${{ secrets.TRANSCRIPTS_CHANNEL }}
SWECC_API_KEY=${{ secrets.SWECC_API_KEY }}
SWECC_URL=${{ secrets.SWECC_URL }}
PREFIX_COMMAND=${{ secrets.PREFIX_COMMAND }}
SWECC_RESUME_CHANNEL=${{ secrets.SWECC_RESUME_CHANNEL }}
CALENDAR_URL=${{ secrets.CALENDAR_URL }}
AOC_LEADERBOARD_ID=${{ secrets.AOC_LEADERBOARD_ID }}
AOC_SESSION=${{ secrets.AOC_SESSION }}
AOC_LEADERBOARD_KEY=${{ secrets.AOC_LEADERBOARD_KEY }}
INTERNSHIP_CHANNEL_ID=${{ secrets.INTERNSHIP_CHANNEL_ID }}
NEW_GRAD_CHANNEL_ID=${{ secrets.NEW_GRAD_CHANNEL_ID }}
GEMINI_API_KEY=${{ secrets.GEMINI_API_KEY }}
OFF_TOPIC_CHANNEL_ID=${{ secrets.OFF_TOPIC_CHANNEL_ID }}
OFFICER_ROLE_ID=${{ secrets.OFFICER_ROLE_ID }}
VERIFIED_ROLE_ID=${{ secrets.VERIFIED_ROLE_ID }}
READING_GROUP_CHANNEL=${{ secrets.READING_GROUP_CHANNEL }}
BOT_RABBIT_USER=${{ secrets.BOT_RABBIT_USER }}
BOT_RABBIT_PASS=${{ secrets.BOT_RABBIT_PASS }}
RABBIT_HOST=${{ secrets.RABBIT_HOST }}
RABBIT_PORT=${{ secrets.RABBIT_PORT }}
RABBIT_VHOST=${{ secrets.RABBIT_VHOST }}
VERIFIED_EMAIL_ROLE_ID=${{ secrets.VERIFIED_EMAIL_ROLE_ID }}
COHORT_CATEGORY_ID=${{ secrets.COHORT_CATEGORY_ID }}
TIMELINE_CHANNEL=${{ secrets.TIMELINE_CHANNEL }}
EOF
- name: Create Chronos Config
run: |
cat > configs/chronos_env.txt << EOF
AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION=${{ secrets.AWS_DEFAULT_REGION }}
EOF
- name: Create Scheduler Config
run: |
cat > configs/scheduler_env.txt << EOF
ENV=prod
SCHEDULER_API_KEY=${{ secrets.SCHEDULER_API_KEY }}
EOF
- name: Create Server Config
run: |
cat > configs/server_env.txt << EOF
DJANGO_DEBUG=${{ secrets.DJANGO_DEBUG }}
DB_HOST=${{ secrets.DB_HOST }}
DB_NAME=${{ secrets.DB_NAME }}
DB_PORT=${{ secrets.DB_PORT }}
DB_USER=${{ secrets.DB_USER }}
DB_PASSWORD=${{ secrets.DB_PASSWORD }}
SENDGRID_API_KEY=${{ secrets.SENDGRID_API_KEY }}
SUPABASE_URL=${{ secrets.SUPABASE_URL }}
SUPABASE_KEY=${{ secrets.SUPABASE_KEY }}
INTERNSHIP_CHANNEL_ID=${{ secrets.INTERNSHIP_CHANNEL_ID }}
NEW_GRAD_CHANNEL_ID=${{ secrets.NEW_GRAD_CHANNEL_ID }}
METRIC_SERVER_URL=${{ secrets.METRIC_SERVER_URL }}
JWT_SECRET=${{ secrets.JWT_SECRET }}
AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_BUCKET_NAME=${{ secrets.AWS_BUCKET_NAME }}
RABBIT_HOST=${{ secrets.RABBIT_HOST }}
RABBIT_PORT=${{ secrets.RABBIT_PORT }}
RABBIT_VHOST=${{ secrets.RABBIT_VHOST }}
SERVER_RABBIT_USER=${{ secrets.SERVER_RABBIT_USER }}
SERVER_RABBIT_PASS=${{ secrets.SERVER_RABBIT_PASS }}
EOF
- name: Create Sockets Config
run: |
cat > configs/sockets_env.txt << EOF
DB_HOST=${{ secrets.DB_HOST }}
DB_NAME=${{ secrets.DB_NAME }}
DB_PORT=${{ secrets.DB_PORT }}
DB_USER=${{ secrets.DB_USER }}
DB_PASSWORD=${{ secrets.DB_PASSWORD }}
JWT_SECRET=${{ secrets.JWT_SECRET }}
SOCKET_RABBIT_USER=${{ secrets.SOCKET_RABBIT_USER }}
SOCKET_RABBIT_PASS=${{ secrets.SOCKET_RABBIT_PASS }}
RABBIT_HOST=${{ secrets.RABBIT_HOST }}
RABBIT_PORT=${{ secrets.RABBIT_PORT }}
RABBIT_VHOST=${{ secrets.RABBIT_VHOST }}
EOF
- name: Create AI Config
run: |
cat > configs/ai_env.txt << EOF
GEMINI_API_KEY=${{ secrets.GEMINI_API_KEY }}
AI_RABBIT_USER=${{ secrets.AI_RABBIT_USER }}
AI_RABBIT_PASS=${{ secrets.AI_RABBIT_PASS }}
AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_BUCKET_NAME=${{ secrets.AWS_BUCKET_NAME }}
EOF
- name: Extract and prepare configs for comparison
run: |
mkdir -p old_configs
mkdir -p normalized_configs
normalize_config() {
local input_file=$1
local output_file=$2
if [ ! -f "${input_file}.original" ]; then
cp "$input_file" "${input_file}.original"
fi
# remove empty lines, strip whitespace, sort
grep '=' "$input_file" | grep -v '^[[:space:]]*$' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sort > "$output_file"
}
extract_config() {
local config_name=$1
if docker config ls --filter name=$config_name -q | grep -q .; then
docker config inspect $config_name --pretty | sed -n '/Data:/,$ p' | sed '1d' > "old_configs/${config_name}.raw"
normalize_config "old_configs/${config_name}.raw" "normalized_configs/old_${config_name}.txt"
else
touch "normalized_configs/old_${config_name}.txt"
fi
}
extract_config "bot_env"
extract_config "chronos_env"
extract_config "scheduler_env"
extract_config "server_env"
extract_config "sockets_env"
extract_config "ai_env"
for config in configs/*.txt; do
filename=$(basename "$config")
normalize_config "$config" "normalized_configs/new_${filename}"
done
- name: Detect changes and update configs
id: config-changes
run: |
echo "SERVICES_TO_REDEPLOY=" > services_to_redeploy.txt
check_and_update_config() {
local config_name=$1
local old_normalized="normalized_configs/old_${config_name}.txt"
local new_normalized="normalized_configs/new_${config_name}.txt"
local original_config="configs/${config_name}.txt.original"
# Use diff with no output for exact comparison
if diff -q "$old_normalized" "$new_normalized" > /dev/null; then
echo "No changes detected for ${config_name}"
else
echo "${config_name} has changed, updating Docker config..."
echo "Differences found:"
diff "$old_normalized" "$new_normalized" || true
if docker config ls --filter name=$config_name -q | grep -q .; then
docker config rm $config_name
fi
docker config create $config_name "$original_config"
if grep -q "SERVICES_TO_REDEPLOY=$" services_to_redeploy.txt; then
sed -i "s/SERVICES_TO_REDEPLOY=/SERVICES_TO_REDEPLOY=${config_name}/" services_to_redeploy.txt
else
sed -i "s/SERVICES_TO_REDEPLOY=/SERVICES_TO_REDEPLOY=${config_name},/" services_to_redeploy.txt
fi
fi
}
check_and_update_config "bot_env"
check_and_update_config "chronos_env"
check_and_update_config "scheduler_env"
check_and_update_config "server_env"
check_and_update_config "sockets_env"
check_and_update_config "ai_env"
source services_to_redeploy.txt
if [ -n "$SERVICES_TO_REDEPLOY" ]; then
echo "Services to redeploy: $SERVICES_TO_REDEPLOY"
echo "CONFIG_CHANGED=true" >> $GITHUB_OUTPUT
echo "SERVICES=$SERVICES_TO_REDEPLOY" >> $GITHUB_OUTPUT
else
echo "No config changes detected"
echo "CONFIG_CHANGED=false" >> $GITHUB_OUTPUT
fi
- name: Trigger Service Workflows
if: steps.config-changes.outputs.CONFIG_CHANGED == 'true'
run: |
trigger_workflow() {
local config_name=$1
local repo=$2
local workflow=$3
echo "Triggering workflow with new config: $config_name in repository $repo using workflow $workflow"
curl -X POST \
-H "Authorization: token ${{ secrets.GH_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$repo/actions/workflows/$workflow/dispatches" \
-d '{"ref":"main"}'
# avoid rate limiting
sleep 2
}
CHANGED_SERVICES="${{ steps.config-changes.outputs.SERVICES }}"
# TODO(elimelt): update workflow names
if [[ "$CHANGED_SERVICES" == *"bot_env"* ]]; then
trigger_workflow "bot_env" "swecc-uw/swecc-bot" "deploy.yml"
fi
if [[ "$CHANGED_SERVICES" == *"chronos_env"* ]]; then
trigger_workflow "chronos_env" "swecc-uw/swecc-chronos" "deploy.yml"
fi
if [[ "$CHANGED_SERVICES" == *"scheduler_env"* ]]; then
trigger_workflow "scheduler_env" "swecc-uw/swecc-scheduler" "deploy.yml"
fi
if [[ "$CHANGED_SERVICES" == *"server_env"* ]]; then
trigger_workflow "server_env" "swecc-uw/swecc-server" "deploy.yml"
fi
if [[ "$CHANGED_SERVICES" == *"sockets_env"* ]]; then
trigger_workflow "sockets_env" "swecc-uw/swecc-sockets" "deploy.yml"
fi
if [[ "$CHANGED_SERVICES" == *"ai_env"* ]]; then
trigger_workflow "ai_env" "swecc-uw/swecc-ai" "deploy.yml"
fi