5.3 KiB
Generated 2026-05-21 at base-sha 5399a5ddc36b. Type: top-level. 4 sources.
Deploy flow
The deploy phase is owned by deployArgoCD.groovy (the ArgoCD ceremony) and deployRingmaster.groovy (the callback to the higher-level deploy controllers). Two things to never mess with: the four-step order, and the canary gate.
The four-step ArgoCD ceremony — load-bearing
deployArgoCD.run() (lines 73-107) calls these in strict order:
1. update_argo_repo (line 91) pushes the ArgoApplication YAML into devops-argo-config
so the app-of-apps registry sees the new app.
2. refresh_app_of_apps (line 94) argocd app sync ${appofapps} — materialises the new
Application object before the per-service sync needs it.
3. update_helm_repo (line 97) computes xms/xmx, renders values.yaml, pushes into
devops-helm-charts.
4. refresh_and_sync (line 100) argocd app sync ${app_name} --hard-refresh — the
actual service rollout. Uses --http-retry-max 3
--retry-backoff-duration 1m (lines 506, 526).
Steps 2 and 4 are not interchangeable. On first-deploy of a brand-new service, the Application object doesn't exist yet — step 2 creates it (as a downstream effect of the app-of-apps sync), step 4 reads it. Swap the order and step 4 fails on a missing Application. See docs/tribal-knowledge.md §10 for the post-incident note.
JVM memory auto-calculation
update_helm_repo (lines 220-255) derives JVM memory flags from the pod's memory_limit:
memory_value = memory_limit * 0.5
xms = "${memory_value}M"
xmx = "${memory_value}M"
Both flags are set equal, derived from memory_limit (not memory_request), with no 0.75 multiplier and no 64m rounding. The historical claim "xmx = memory_request * 0.75, xms = xmx * 0.5" was wrong and has been reconciled out of docs/tribal-knowledge.md.
Do not hard-code -Xmx in JAVA_OPTS — the auto-computed value will collide with it, and the last value seen by the JVM wins depending on arg order. There is no jvm_memory_override flag (that referenced flag does not exist in code).
Canary enforcement — sp0 / up0 in prd
enforceCanary = (priority_v2 ∈ {sp0, up0})
∧ (envrn == 'prd')
∧ ¬(service is canary | cron | worker | scheduler | consumer | node | headless)
When enforceCanary is true, the deploy hard-errors unless the Helm values declare:
canary.enabled = truecanary.skipAnalysis = falsecanary.enableManualPromotion = true
There is no whitelist and no bypass flag. A service that needs to skip canary on a high-priority prd path has to either (a) be classified out of sp0/up0, or (b) match one of the exempted service types listed above.
Ringmaster vs Turbo-Turtle routing
deployRingmaster.groovy:55-89:
def build_user = currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId()
if (build_user == "ringmaster-bot") {
callApi(url, header, jsonData) // → ringmaster endpoint
} else {
// → http://turbo-turtle.meeshogcp.in (line 71)
// http://turbo-turtle.admin.meeshogcp.in (line 74)
sh "curl -s -X POST -H '$newCICD_Header' -w '\\n%{response_code}' $newCICD_URL -d '$newCICD_JSON'"
}
The string "ringmaster-bot" is a load-bearing constant. Renaming the bot user silently routes every Ringmaster callback to Turbo-Turtle, which rejects them.
The JSON payload is passed inline via -d '$newCICD_JSON' (line 80). Earlier documentation claimed a temp-file + curl -d @<file> pattern with finally-block cleanup — that pattern does not exist in the current code and was reconciled out of docs/tribal-knowledge.md.
Deployment-tracker callback (notify.groovy)
notify.groovy:108-152 POSTs to one of:
http://deployment-tracker.meeshoint.in/api/1.0/deployment-tracker/jenkins/create(AWS)http://deployment-tracker.prd.meesho.int/api/1.0/deployment-tracker/jenkins/create(GCP)
Only triggered on branches main / master / gcp-main / gcp-master (line 34). Payload includes repository, team, link, job_name, tag, status, commit_id, error_msg. No retry — a single failed POST means the dashboard miscounts that deploy.
See also: 05-cross-cutting, concepts/whitelists, docs/tribal-knowledge.md.