-
Notifications
You must be signed in to change notification settings - Fork 1
351 lines (321 loc) · 13.2 KB
/
reusable.yaml
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
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
name: Reusable Uffizzi Cluster Environment Workflow
env:
LOGGER_KEY: "aHR0cHM6Ly80NGI3Zjk5MTFiODU0NWI5YTMzMDY4NzRhY2ZjYjJjOUBvMzI0MzExLmluZ2VzdC5zZW50cnkuaW8vNDUwNDM2MTIxMjI0ODA2NA=="
on:
workflow_call:
inputs:
k8s-manifest-cache-key:
description: "GHA Cache Key for Kubernetes manifests file ready to deploy"
required: false # TODO: true
type: string
k8s-manifest-cache-path:
description: "GHA Cache Path for Kubernetes manifests file ready to deploy"
required: false # TODO: true
type: string
username:
description: "Uffizzi username for login, usually an email address"
required: false
type: string
server:
description: "Uffizzi server URL"
default: https://app.uffizzi.com
required: false
type: string
project:
description: "Uffizzi project name"
default: default
required: false
type: string
pr-number:
description: "GitHub Pull Request Number"
default: ""
required: false
type: string
git-ref:
description: "Branch or other git reference to checkout"
default: ""
required: false
type: string
healthcheck-url-path:
description: "URL Path to the Uffizzi Cluster URL where healthcheck would be performed. The URL Path has to start with a '/'."
default: ""
required: false
type: string
description:
description: "Text string added to comment on pull request issue"
default: "What is Uffizzi? [Learn more](https://www.uffizzi.com)!"
required: false
type: string
environment:
description: "Custom environment for the deployed cluster"
default: "uffizzi"
required: false
type: string
image:
description: "Uffizzi CLI image"
default: "uffizzi/cli:v2"
required: false
type: string
secrets:
access-token:
description: "Github pipeline token"
required: false
password:
description: "Uffizzi password for login"
required: false
url-username:
description: "Username for authenticating to each Environment"
required: false
url-password:
description: "Password for authentication to each Environment"
required: false
personal-access-token:
description: "GitHub personal access token with access to container registry"
required: false
dockerhub-username:
description: "DockerHub username"
required: false
dockerhub-password:
description: "DockerHub password"
required: false
acr-username:
description: "Azure username"
required: false
acr-password:
description: "Azure password"
required: false
acr-registry-url:
description: "Azure registry url"
required: false
aws-access-key-id:
description: "Amazon Web Services access key id"
required: false
aws-secret-access-key:
description: "Amazon Web Services secret access key"
required: false
aws-registry-url:
description: "Amazon Web Services registry url"
required: false
gcloud-service-key:
description: "Google Cloud service key"
required: false
docker-registry-username:
description: "Custom docker registry username"
required: false
docker-registry-password:
description: "Custom docker registry password"
required: false
docker-registry-url:
description: "Custom docker registry url"
required: false
outputs:
url:
description: "URL to Uffizzi Cluster Environment"
value: ${{ jobs.uffizzi-cluster.outputs.url }}
id:
description: "Uffizzi Cluster Deployment ID"
value: ${{ jobs.uffizzi-cluster.outputs.id }}
containers_uri:
description: "URL to Uffizzi Deployment Details"
value: ${{ jobs.uffizzi-cluster.outputs.containers_uri }}
expiration_interval:
description: "Uffizzi Cluster Expiration Interval in Seconds"
value: ${{ jobs.uffizzi-cluster.outputs.expiration_interval }}
expiration:
description: "Uffizzi Cluster Expiration Time String"
value: ${{ jobs.uffizzi-cluster.outputs.expiration }}
expiration_timestamp:
description: "Uffizzi Cluster Expiration UNIX Timestamp"
value: ${{ jobs.uffizzi-cluster.outputs.expiration_timestamp }}
permissions:
contents: read
pull-requests: write
id-token: write
jobs:
uffizzi-cluster:
name: "Create, or Delete cluster on Uffizzi"
runs-on: ubuntu-22.04
environment:
name: ${{ inputs.environment }}
url: "${{ steps.outputs.outputs.url }}"
outputs:
url: ${{ steps.outputs.outputs.url }}
id: ${{ steps.outputs.outputs.id }}
containers_uri: ${{ steps.outputs.outputs.containers_uri }}
expiration_interval: ${{ steps.outputs.outputs.expiration_interval }}
expiration: ${{ steps.outputs.outputs.expiration }}
expiration_timestamp: ${{ steps.outputs.outputs.expiration_timestamp }}
steps:
# DEBUG
- name: DEBUG - Dump GitHub context and environment info
if: ${{ runner.debug }}
uses: crazy-max/ghaction-dump-context@v1
# Get pull request number
- name: Determine Pull Request Number
id: pr
run: |
export INPUT_PR=${{ inputs.pr-number }}
export CONTEXT_PR=${{ github.event.number }}
export OUTPUT_PR=${INPUT_PR:-$CONTEXT_PR}
echo "PR_NUMBER=$OUTPUT_PR" >> $GITHUB_ENV
# Look for an existing Cluster Deployment and set DEPLOYMENT_ID necessary to determine operation
- name: Find Cluster for this Pull Request
id: find-deployment
run: |
if docker run --rm \
--env UFFIZZI_SERVER="${{ inputs.server }}" \
--env REQUEST_TOKEN=${ACTIONS_ID_TOKEN_REQUEST_TOKEN} \
--env REQUEST_TOKEN_URL=${ACTIONS_ID_TOKEN_REQUEST_URL} \
"${{ inputs.image }}" cluster list | grep --quiet "pr-$PR_NUMBER$"
then
echo DEPLOYMENT_ID="pr-$PR_NUMBER" >> $GITHUB_ENV
else
echo DEPLOYMENT_ID='' >> $GITHUB_ENV
echo "Uffizzi cluster with name pr-$PR_NUMBER not found"
fi
env:
LOGGER_KEY: ${{ env.LOGGER_KEY }}
CI_WORKFLOW: "true"
# Identify comment to be updated
- name: Find comment for deployment URL
uses: peter-evans/find-comment@v2
id: find-comment
with:
issue-number: ${{ env.PR_NUMBER }}
comment-author: "github-actions[bot]"
body-includes: "${{ env.EXPECTED_URL }}"
direction: last
# Identify the operation -- create, update or delete
- name: Determine Operation
uses: actions/github-script@v6
with:
k8s-manifest-cache-key: ${{ inputs.k8s-manifest-cache-key }}
script: |
let action = 'none'; // default
const { PR_NUMBER, DEPLOYMENT_ID } = process.env;
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: PR_NUMBER
});
if (core.isDebug()) {
console.log(pr);
}
// `state` is either `open` or `closed`.
if (pr.data.state == 'open') {
if (DEPLOYMENT_ID == '') {
console.log(`PR ${PR_NUMBER} is open but no deployment found. Creating new deployment.`);
action = 'create';
} else {
console.log(`PR ${PR_NUMBER} is open and ${DEPLOYMENT_ID} found. Updating existing deployment.`);
action = 'update';
}
} else if (pr.data.state == 'closed') {
if (DEPLOYMENT_ID == '') {
core.warning(`PR ${PR_NUMBER} is closed but no deployment found. No operation.`);
action = 'none';
} else {
console.log(`PR ${PR_NUMBER} is closed and ${DEPLOYMENT_ID} found. Deleting existing deployment.`);
action = 'delete';
}
} else {
core.setFailed(`Fatal exception: PR ${PR_NUMBER} is neither \`open\` nor \`closed\` but \`${pr.data.state}\`.`);
}
core.exportVariable('UFFIZZI_ACTION', action);
// core.setOutput('action', action);
return;
# Call to the checkout action
- name: Checkout commit
if: ${{ contains(fromJSON('["create", "update"]'), env.UFFIZZI_ACTION) }}
uses: actions/checkout@v3
with:
ref: ${{ inputs.git-ref || github.event.pull_request.head.sha }}
# Create/Update comment with action deployment status
- name: Create or Update Comment with Deployment Notification
id: notification
uses: peter-evans/create-or-update-comment@v2
if: ${{ contains(fromJSON('["create", "update"]'), env.UFFIZZI_ACTION) }}
with:
comment-id: ${{ steps.find-comment.outputs.comment-id }}
issue-number: ${{ env.PR_NUMBER }}
body: |
## Uffizzi Ephemeral Cluster Environment Deploying
:cloud: ${{ env.EXPECTED_URL }}
:gear: Updating now by workflow run [${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}).
${{ inputs.description }}
edit-mode: replace
# Create cluster
- name: Deploy Cluster Update cluster credentials
id: create-cluster
if: ${{ env.UFFIZZI_ACTION == 'create' }} || ${{ env.UFFIZZI_ACTION == 'update' }}
uses: UffizziCloud/cluster-action@main
with:
action: create
cluster-name: pr-$PR_NUMBER
k8s-manifest-file: ${{ inputs.k8s-manifest-cache-path }}
server: ${{ inputs.server }}
# Upload kubeconfig
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: my-artifact
path: kubeconfig
# Output create-cluster related metadata
- name: Job output consolidation
id: outputs
if: ${{ contains(fromJSON('["create"]'), env.UFFIZZI_ACTION) }}
run: |
export CREATE_URL=${{ steps.create-cluster.outputs.url }}
export CREATE_ID=${{ steps.create-cluster.outputs.id }}
export CREATE_CONTAINERS=${{ steps.create-cluster.outputs.containers_uri }}
export OUTPUT_URL=${CREATE_URL:-$UPDATE_URL}
export OUTPUT_ID=${CREATE_ID:-$UPDATE_ID}
export OUTPUT_CONTAINERS=${CREATE_CONTAINERS:-$UPDATE_CONTAINERS}
echo "Deployment ID $OUTPUT_ID at $OUTPUT_URL"
echo "OUTPUT_ID=$OUTPUT_ID" >> $GITHUB_ENV
echo "DEPLOYMENT_ID=$OUTPUT_ID" >> $GITHUB_ENV
echo "OUTPUT_URL=$OUTPUT_URL" >> $GITHUB_ENV
echo "OUTPUT_CONTAINERS=$OUTPUT_CONTAINERS" >> $GITHUB_ENV
# Expose the step output variables
echo "url=$OUTPUT_URL" >> $GITHUB_OUTPUT
echo "id=$OUTPUT_ID" >> $GITHUB_OUTPUT
echo "containers_uri=$OUTPUT_CONTAINERS" >> $GITHUB_OUTPUT
echo "expiration_interval=$EXPIRATION_INTERVAL" >> $GITHUB_OUTPUT
echo "expiration=$EXPIRATION" >> $GITHUB_OUTPUT
echo "expiration_timestamp=$EXPIRATION_TIMESTAMP" >> $GITHUB_OUTPUT
# Create/Update comment with the deployment url
- name: Create or Update Comment with Deployment URL
uses: peter-evans/create-or-update-comment@v2
if: ${{ contains(fromJSON('["create", "update"]'), env.UFFIZZI_ACTION) }}
with:
comment-id: ${{ steps.notification.outputs.comment-id }}
issue-number: ${{ env.PR_NUMBER }}
body: |
## Uffizzi Ephemeral Cluster Environment
Your cluster `pr-${{ env.PR_NUMBER }}` was successfully created. Learn more about [Uffizzi virtual clusters](https://docs.uffizzi.com/virtual-clusters)
To connect to this cluster, follow these steps:
1. Download and install the Uffizzi CLI
2. Login to Uffizzi: `uffizzi login`
3. Update your kubeconfig: `uffizzi cluster update-kubeconfig pr-${{ env.PR_NUMBER }} --kubeconfig=[KUBECONFIG]` , replacing `[KUBECONFIG]` with the path to your kubeconfig file.
After updating your kubeconfig, you can manage your cluster with kubectl
${{ inputs.description }}
edit-mode: replace
# Delete cluster
- name: Delete Cluster from Uffizzi
if: ${{ env.UFFIZZI_ACTION == 'delete' }}
uses: UffizziCloud/cluster-action@main
with:
action: delete
cluster-name: pr-$PR_NUMBER
k8s-manifest-file: ${{ inputs.k8s-manifest-cache-path }}
server: ${{ inputs.server }}
# Update comment with deletion status
- name: Update Comment with Deletion
uses: peter-evans/create-or-update-comment@v2
if: ${{ env.UFFIZZI_ACTION == 'delete' }}
with:
comment-id: ${{ steps.find-comment.outputs.comment-id }}
issue-number: ${{ env.PR_NUMBER }}
body: |
Uffizzi Cluster `${{ env.DEPLOYMENT_ID }}` was deleted.
edit-mode: replace