Skip to content

Localize order id notifications #75

Localize order id notifications

Localize order id notifications #75

name: Sync Cloud Run Env
on:
push:
branches: [ main ]
env:
GCP_PROJECT_ID: longbridgequant
GCP_WORKLOAD_IDENTITY_PROVIDER: projects/252919773759/locations/global/workloadIdentityPools/github-actions/providers/github-main
GCP_WORKLOAD_IDENTITY_SERVICE_ACCOUNT: longbridge-platform-deploy@longbridgequant.iam.gserviceaccount.com
jobs:
sync-hk:
name: Sync HK Cloud Run Env
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
environment: longbridge-hk
env:
ENABLE_GITHUB_ENV_SYNC: ${{ vars.ENABLE_GITHUB_ENV_SYNC }}
# Set CLOUD_RUN_REGION per Environment so HK/SG can target different regions.
CLOUD_RUN_REGION: ${{ vars.CLOUD_RUN_REGION }}
CLOUD_RUN_SERVICE: ${{ vars.CLOUD_RUN_SERVICE }}
ACCOUNT_PREFIX: ${{ vars.ACCOUNT_PREFIX }}
TELEGRAM_TOKEN_SECRET_NAME: ${{ vars.TELEGRAM_TOKEN_SECRET_NAME }}
LONGPORT_APP_KEY_SECRET_NAME: ${{ vars.LONGPORT_APP_KEY_SECRET_NAME }}
LONGPORT_APP_SECRET_SECRET_NAME: ${{ vars.LONGPORT_APP_SECRET_SECRET_NAME }}
STRATEGY_PROFILE: ${{ vars.STRATEGY_PROFILE || 'soxl_soxx_trend_income' }}
ACCOUNT_REGION: ${{ vars.ACCOUNT_REGION || 'HK' }}
LONGPORT_SECRET_NAME: ${{ vars.LONGPORT_SECRET_NAME }}
LONGBRIDGE_FEATURE_SNAPSHOT_PATH: ${{ vars.LONGBRIDGE_FEATURE_SNAPSHOT_PATH }}
LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH: ${{ vars.LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH }}
LONGBRIDGE_STRATEGY_CONFIG_PATH: ${{ vars.LONGBRIDGE_STRATEGY_CONFIG_PATH }}
NOTIFY_LANG: ${{ vars.NOTIFY_LANG }}
EXECUTION_REPORT_GCS_URI: ${{ vars.EXECUTION_REPORT_GCS_URI }}
LONGBRIDGE_DRY_RUN_ONLY: ${{ vars.LONGBRIDGE_DRY_RUN_ONLY }}
GLOBAL_TELEGRAM_CHAT_ID: ${{ vars.GLOBAL_TELEGRAM_CHAT_ID }}
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
steps:
- name: Check whether env sync is configured
id: config
run: |
set -euo pipefail
if [ "${ENABLE_GITHUB_ENV_SYNC:-}" != "true" ]; then
echo "enabled=false" >> "$GITHUB_OUTPUT"
echo "Skipping HK Cloud Run env sync because ENABLE_GITHUB_ENV_SYNC is not set to true." >&2
exit 0
fi
required_vars=(
CLOUD_RUN_REGION
CLOUD_RUN_SERVICE
ACCOUNT_PREFIX
LONGPORT_SECRET_NAME
NOTIFY_LANG
GLOBAL_TELEGRAM_CHAT_ID
)
missing_vars=()
for var_name in "${required_vars[@]}"; do
if [ -z "${!var_name:-}" ]; then
missing_vars+=("${var_name}")
fi
done
if [ -z "${TELEGRAM_TOKEN_SECRET_NAME:-}" ] && [ -z "${TELEGRAM_TOKEN:-}" ]; then
missing_vars+=("TELEGRAM_TOKEN_SECRET_NAME or TELEGRAM_TOKEN")
fi
if [ -z "${LONGPORT_APP_KEY_SECRET_NAME:-}" ]; then
missing_vars+=("LONGPORT_APP_KEY_SECRET_NAME")
fi
if [ -z "${LONGPORT_APP_SECRET_SECRET_NAME:-}" ]; then
missing_vars+=("LONGPORT_APP_SECRET_SECRET_NAME")
fi
if { [ "${STRATEGY_PROFILE:-}" = "tech_communication_pullback_enhancement" ] || [ "${STRATEGY_PROFILE:-}" = "qqq_tech_enhancement" ]; } && [ -z "${LONGBRIDGE_FEATURE_SNAPSHOT_PATH:-}" ]; then
missing_vars+=("LONGBRIDGE_FEATURE_SNAPSHOT_PATH")
fi
if [ "${#missing_vars[@]}" -gt 0 ]; then
echo "enabled=false" >> "$GITHUB_OUTPUT"
echo "HK Cloud Run env sync is enabled, but these values are missing:" >&2
echo " - If HK and SG run in different regions, set CLOUD_RUN_REGION on the longbridge-hk Environment." >&2
echo " - Set LONGPORT_APP_KEY_SECRET_NAME and LONGPORT_APP_SECRET_SECRET_NAME on the longbridge-hk Environment so HK does not fall back to shared repository defaults." >&2
printf ' - %s\n' "${missing_vars[@]}" >&2
exit 1
fi
echo "enabled=true" >> "$GITHUB_OUTPUT"
- name: Authenticate to Google Cloud
id: auth
if: steps.config.outputs.enabled == 'true'
uses: google-github-actions/auth@v3
with:
workload_identity_provider: ${{ env.GCP_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ env.GCP_WORKLOAD_IDENTITY_SERVICE_ACCOUNT }}
- name: Set up gcloud
if: steps.config.outputs.enabled == 'true'
uses: google-github-actions/setup-gcloud@v3
with:
project_id: ${{ env.GCP_PROJECT_ID }}
version: ">= 416.0.0"
- name: Wait for Cloud Run deployment of current commit
if: steps.config.outputs.enabled == 'true'
run: |
set -euo pipefail
target_sha="${GITHUB_SHA}"
deadline=$((SECONDS + 1800))
while true; do
deployed_sha="$(gcloud run services describe "${CLOUD_RUN_SERVICE}" --region "${CLOUD_RUN_REGION}" --format='value(spec.template.metadata.labels.commit-sha)' 2>/dev/null || true)"
if [ -n "${deployed_sha}" ] && [ "${deployed_sha}" = "${target_sha}" ]; then
echo "Cloud Run service ${CLOUD_RUN_SERVICE} is on commit ${deployed_sha}."
break
fi
if [ "${SECONDS}" -ge "${deadline}" ]; then
echo "Timed out waiting for Cloud Run service ${CLOUD_RUN_SERVICE} to deploy commit ${target_sha}. Last seen commit: ${deployed_sha:-<none>}" >&2
exit 1
fi
echo "Waiting for Cloud Run service ${CLOUD_RUN_SERVICE} to deploy commit ${target_sha}. Last seen commit: ${deployed_sha:-<none>}" >&2
sleep 10
done
- name: Sync Cloud Run environment
if: steps.config.outputs.enabled == 'true'
run: |
set -euo pipefail
env_pairs=(
"GLOBAL_TELEGRAM_CHAT_ID=${GLOBAL_TELEGRAM_CHAT_ID}"
"NOTIFY_LANG=${NOTIFY_LANG}"
"LONGPORT_SECRET_NAME=${LONGPORT_SECRET_NAME}"
"ACCOUNT_PREFIX=${ACCOUNT_PREFIX}"
"STRATEGY_PROFILE=${STRATEGY_PROFILE}"
"ACCOUNT_REGION=${ACCOUNT_REGION}"
)
secret_pairs=()
remove_env_vars=(
"TELEGRAM_CHAT_ID"
"SERVICE_NAME"
)
remove_secret_vars=()
if [ -n "${TELEGRAM_TOKEN_SECRET_NAME:-}" ]; then
secret_pairs+=("TELEGRAM_TOKEN=${TELEGRAM_TOKEN_SECRET_NAME}:latest")
remove_env_vars+=("TELEGRAM_TOKEN")
else
env_pairs+=("TELEGRAM_TOKEN=${TELEGRAM_TOKEN}")
remove_secret_vars+=("TELEGRAM_TOKEN")
fi
secret_pairs+=("LONGPORT_APP_KEY=${LONGPORT_APP_KEY_SECRET_NAME}:latest")
remove_env_vars+=("LONGPORT_APP_KEY")
secret_pairs+=("LONGPORT_APP_SECRET=${LONGPORT_APP_SECRET_SECRET_NAME}:latest")
remove_env_vars+=("LONGPORT_APP_SECRET")
if [ -n "${EXECUTION_REPORT_GCS_URI:-}" ]; then
env_pairs+=("EXECUTION_REPORT_GCS_URI=${EXECUTION_REPORT_GCS_URI}")
else
remove_env_vars+=("EXECUTION_REPORT_GCS_URI")
fi
if [ -n "${LONGBRIDGE_FEATURE_SNAPSHOT_PATH:-}" ]; then
env_pairs+=("LONGBRIDGE_FEATURE_SNAPSHOT_PATH=${LONGBRIDGE_FEATURE_SNAPSHOT_PATH}")
else
remove_env_vars+=("LONGBRIDGE_FEATURE_SNAPSHOT_PATH")
fi
if [ -n "${LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH:-}" ]; then
env_pairs+=("LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH=${LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH}")
else
remove_env_vars+=("LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH")
fi
if [ -n "${LONGBRIDGE_STRATEGY_CONFIG_PATH:-}" ]; then
env_pairs+=("LONGBRIDGE_STRATEGY_CONFIG_PATH=${LONGBRIDGE_STRATEGY_CONFIG_PATH}")
else
remove_env_vars+=("LONGBRIDGE_STRATEGY_CONFIG_PATH")
fi
if [ -n "${LONGBRIDGE_DRY_RUN_ONLY:-}" ]; then
env_pairs+=("LONGBRIDGE_DRY_RUN_ONLY=${LONGBRIDGE_DRY_RUN_ONLY}")
else
remove_env_vars+=("LONGBRIDGE_DRY_RUN_ONLY")
fi
gcloud_args=(
run services update "${CLOUD_RUN_SERVICE}"
--region "${CLOUD_RUN_REGION}"
--remove-env-vars "$(IFS=,; echo "${remove_env_vars[*]}")"
--update-env-vars "$(IFS=,; echo "${env_pairs[*]}")"
)
if [ "${#remove_secret_vars[@]}" -gt 0 ]; then
gcloud_args+=(--remove-secrets "$(IFS=,; echo "${remove_secret_vars[*]}")")
fi
if [ "${#secret_pairs[@]}" -gt 0 ]; then
gcloud_args+=(--update-secrets "$(IFS=,; echo "${secret_pairs[*]}")")
fi
gcloud "${gcloud_args[@]}"
sync-sg:
name: Sync SG Cloud Run Env
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
environment: longbridge-sg
env:
ENABLE_GITHUB_ENV_SYNC: ${{ vars.ENABLE_GITHUB_ENV_SYNC }}
# Set CLOUD_RUN_REGION per Environment so HK/SG can target different regions.
CLOUD_RUN_REGION: ${{ vars.CLOUD_RUN_REGION }}
CLOUD_RUN_SERVICE: ${{ vars.CLOUD_RUN_SERVICE }}
ACCOUNT_PREFIX: ${{ vars.ACCOUNT_PREFIX }}
TELEGRAM_TOKEN_SECRET_NAME: ${{ vars.TELEGRAM_TOKEN_SECRET_NAME }}
LONGPORT_APP_KEY_SECRET_NAME: ${{ vars.LONGPORT_APP_KEY_SECRET_NAME }}
LONGPORT_APP_SECRET_SECRET_NAME: ${{ vars.LONGPORT_APP_SECRET_SECRET_NAME }}
STRATEGY_PROFILE: ${{ vars.STRATEGY_PROFILE || 'soxl_soxx_trend_income' }}
ACCOUNT_REGION: ${{ vars.ACCOUNT_REGION || 'SG' }}
LONGPORT_SECRET_NAME: ${{ vars.LONGPORT_SECRET_NAME }}
LONGBRIDGE_FEATURE_SNAPSHOT_PATH: ${{ vars.LONGBRIDGE_FEATURE_SNAPSHOT_PATH }}
LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH: ${{ vars.LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH }}
LONGBRIDGE_STRATEGY_CONFIG_PATH: ${{ vars.LONGBRIDGE_STRATEGY_CONFIG_PATH }}
NOTIFY_LANG: ${{ vars.NOTIFY_LANG }}
EXECUTION_REPORT_GCS_URI: ${{ vars.EXECUTION_REPORT_GCS_URI }}
LONGBRIDGE_DRY_RUN_ONLY: ${{ vars.LONGBRIDGE_DRY_RUN_ONLY }}
GLOBAL_TELEGRAM_CHAT_ID: ${{ vars.GLOBAL_TELEGRAM_CHAT_ID }}
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
steps:
- name: Check whether env sync is configured
id: config
run: |
set -euo pipefail
if [ "${ENABLE_GITHUB_ENV_SYNC:-}" != "true" ]; then
echo "enabled=false" >> "$GITHUB_OUTPUT"
echo "Skipping SG Cloud Run env sync because ENABLE_GITHUB_ENV_SYNC is not set to true." >&2
exit 0
fi
required_vars=(
CLOUD_RUN_REGION
CLOUD_RUN_SERVICE
ACCOUNT_PREFIX
LONGPORT_SECRET_NAME
NOTIFY_LANG
GLOBAL_TELEGRAM_CHAT_ID
)
missing_vars=()
for var_name in "${required_vars[@]}"; do
if [ -z "${!var_name:-}" ]; then
missing_vars+=("${var_name}")
fi
done
if [ -z "${TELEGRAM_TOKEN_SECRET_NAME:-}" ] && [ -z "${TELEGRAM_TOKEN:-}" ]; then
missing_vars+=("TELEGRAM_TOKEN_SECRET_NAME or TELEGRAM_TOKEN")
fi
if [ -z "${LONGPORT_APP_KEY_SECRET_NAME:-}" ]; then
missing_vars+=("LONGPORT_APP_KEY_SECRET_NAME")
fi
if [ -z "${LONGPORT_APP_SECRET_SECRET_NAME:-}" ]; then
missing_vars+=("LONGPORT_APP_SECRET_SECRET_NAME")
fi
if { [ "${STRATEGY_PROFILE:-}" = "tech_communication_pullback_enhancement" ] || [ "${STRATEGY_PROFILE:-}" = "qqq_tech_enhancement" ]; } && [ -z "${LONGBRIDGE_FEATURE_SNAPSHOT_PATH:-}" ]; then
missing_vars+=("LONGBRIDGE_FEATURE_SNAPSHOT_PATH")
fi
if [ "${#missing_vars[@]}" -gt 0 ]; then
echo "enabled=false" >> "$GITHUB_OUTPUT"
echo "SG Cloud Run env sync is enabled, but these values are missing:" >&2
echo " - If HK and SG run in different regions, set CLOUD_RUN_REGION on the longbridge-sg Environment." >&2
echo " - Set LONGPORT_APP_KEY_SECRET_NAME and LONGPORT_APP_SECRET_SECRET_NAME on the longbridge-sg Environment so SG does not fall back to shared repository defaults." >&2
printf ' - %s\n' "${missing_vars[@]}" >&2
exit 1
fi
echo "enabled=true" >> "$GITHUB_OUTPUT"
- name: Authenticate to Google Cloud
id: auth
if: steps.config.outputs.enabled == 'true'
uses: google-github-actions/auth@v3
with:
workload_identity_provider: ${{ env.GCP_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ env.GCP_WORKLOAD_IDENTITY_SERVICE_ACCOUNT }}
- name: Set up gcloud
if: steps.config.outputs.enabled == 'true'
uses: google-github-actions/setup-gcloud@v3
with:
project_id: ${{ env.GCP_PROJECT_ID }}
version: ">= 416.0.0"
- name: Wait for Cloud Run deployment of current commit
if: steps.config.outputs.enabled == 'true'
run: |
set -euo pipefail
target_sha="${GITHUB_SHA}"
deadline=$((SECONDS + 1800))
while true; do
deployed_sha="$(gcloud run services describe "${CLOUD_RUN_SERVICE}" --region "${CLOUD_RUN_REGION}" --format='value(spec.template.metadata.labels.commit-sha)' 2>/dev/null || true)"
if [ -n "${deployed_sha}" ] && [ "${deployed_sha}" = "${target_sha}" ]; then
echo "Cloud Run service ${CLOUD_RUN_SERVICE} is on commit ${deployed_sha}."
break
fi
if [ "${SECONDS}" -ge "${deadline}" ]; then
echo "Timed out waiting for Cloud Run service ${CLOUD_RUN_SERVICE} to deploy commit ${target_sha}. Last seen commit: ${deployed_sha:-<none>}" >&2
exit 1
fi
echo "Waiting for Cloud Run service ${CLOUD_RUN_SERVICE} to deploy commit ${target_sha}. Last seen commit: ${deployed_sha:-<none>}" >&2
sleep 10
done
- name: Sync Cloud Run environment
if: steps.config.outputs.enabled == 'true'
run: |
set -euo pipefail
env_pairs=(
"GLOBAL_TELEGRAM_CHAT_ID=${GLOBAL_TELEGRAM_CHAT_ID}"
"NOTIFY_LANG=${NOTIFY_LANG}"
"LONGPORT_SECRET_NAME=${LONGPORT_SECRET_NAME}"
"ACCOUNT_PREFIX=${ACCOUNT_PREFIX}"
"STRATEGY_PROFILE=${STRATEGY_PROFILE}"
"ACCOUNT_REGION=${ACCOUNT_REGION}"
)
secret_pairs=()
remove_env_vars=(
"TELEGRAM_CHAT_ID"
"SERVICE_NAME"
)
remove_secret_vars=()
if [ -n "${TELEGRAM_TOKEN_SECRET_NAME:-}" ]; then
secret_pairs+=("TELEGRAM_TOKEN=${TELEGRAM_TOKEN_SECRET_NAME}:latest")
remove_env_vars+=("TELEGRAM_TOKEN")
else
env_pairs+=("TELEGRAM_TOKEN=${TELEGRAM_TOKEN}")
remove_secret_vars+=("TELEGRAM_TOKEN")
fi
secret_pairs+=("LONGPORT_APP_KEY=${LONGPORT_APP_KEY_SECRET_NAME}:latest")
remove_env_vars+=("LONGPORT_APP_KEY")
secret_pairs+=("LONGPORT_APP_SECRET=${LONGPORT_APP_SECRET_SECRET_NAME}:latest")
remove_env_vars+=("LONGPORT_APP_SECRET")
if [ -n "${EXECUTION_REPORT_GCS_URI:-}" ]; then
env_pairs+=("EXECUTION_REPORT_GCS_URI=${EXECUTION_REPORT_GCS_URI}")
else
remove_env_vars+=("EXECUTION_REPORT_GCS_URI")
fi
if [ -n "${LONGBRIDGE_FEATURE_SNAPSHOT_PATH:-}" ]; then
env_pairs+=("LONGBRIDGE_FEATURE_SNAPSHOT_PATH=${LONGBRIDGE_FEATURE_SNAPSHOT_PATH}")
else
remove_env_vars+=("LONGBRIDGE_FEATURE_SNAPSHOT_PATH")
fi
if [ -n "${LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH:-}" ]; then
env_pairs+=("LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH=${LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH}")
else
remove_env_vars+=("LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH")
fi
if [ -n "${LONGBRIDGE_STRATEGY_CONFIG_PATH:-}" ]; then
env_pairs+=("LONGBRIDGE_STRATEGY_CONFIG_PATH=${LONGBRIDGE_STRATEGY_CONFIG_PATH}")
else
remove_env_vars+=("LONGBRIDGE_STRATEGY_CONFIG_PATH")
fi
if [ -n "${LONGBRIDGE_DRY_RUN_ONLY:-}" ]; then
env_pairs+=("LONGBRIDGE_DRY_RUN_ONLY=${LONGBRIDGE_DRY_RUN_ONLY}")
else
remove_env_vars+=("LONGBRIDGE_DRY_RUN_ONLY")
fi
gcloud_args=(
run services update "${CLOUD_RUN_SERVICE}"
--region "${CLOUD_RUN_REGION}"
--remove-env-vars "$(IFS=,; echo "${remove_env_vars[*]}")"
--update-env-vars "$(IFS=,; echo "${env_pairs[*]}")"
)
if [ "${#remove_secret_vars[@]}" -gt 0 ]; then
gcloud_args+=(--remove-secrets "$(IFS=,; echo "${remove_secret_vars[*]}")")
fi
if [ "${#secret_pairs[@]}" -gt 0 ]; then
gcloud_args+=(--update-secrets "$(IFS=,; echo "${secret_pairs[*]}")")
fi
gcloud "${gcloud_args[@]}"