-
Notifications
You must be signed in to change notification settings - Fork 0
291 lines (283 loc) · 12.3 KB
/
open-pr.yml
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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# You need to set up Workload Identity Federation in your Google Cloud project in order to use this GitHub Actions definition: https://medium.com/p/3932dce678b8.
# And the secrets.GSA_ID needs to have the roles/artifactregistry.repoAdmin role in order push and delete container images.
name: open-pr
permissions:
contents: read
id-token: write
pull-requests: write
on:
pull_request:
env:
ENVIRONMENT_ID: pr-${{ github.event.number }}
IMAGE_NAME: ${{ secrets.REGISTRY_LOCATION }}-docker.pkg.dev/${{ secrets.PROJECT_ID }}/${{ secrets.REGISTRY_NAME }}/my-sample-workload
SCORE_COMPOSE_VERSION: 'latest'
SCORE_K8S_VERSION: 'latest'
WORKLOAD_NAME: my-sample-workload
CONTAINER_NAME: my-sample-container
HUMCTL_VERSION: '*'
jobs:
build-run-test-push:
runs-on: ubuntu-24.04
steps:
- name: checkout code
uses: actions/checkout@v4
- name: install humctl
uses: humanitec/setup-cli-action@v1
with:
version: ${{ env.HUMCTL_VERSION }}
- name: humctl score validate
run: |
humctl score validate score/score.yaml \
--token ${{ secrets.HUMANITEC_TOKEN }} \
--org ${{ secrets.HUMANITEC_ORG }} \
--strict
- name: install score-compose
uses: score-spec/setup-score@v3
with:
file: score-compose
token: ${{ secrets.GITHUB_TOKEN }}
version: ${{ env.SCORE_COMPOSE_VERSION }}
- name: make compose.yaml
run: |
make compose.yaml
cat <<EOF > compose.override.yaml
services:
${{ env.WORKLOAD_NAME }}-${{ env.CONTAINER_NAME }}:
read_only: true
cap_drop:
- ALL
user: "1000"
EOF
- name: make compose-test
run: |
make compose-test
- name: make kind-create-cluster
run: |
make kind-create-cluster
- name: make kind-load-image
run: |
make kind-load-image
- name: install score-k8s
uses: score-spec/setup-score@v3
with:
file: score-k8s
token: ${{ secrets.GITHUB_TOKEN }}
version: ${{ env.SCORE_K8S_VERSION }}
- name: make k8s-up
id: k8s-up
run: |
make k8s-up
- name: catch k8s-up errors
if: ${{ failure() && steps.k8s-up.outcome == 'failure' }}
run: |
kubectl get events
kubectl logs \
-l app.kubernetes.io/name=${{ env.WORKLOAD_NAME }}
- name: authenticate to google cloud
uses: google-github-actions/auth@v2
with:
workload_identity_provider: '${{ secrets.WI_PROVIDER_ID }}'
service_account: '${{ secrets.GSA_ID }}'
- name: setup gcloud
uses: google-github-actions/setup-gcloud@v2
with:
version: latest
- name: sign-in to gar
run: |
gcloud auth configure-docker \
${{ secrets.REGISTRY_LOCATION }}-docker.pkg.dev \
--quiet
- name: delete previous container image in gar
run: |
gcloud artifacts docker images delete \
${IMAGE_NAME}:${{ env.ENVIRONMENT_ID }} \
--delete-tags \
--quiet \
|| true
- name: push the container to gar
run: |
docker tag ${{ env.WORKLOAD_NAME }}:test ${{ env.IMAGE_NAME }}:${{ env.ENVIRONMENT_ID }}
docker push \
${{ env.IMAGE_NAME }}:${{ env.ENVIRONMENT_ID }}
deploy-preview-env:
needs: build-run-test-push
runs-on: ubuntu-24.04
env:
BASE_ENVIRONMENT: 'development'
ENVIRONMENT_TYPE: 'development'
ENVIRONMENT_NAME: PR-${{ github.event.number }}
steps:
- name: checkout code
uses: actions/checkout@v4
- name: install humctl
uses: humanitec/setup-cli-action@v1
with:
version: ${{ env.HUMCTL_VERSION }}
- name: create humanitec preview env
run: |
EXISTING_ENV_ID=$(humctl get environment ${{ env.ENVIRONMENT_ID }} \
--token ${{ secrets.HUMANITEC_TOKEN }} \
--org ${{ secrets.HUMANITEC_ORG }} \
--app ${{ vars.APP_NAME }} \
-o json \
| jq .metadata.id \
|| true)
if [ -z "$EXISTING_ENV_ID" ]; then
humctl create environment ${{ env.ENVIRONMENT_ID }} \
--token ${{ secrets.HUMANITEC_TOKEN }} \
--org ${{ secrets.HUMANITEC_ORG }} \
--app ${{ vars.APP_NAME }} \
--name ${{ env.ENVIRONMENT_NAME }} \
-t ${{ env.ENVIRONMENT_TYPE }} \
--from ${{ env.BASE_ENVIRONMENT }}
fi
- name: authenticate to google cloud
uses: google-github-actions/auth@v2
with:
workload_identity_provider: '${{ secrets.WI_PROVIDER_ID }}'
service_account: '${{ secrets.GSA_ID }}'
- name: setup gcloud
uses: google-github-actions/setup-gcloud@v2
with:
version: latest
- name: sign-in to gar
run: |
gcloud auth configure-docker \
${{ secrets.REGISTRY_LOCATION }}-docker.pkg.dev \
--quiet
- uses: oras-project/setup-oras@v1
- name: get container image digest
run: |
echo "IMAGE_DIGEST=$(oras manifest fetch ${{ env.IMAGE_NAME }}:${{ env.ENVIRONMENT_ID }} \
--descriptor \
| jq -r .digest)" >> ${{ github.env }}
- name: humctl score deploy
run: |
humctl score deploy \
--deploy-config score/score.deploy.yaml \
--image ${{ env.IMAGE_NAME }}@${IMAGE_DIGEST} \
--message "$(curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" "${{ github.event.pull_request.commits_url }}?per_page=10" | jq -r .[-1].commit.message)" \
--workload-source-url-prefix "https://github.com/${{ github.repository }}/blob/${{ github.head_ref }}/score" \
--token ${{ secrets.HUMANITEC_TOKEN }} \
--org ${{ secrets.HUMANITEC_ORG }} \
--app ${{ vars.APP_NAME }} \
--env ${{ env.ENVIRONMENT_ID }} \
--wait
- name: build comment message
if: ${{ always() }}
run: |
DEPLOYMENT_ID=$(humctl get deployment . -o json \
--token ${{ secrets.HUMANITEC_TOKEN }} \
--org ${{ secrets.HUMANITEC_ORG }} \
--app ${{ vars.APP_NAME }} \
--env ${{ env.ENVIRONMENT_ID }} \
| jq -r .metadata.id)
ENV_URL="https://app.humanitec.io/orgs/"${{ secrets.HUMANITEC_ORG }}"/apps/"${{ vars.APP_NAME }}"/envs/"${{ env.ENVIRONMENT_ID }}"/deploys/"${DEPLOYMENT_ID}
DOMAINS=$(humctl get active-resources \
--token ${{ secrets.HUMANITEC_TOKEN }} \
--org ${{ secrets.HUMANITEC_ORG }} \
--app ${{ vars.APP_NAME }} \
--env ${{ env.ENVIRONMENT_ID }} -o json \
| jq -r '. | map(. | select(.metadata.type == "dns")) | map((.metadata.res_id | split(".") | .[1]) + ": [" + .status.resource.host + "](https://" + .status.resource.host + ")") | join("\n")')
DEPLOYMENT_ERRORS=$(humctl get deployment-error \
--token ${{ secrets.HUMANITEC_TOKEN }} \
--org ${{ secrets.HUMANITEC_ORG }} \
--app ${{ vars.APP_NAME }} \
--env ${{ env.ENVIRONMENT_ID }} -o json)
RUNTIME_ERRORS=$(humctl api get /orgs/${{ secrets.HUMANITEC_ORG }}/apps/${{ vars.APP_NAME }}/envs/${{ env.ENVIRONMENT_ID }}/runtime \
--token ${{ secrets.HUMANITEC_TOKEN }} \
| grep '"status": "Failure"' -B 10 -A 1) \
|| true
if [[ "$DEPLOYMENT_ERRORS" = "[]" && -z "$RUNTIME_ERRORS" ]]; then
echo "## Deployment successfully completed for ${{ env.ENVIRONMENT_NAME }}! :tada:" >> pr_message.txt
echo "" >> pr_message.txt
else
echo "## Deployment failed for ${{ env.ENVIRONMENT_NAME }}! :x:" >> pr_message.txt
echo "" >> pr_message.txt
if [ "$DEPLOYMENT_ERRORS" != "[]" ]; then
echo "### Deployment errors:" >> pr_message.txt
echo "" >> pr_message.txt
echo '```json' >> pr_message.txt
echo "" >> pr_message.txt
echo "$DEPLOYMENT_ERRORS" | jq .[0].status.message -r >> pr_message.txt
echo "" >> pr_message.txt
echo '```' >> pr_message.txt
echo "" >> pr_message.txt
echo "<details><summary>Deployment errors details</summary>" >> pr_message.txt
echo "" >> pr_message.txt
echo "### Deployment errors details:" >> pr_message.txt
echo '```json' >> pr_message.txt
echo "" >> pr_message.txt
echo "$DEPLOYMENT_ERRORS" >> pr_message.txt
echo "" >> pr_message.txt
echo '```' >> pr_message.txt
echo "" >> pr_message.txt
echo "</details>" >> pr_message.txt
echo "" >> pr_message.txt
fi
if [ -n "$RUNTIME_ERRORS" ]; then
echo "### Runtime errors:" >> pr_message.txt
echo "" >> pr_message.txt
echo "$RUNTIME_ERRORS" >> pr_message.txt
echo "" >> pr_message.txt
fi
fi
echo "### [View in Humanitec]($ENV_URL)" >> pr_message.txt
echo "Deployment ID: $DEPLOYMENT_ID" >> pr_message.txt
echo "" >> pr_message.txt
echo "### URLs:" >> pr_message.txt
echo "" >> pr_message.txt
echo "$DOMAINS" >> pr_message.txt
echo "" >> pr_message.txt
echo "<details><summary>Deployment diff</summary>" >> pr_message.txt
echo "" >> pr_message.txt
echo "### Deployment diff:" >> pr_message.txt
echo '```json' >> pr_message.txt
echo "" >> pr_message.txt
humctl diff sets env/${{ env.ENVIRONMENT_ID }} env/${{ env.BASE_ENVIRONMENT }} \
--token ${{ secrets.HUMANITEC_TOKEN }} \
--org ${{ secrets.HUMANITEC_ORG }} \
--app ${{ vars.APP_NAME }} -o json >> pr_message.txt
echo "" >> pr_message.txt
echo '```' >> pr_message.txt
echo "" >> pr_message.txt
echo "</details>" >> pr_message.txt
if [ "$DEPLOYMENT_ERRORS" = "[]" ]; then
echo "<details><summary>Active Resources Usage</summary>" >> pr_message.txt
echo "" >> pr_message.txt
echo "### Active Resources Usage:" >> pr_message.txt
echo '```none' >> pr_message.txt
echo "" >> pr_message.txt
humctl resources active-resource-usage \
--env ${{ env.ENVIRONMENT_ID }} \
--token ${{ secrets.HUMANITEC_TOKEN }} \
--org ${{ secrets.HUMANITEC_ORG }} \
--app ${{ vars.APP_NAME }} >> pr_message.txt
echo "" >> pr_message.txt
echo '```' >> pr_message.txt
echo "" >> pr_message.txt
echo "</details>" >> pr_message.txt
fi
if [ "$DEPLOYMENT_ERRORS" = "[]" ]; then
echo "<details><summary>Resources Graph</summary>" >> pr_message.txt
echo "" >> pr_message.txt
echo "### Resources Graph:" >> pr_message.txt
echo "Use a [Graphviz](https://graphviz.org) viewer for a visual representation." >> pr_message.txt
echo '```none' >> pr_message.txt
echo "" >> pr_message.txt
humctl resources graph \
--env ${{ env.ENVIRONMENT_ID }} \
--token ${{ secrets.HUMANITEC_TOKEN }} \
--org ${{ secrets.HUMANITEC_ORG }} \
--app ${{ vars.APP_NAME }} >> pr_message.txt
echo "" >> pr_message.txt
echo '```' >> pr_message.txt
echo "" >> pr_message.txt
echo "</details>" >> pr_message.txt
fi
- name: comment pr
if: ${{ always() }}
run: |
gh pr comment ${{ github.event.number }} --repo ${{ github.repository }} --body-file pr_message.txt
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}