Repository navigation
233 lines (217 loc) · 10 KB
/
Copy pathcd-dev.yml
File metadata and controls
233 lines (217 loc) · 10 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
name: CI/CD using github actions & docker
on:
workflow_dispatch:
inputs:
counter_phase:
description: Audit or apply the durable counter snapshot and hourly Neon checkpoint
type: choice
options: ['', audit, apply, checkpoint]
default: ''
rehome_phase:
description: Stage, activate, or verify the reviewed Neon project migration
type: choice
options: ['', prepare, apply, verify]
default: ''
audit_only:
description: Inspect backend versions and worker settings without deploying
type: boolean
default: false
rollout_idle:
description: Deploy the immutable wake-on-work image to dev, latest and stable (requires stage_only)
type: boolean
default: false
image_revision:
description: Reuse an already built immutable revision for rollout_idle
type: string
default: ''
publish_idle_revision:
description: Publish aliases for an immutable revision already verified on all three backends
type: string
default: ''
stage_only:
description: Build an immutable image without deploying
type: boolean
default: false
push:
branches:
- develop
permissions:
contents: read
jobs:
push_to_registry:
if: ${{ !inputs.audit_only && !inputs.publish_idle_revision && !inputs.image_revision && !inputs.rehome_phase && !inputs.counter_phase }}
name: Push to aws container registry
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'corretto'
- name: make application-prod.yml
if: inputs.stage_only || contains(github.ref, 'develop') || contains(github.ref, 'main')
run: |
cd ./src/main/resources
touch ./application-prod.yml
echo "${{ secrets.YML_PROD }}" > ./application-prod.yml
shell: bash
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
env:
SPRING_PROFILES_ACTIVE: prod
run: ./gradlew clean build --stacktrace
shell: bash
- name: Build immutable cutover image
if: inputs.stage_only
env:
REGISTRY_USER: ${{ secrets.DOCKER_USER }}
REGISTRY_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
run: |
printf '%s' "$REGISTRY_PASSWORD" | docker login --username "$REGISTRY_USER" --password-stdin
docker build -t "$REGISTRY_USER/kodaero-app:neon-$GITHUB_SHA" -f ./Dockerfile .
docker push "$REGISTRY_USER/kodaero-app:neon-$GITHUB_SHA"
- name: Docker build & push to prod
if: ${{ !inputs.stage_only && (contains(github.ref, 'develop') || contains(github.ref, 'main')) }}
run: |
docker login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASSWORD }}
docker build -t kodaero-dev -f ./Dockerfile .
docker tag kodaero-dev:latest ${{ secrets.DOCKER_USER }}/kodaero-dev:latest
docker push ${{ secrets.DOCKER_USER }}/kodaero-dev:latest
pull_from_registry:
if: ${{ !inputs.stage_only && !inputs.audit_only && !inputs.publish_idle_revision && !inputs.rehome_phase && !inputs.counter_phase }}
name: Connect server ssh and pull from container registry
needs: push_to_registry
runs-on: ubuntu-latest
steps:
- name: Deploy to prod
if: contains(github.ref, 'develop') || contains(github.ref, 'main')
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST_NAME }}
username: ${{ secrets.USER_NAME }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.PORT }}
script: |
docker pull ${{ secrets.DOCKER_USER }}/kodaero-dev:latest
cd infra
chmod +x ./deploy-dev.sh
sudo ./deploy-dev.sh
docker image prune -f
audit_backends:
if: ${{ inputs.audit_only }}
runs-on: ubuntu-latest
steps:
- name: Inspect deployed backends without printing credentials
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST_NAME }}
username: ${{ secrets.USER_NAME }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.PORT }}
script: |
set -eu
docker ps --format '{{.Names}} {{.Image}} {{.Status}}'
docker inspect app-dev app-latest app-stable | python3 -c '
import json,sys
allowed={"PUSH_STORAGE","PUSH_AUDIENCE","PUSH_WORKER_ENABLED","PUSH_RECEIPT_WORKER_ENABLED","PUSH_SURVEY_WORKER_ENABLED","PUSH_OUTBOX_ENABLED","PUSH_WORKER_FIXED_DELAY_MS","PUSH_RECEIPT_WORKER_FIXED_DELAY_MS","PUSH_SURVEY_POLL_INTERVAL_MS","PUSH_IDLE_NAMESPACE","PUSH_IDLE_RECONCILE_CRON","SERVER_PORT","SPRING_PROFILES_ACTIVE"}
for c in json.load(sys.stdin):
print(c["Name"], c["Config"]["Image"], c["Image"], c["State"]["Status"])
print("ports", c["NetworkSettings"]["Ports"])
print("network", c["HostConfig"]["NetworkMode"], "port arguments", [v for v in c["Config"].get("Cmd",[]) or [] if v.startswith("--server.port=")])
print("compose files", c["Config"].get("Labels",{}).get("com.docker.compose.project.config_files"))
print("worker settings", dict(v.split("=",1) for v in c["Config"]["Env"] if v.split("=",1)[0] in allowed))
print("configuration mounts", [(m["Source"],m["Destination"]) for m in c.get("Mounts",[]) if "yml" in m["Destination"] or "yaml" in m["Destination"]])
'
counter_script=$(mktemp)
trap 'rm -f "$counter_script"' EXIT
curl --fail --silent --show-error 'https://raw.githubusercontent.com/DevKor-github/team-c-back/${{ github.sha }}/scripts/verify-push-idle.py' -o "$counter_script"
sudo -n python3 "$counter_script"
rehome_neon:
if: ${{ inputs.rehome_phase }}
runs-on: ubuntu-latest
steps:
- name: Switch only the reviewed Neon connection on the existing immutable backend
uses: appleboy/ssh-action@master
env:
NEON_REHOME_PAYLOAD: ${{ secrets.NEON_REHOME_PAYLOAD }}
REHOME_PHASE: ${{ inputs.rehome_phase }}
with:
host: ${{ secrets.HOST_NAME }}
username: ${{ secrets.USER_NAME }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.PORT }}
command_timeout: 15m
envs: NEON_REHOME_PAYLOAD,REHOME_PHASE
script: |
set -eu
rehome_script=$(mktemp)
trap 'rm -f "$rehome_script"' EXIT
curl --fail --silent --show-error 'https://raw.githubusercontent.com/DevKor-github/team-c-back/${{ github.sha }}/scripts/rehome-push-neon.py' -o "$rehome_script"
sudo -n --preserve-env=NEON_REHOME_PAYLOAD python3 "$rehome_script" "$REHOME_PHASE"
reduce_counter_compute:
if: ${{ inputs.counter_phase }}
runs-on: ubuntu-latest
steps:
- name: Preserve counter ledger and configure idle Neon checkpointing
uses: appleboy/ssh-action@master
env:
COUNTER_COMPUTE_PAYLOAD: ${{ secrets.COUNTER_COMPUTE_PAYLOAD }}
COUNTER_PHASE: ${{ inputs.counter_phase }}
with:
host: ${{ secrets.HOST_NAME }}
username: ${{ secrets.USER_NAME }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.PORT }}
command_timeout: 5m
envs: COUNTER_COMPUTE_PAYLOAD,COUNTER_PHASE
script: |
set -eu
counter_script=$(mktemp)
trap 'rm -f "$counter_script"' EXIT
curl --fail --silent --show-error 'https://raw.githubusercontent.com/DevKor-github/team-c-back/${{ github.sha }}/scripts/reduce-counter-compute.py' -o "$counter_script"
sudo -n --preserve-env=COUNTER_COMPUTE_PAYLOAD python3 "$counter_script" "$COUNTER_PHASE"
rollout_idle_workers:
if: ${{ always() && !cancelled() && inputs.rollout_idle && inputs.stage_only && !inputs.audit_only && (needs.push_to_registry.result == 'success' || (needs.push_to_registry.result == 'skipped' && inputs.image_revision)) }}
needs: push_to_registry
runs-on: ubuntu-latest
steps:
- name: Roll out one verified image to every push worker
uses: appleboy/ssh-action@master
env:
IMAGE_REVISION: ${{ inputs.image_revision || github.sha }}
with:
host: ${{ secrets.HOST_NAME }}
username: ${{ secrets.USER_NAME }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.PORT }}
command_timeout: 15m
envs: IMAGE_REVISION
script: |
set -eu
rollout_script=$(mktemp)
trap 'rm -f "$rollout_script"' EXIT
curl --fail --silent --show-error 'https://raw.githubusercontent.com/DevKor-github/team-c-back/${{ github.sha }}/scripts/deploy-push-idle.py' -o "$rollout_script"
python3 "$rollout_script" "${{ secrets.DOCKER_USER }}/kodaero-app:neon-$IMAGE_REVISION" "$IMAGE_REVISION"
publish_verified_idle_aliases:
if: ${{ inputs.publish_idle_revision }}
runs-on: ubuntu-latest
steps:
- name: Publish the verified immutable image for subsequent standard deployments
env:
REGISTRY_USER: ${{ secrets.DOCKER_USER }}
REGISTRY_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
REVISION: ${{ inputs.publish_idle_revision }}
run: |
set -eu
[[ "$REVISION" =~ ^[0-9a-f]{40}$ ]]
printf '%s' "$REGISTRY_PASSWORD" | docker login --username "$REGISTRY_USER" --password-stdin
image="$REGISTRY_USER/kodaero-app:neon-$REVISION"
docker pull "$image"
test "$(docker inspect --format '{{ index .Config.Labels "com.kodaero.push-idle" }}' "$image")" = wake-v1
for alias in "$REGISTRY_USER/kodaero-app:latest" "$REGISTRY_USER/kodaero-app:stable" "$REGISTRY_USER/kodaero-dev:latest"; do
docker tag "$image" "$alias"
docker push "$alias"
done