-
Notifications
You must be signed in to change notification settings - Fork 0
195 lines (179 loc) · 7.91 KB
/
Copy pathdeploy.yml
File metadata and controls
195 lines (179 loc) · 7.91 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
name: Deploy application
on:
workflow_run:
workflows: ["Tests"]
types: [completed]
branches: [main]
workflow_dispatch:
inputs:
component:
description: "Application service to build and deploy"
required: true
type: choice
options: [api, web, all]
default: all
concurrency:
group: deploy-sandbox
cancel-in-progress: false
env:
PROJECT_CONFIG: infra/terraform/projects/config/memory-director.json
ENVIRONMENT_CONFIG: infra/terraform/projects/config/sandbox.json
STATE_PREFIX: memory-director/sandbox
jobs:
deploy:
if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
environment: sandbox
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
- id: config
name: Read non-sensitive deployment configuration
shell: bash
run: |
set -euo pipefail
project_config_file="$GITHUB_WORKSPACE/$PROJECT_CONFIG"
environment_config_file="$GITHUB_WORKSPACE/$ENVIRONMENT_CONFIG"
test -f "$project_config_file"
test -f "$environment_config_file"
project_id="$(jq -r '.project_id' "$PROJECT_CONFIG")"
resource_name="$(jq -r '.resource_name' "$PROJECT_CONFIG")"
state_bucket="$(jq -r '.state_bucket_name // empty' "$PROJECT_CONFIG")"
test -n "$state_bucket"
region="$(jq -r '.region // empty' "$PROJECT_CONFIG")"
if [ -z "$region" ]; then
region="$(jq -r '.default_region' infra/terraform/projects/config/common-environment.json)"
fi
{
echo "project_id=$project_id"
echo "resource_name=$resource_name"
echo "project_config_file=$project_config_file"
echo "environment_config_file=$environment_config_file"
echo "state_bucket=$state_bucket"
echo "region=$region"
echo "registry=$region-docker.pkg.dev/$project_id/$resource_name"
echo "component=${{ github.event.inputs.component || 'all' }}"
echo "sha=${{ github.event.workflow_run.head_sha || github.sha }}"
} >> "$GITHUB_OUTPUT"
- uses: google-github-actions/auth@v2
with:
workload_identity_provider: ${{ vars.GCP_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ vars.TERRAFORM_SERVICE_ACCOUNT }}
- uses: google-github-actions/setup-gcloud@v2
- name: Preserve existing Cloud Run ingress mode
id: ingress
shell: bash
run: |
set -euo pipefail
ingress_values=()
for service in api web; do
if ! ingress="$(gcloud run services describe "${{ steps.config.outputs.resource_name }}-$service" \
--project "${{ steps.config.outputs.project_id }}" \
--region "${{ steps.config.outputs.region }}" \
--format="value(metadata.annotations.'run.googleapis.com/ingress')" 2>&1)"; then
if [[ "$ingress" == *"NOT_FOUND"* ]]; then
continue
fi
printf '%s\n' "$ingress" >&2
exit 1
fi
test -n "$ingress"
if [ -n "$ingress" ]; then
ingress_values+=("$ingress")
fi
done
public_ingress=true
if [ "${#ingress_values[@]}" -gt 0 ]; then
for ingress in "${ingress_values[@]}"; do
case "$ingress" in
all) ;;
internal-and-cloud-load-balancing) public_ingress=false ;;
*) echo "Unsupported Cloud Run ingress value: $ingress" >&2; exit 1 ;;
esac
done
fi
if [ "$public_ingress" = false ]; then
for ingress in "${ingress_values[@]}"; do
test "$ingress" = "internal-and-cloud-load-balancing"
done
fi
echo "public_ingress=$public_ingress" >> "$GITHUB_OUTPUT"
- name: Resolve private ClickHouse MCP endpoint
id: mcp
shell: bash
run: |
set -euo pipefail
mcp_uri="$(gcloud run services describe "${{ steps.config.outputs.resource_name }}-mcp" \
--project "${{ steps.config.outputs.project_id }}" \
--region "${{ steps.config.outputs.region }}" \
--format='value(status.url)')"
test -n "$mcp_uri"
echo "uri=$mcp_uri" >> "$GITHUB_OUTPUT"
- run: gcloud auth configure-docker "${{ steps.config.outputs.region }}-docker.pkg.dev" --quiet
- uses: docker/setup-buildx-action@v3
- name: Build and push API image
if: steps.config.outputs.component == 'api' || steps.config.outputs.component == 'all'
uses: docker/build-push-action@v6
with:
context: services/api
push: true
tags: ${{ steps.config.outputs.registry }}/api:${{ steps.config.outputs.sha }}
- uses: hashicorp/setup-terraform@v3
- name: Apply API service
if: steps.config.outputs.component == 'api' || steps.config.outputs.component == 'all'
shell: bash
run: |
set -euo pipefail
terraform -chdir=infra/terraform/components/app init \
-backend-config="bucket=${{ steps.config.outputs.state_bucket }}" \
-backend-config="prefix=$STATE_PREFIX/app-api"
terraform -chdir=infra/terraform/components/app apply -auto-approve \
-var="project_config=${{ steps.config.outputs.project_config_file }}" \
-var="environment_config=${{ steps.config.outputs.environment_config_file }}" \
-var="service=api" \
-var="api_image=${{ steps.config.outputs.registry }}/api:${{ steps.config.outputs.sha }}" \
-var="web_image=unused" \
-var="mcp_endpoint=${{ steps.mcp.outputs.uri }}" \
-var="public_ingress=${{ steps.ingress.outputs.public_ingress }}"
- name: Resolve deployed API URL
if: steps.config.outputs.component == 'web' || steps.config.outputs.component == 'all'
id: api
shell: bash
run: |
set -euo pipefail
terraform -chdir=infra/terraform/components/app init \
-backend-config="bucket=${{ steps.config.outputs.state_bucket }}" \
-backend-config="prefix=$STATE_PREFIX/app-api" \
-reconfigure
api_uri="$(terraform -chdir=infra/terraform/components/app output -raw api_uri)"
test -n "$api_uri"
echo "uri=$api_uri" >> "$GITHUB_OUTPUT"
- name: Build and push web image
if: steps.config.outputs.component == 'web' || steps.config.outputs.component == 'all'
uses: docker/build-push-action@v6
with:
context: apps/web
push: true
build-args: NEXT_PUBLIC_API_BASE_URL=/api
tags: ${{ steps.config.outputs.registry }}/web:${{ steps.config.outputs.sha }}
- name: Apply web service
if: steps.config.outputs.component == 'web' || steps.config.outputs.component == 'all'
shell: bash
run: |
set -euo pipefail
terraform -chdir=infra/terraform/components/app init \
-backend-config="bucket=${{ steps.config.outputs.state_bucket }}" \
-backend-config="prefix=$STATE_PREFIX/app-web" \
-reconfigure
terraform -chdir=infra/terraform/components/app apply -auto-approve \
-var="project_config=${{ steps.config.outputs.project_config_file }}" \
-var="environment_config=${{ steps.config.outputs.environment_config_file }}" \
-var="service=web" \
-var="api_image=unused" \
-var="web_image=${{ steps.config.outputs.registry }}/web:${{ steps.config.outputs.sha }}" \
-var="api_base_url=${{ steps.api.outputs.uri }}" \
-var="public_ingress=${{ steps.ingress.outputs.public_ingress }}"