Skip to content

Commit 279869e

Browse files
committed
chore: split production deploy into ru and eu workflows
1 parent 138b7ab commit 279869e

9 files changed

Lines changed: 563 additions & 51 deletions

File tree

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
name: Deploy production EU
2+
3+
on:
4+
push:
5+
branches:
6+
- chore/prod-split-ru-eu
7+
paths:
8+
- '.github/workflows/deploy-production-ru.yml'
9+
- '.github/workflows/deploy-production-eu.yml'
10+
- '.github/workflows/deploy.yml'
11+
- '.helm/**'
12+
workflow_dispatch:
13+
inputs:
14+
mode:
15+
description: "Run mode"
16+
required: true
17+
default: preflight
18+
type: choice
19+
options:
20+
- preflight
21+
- deploy
22+
23+
env:
24+
RUN_MODE: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.mode || 'preflight' }}
25+
WERF_ENV: "production"
26+
WERF_REPO: "ghcr.io/${{ github.repository_owner }}/werfio-guides"
27+
WERF_STAGES_STORAGE: "ghcr.io/werf/werfio-guides-stages"
28+
WERF_SET_ACTIVE_RELEASE: "global.active_release=2"
29+
WERFIO_GITHUB_TOKEN: "${{ secrets.API_TOKEN }}"
30+
VAULT_ADDR: "https://seguro.flant.com"
31+
VAULT_ROLE: "werf-web"
32+
EU_KUBECONFIG_SECRET_PATH: "projects/data/b454e6aa-39f0-45f4-aa7c-a9465ab154cb/KUBE_CONFIG"
33+
34+
jobs:
35+
converge-eu:
36+
name: Deploy EU to old cluster
37+
runs-on: prod-github-runner-0
38+
permissions:
39+
contents: read
40+
id-token: write
41+
packages: write
42+
steps:
43+
- name: Checkout code
44+
uses: actions/checkout@v4
45+
with:
46+
fetch-depth: 0
47+
48+
- name: Checkout werf repo
49+
uses: actions/checkout@v4
50+
with:
51+
repository: werf/werf
52+
path: werf
53+
fetch-depth: 0
54+
55+
- name: Inject trdl_channels.yaml
56+
run: |
57+
cp werf/trdl_channels.yaml .helm/trdl_channels.yaml
58+
59+
- name: Install werf
60+
uses: werf/actions/install@v2
61+
62+
- name: Request GitHub OIDC token
63+
id: oidc
64+
run: |
65+
set -euo pipefail
66+
oidc_token="$({ curl -fsSL \
67+
-H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
68+
"${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=github-access-aud"; } | jq -r '.value')"
69+
70+
if [[ -z "$oidc_token" || "$oidc_token" == "null" ]]; then
71+
echo "Failed to get GitHub OIDC token" >&2
72+
exit 1
73+
fi
74+
75+
echo "::add-mask::$oidc_token"
76+
echo "token=$oidc_token" >> "$GITHUB_OUTPUT"
77+
78+
- name: Login to Seguro
79+
id: seguro
80+
run: |
81+
set -euo pipefail
82+
vault_token="$({ curl -fsSL \
83+
-X POST \
84+
-H 'Content-Type: application/json' \
85+
"$VAULT_ADDR/v1/auth/github/login" \
86+
-d "{\"role\":\"$VAULT_ROLE\",\"jwt\":\"${{ steps.oidc.outputs.token }}\"}"; } | jq -r '.auth.client_token')"
87+
88+
if [[ -z "$vault_token" || "$vault_token" == "null" ]]; then
89+
echo "Failed to get Vault token from Seguro" >&2
90+
exit 1
91+
fi
92+
93+
echo "::add-mask::$vault_token"
94+
echo "token=$vault_token" >> "$GITHUB_OUTPUT"
95+
96+
- name: Read EU kubeconfig from Seguro
97+
id: eu_kubeconfig
98+
run: |
99+
set -euo pipefail
100+
101+
response="$(curl -fsSL -H "X-Vault-Token: ${{ steps.seguro.outputs.token }}" "$VAULT_ADDR/v1/$EU_KUBECONFIG_SECRET_PATH")"
102+
field_count="$(printf '%s' "$response" | jq -r '.data.data | keys | length')"
103+
104+
if [[ "$field_count" == "0" || "$field_count" == "null" ]]; then
105+
echo "EU kubeconfig secret is empty" >&2
106+
exit 1
107+
fi
108+
109+
if [[ "$field_count" -ne 1 ]]; then
110+
echo "Expected exactly one field in EU kubeconfig secret, got: $(printf '%s' "$response" | jq -r '.data.data | keys | join(", ")')" >&2
111+
exit 1
112+
fi
113+
114+
secret_key="$(printf '%s' "$response" | jq -r '.data.data | keys[0]')"
115+
secret_value="$(printf '%s' "$response" | jq -r --arg k "$secret_key" '.data.data[$k]')"
116+
117+
if [[ -z "$secret_value" || "$secret_value" == "null" ]]; then
118+
echo "EU kubeconfig secret field '$secret_key' is empty" >&2
119+
exit 1
120+
fi
121+
122+
if printf '%s' "$secret_value" | base64 -d >/tmp/eu-kubeconfig-decoded 2>/dev/null && grep -q '^apiVersion:' /tmp/eu-kubeconfig-decoded; then
123+
kubeconfig_base64="$secret_value"
124+
else
125+
kubeconfig_base64="$(printf '%s' "$secret_value" | base64 | tr -d '\n')"
126+
fi
127+
128+
echo "::add-mask::$kubeconfig_base64"
129+
echo "field=$secret_key" >> "$GITHUB_OUTPUT"
130+
echo "kubeconfig_base64=$kubeconfig_base64" >> "$GITHUB_OUTPUT"
131+
132+
- name: Check EU cluster access
133+
env:
134+
WERF_KUBE_CONFIG_BASE64: ${{ steps.eu_kubeconfig.outputs.kubeconfig_base64 }}
135+
run: |
136+
set -euo pipefail
137+
. $(werf ci-env github --as-file)
138+
139+
missing_requirements=0
140+
141+
echo "== cluster-info =="
142+
werf kubectl cluster-info
143+
144+
echo "== namespace =="
145+
if werf kubectl get ns werfio-production >/dev/null 2>&1; then
146+
echo "Namespace werfio-production exists"
147+
else
148+
echo "Namespace werfio-production is missing"
149+
missing_requirements=1
150+
fi
151+
152+
echo "== priorityclass =="
153+
if werf kubectl get priorityclass production-medium >/dev/null 2>&1; then
154+
echo "PriorityClass production-medium exists"
155+
else
156+
echo "PriorityClass production-medium is missing"
157+
missing_requirements=1
158+
fi
159+
160+
echo "== can-i =="
161+
werf kubectl auth can-i get pods -n werfio-production
162+
werf kubectl auth can-i get ingress -n werfio-production
163+
werf kubectl auth can-i create deployment.apps -n werfio-production
164+
165+
echo "== image pull secret =="
166+
if werf kubectl -n werfio-production get secret github-werfio >/dev/null 2>&1; then
167+
echo "Secret github-werfio exists in werfio-production"
168+
else
169+
echo "Secret github-werfio is missing in werfio-production"
170+
missing_requirements=1
171+
fi
172+
173+
echo "== existing resources =="
174+
werf kubectl -n werfio-production get deploy,svc,ingress,pdb || true
175+
176+
if [[ "$missing_requirements" -ne 0 ]]; then
177+
echo "EU cluster access works, but required bootstrap objects are missing" >&2
178+
exit 1
179+
fi
180+
181+
- name: Render EU manifests
182+
env:
183+
WERF_KUBE_CONFIG_BASE64: ${{ steps.eu_kubeconfig.outputs.kubeconfig_base64 }}
184+
run: |
185+
set -euo pipefail
186+
. $(werf ci-env github --as-file)
187+
werf render --dev --env production --without-images --stub-tags --ignore-secret-key --set global.targetCluster=eu >/tmp/werf-render-eu.yaml
188+
189+
echo "Rendered EU objects summary:"
190+
grep '^kind:' /tmp/werf-render-eu.yaml | sort | uniq -c | cat
191+
192+
- name: Deploy EU to old cluster
193+
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.mode == 'deploy' }}
194+
run: |
195+
. $(werf ci-env github --as-file)
196+
werf converge --set global.targetCluster=eu
197+
env:
198+
WERF_NAMESPACE: "werfio-production"
199+
WERF_RELEASE: "werfio-site-production"
200+
WERF_LOG_VERBOSE: "on"
201+
WERF_ENV: "production"
202+
WERF_KUBE_CONFIG_BASE64: ${{ steps.eu_kubeconfig.outputs.kubeconfig_base64 }}
203+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
204+
205+
- name: Summary
206+
run: |
207+
cat <<EOF >> "$GITHUB_STEP_SUMMARY"
208+
## EU deploy
209+
210+
- Event: ${{ github.event_name }}
211+
- Mode: $RUN_MODE
212+
- Target cluster mode: eu
213+
- Seguro role: $VAULT_ROLE
214+
- Secret path: $EU_KUBECONFIG_SECRET_PATH
215+
- Secret field used: ${{ steps.eu_kubeconfig.outputs.field }}
216+
- Helm switch: global.targetCluster=eu
217+
218+
If mode is preflight, no converge was executed.
219+
This workflow targets the old cluster and is intended to keep only the EU version there.
220+
EOF
221+

0 commit comments

Comments
 (0)